Refactoring in Client and Tester builder implementations
The default transport-specific client and tester extensions contained their builder implementations, but it makes more sense the other way around since the extensions are mainly about the builders they provide.
This commit is contained in:
@@ -198,7 +198,7 @@ request execution as any `GraphQlTester`.
|
||||
|
||||
Many times it's enough to test GraphQL requests on the server side, without the use of a
|
||||
client to send requests over a transport protocol. To test directly against a
|
||||
`ExecutionGraphQlService`, use the `GraphQlServiceTester` extension:
|
||||
`ExecutionGraphQlService`, use the `ExecutionGraphQlServiceTester` extension:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link ExecutionGraphQlServiceTester.Builder} implementation that
|
||||
* wraps an {@code ExecutionGraphQlService}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultExecutionGraphQlServiceTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultExecutionGraphQlServiceTesterBuilder>
|
||||
implements ExecutionGraphQlServiceTester.Builder<DefaultExecutionGraphQlServiceTesterBuilder> {
|
||||
|
||||
private final ExecutionGraphQlService service;
|
||||
|
||||
|
||||
DefaultExecutionGraphQlServiceTesterBuilder(ExecutionGraphQlService service) {
|
||||
Assert.notNull(service, "GraphQlService is required");
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
DefaultExecutionGraphQlServiceTesterBuilder(GraphQlServiceGraphQlTransport transport) {
|
||||
this.service = transport.getGraphQlService();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ExecutionGraphQlServiceTester build() {
|
||||
GraphQlServiceGraphQlTransport transport = new GraphQlServiceGraphQlTransport(this.service);
|
||||
GraphQlTester tester = super.buildGraphQlTester(transport);
|
||||
return new DefaultExecutionGraphQlServiceTester(tester, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link ExecutionGraphQlServiceTester} implementation.
|
||||
*/
|
||||
private static class DefaultExecutionGraphQlServiceTester
|
||||
extends AbstractDelegatingGraphQlTester implements ExecutionGraphQlServiceTester {
|
||||
|
||||
private final GraphQlServiceGraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
private DefaultExecutionGraphQlServiceTester(GraphQlTester tester, GraphQlServiceGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(tester);
|
||||
|
||||
Assert.notNull(transport, "GraphQlServiceTransport is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultExecutionGraphQlServiceTesterBuilder mutate() {
|
||||
DefaultExecutionGraphQlServiceTesterBuilder builder = new DefaultExecutionGraphQlServiceTesterBuilder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlServiceTester} that uses a {@link ExecutionGraphQlService} for
|
||||
* request execution.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultGraphQlServiceTester extends AbstractDelegatingGraphQlTester implements GraphQlServiceTester {
|
||||
|
||||
private final GraphQlServiceGraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
private DefaultGraphQlServiceTester(GraphQlTester tester, GraphQlServiceGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(tester);
|
||||
|
||||
Assert.notNull(transport, "GraphQlServiceTransport is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder<?> mutate() {
|
||||
Builder<?> builder = new Builder<>(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlServiceTester.Builder} implementation.
|
||||
*/
|
||||
static class Builder<B extends Builder<B>> extends AbstractGraphQlTesterBuilder<B>
|
||||
implements GraphQlServiceTester.Builder<B> {
|
||||
|
||||
private final ExecutionGraphQlService service;
|
||||
|
||||
Builder(ExecutionGraphQlService service) {
|
||||
Assert.notNull(service, "GraphQlService is required");
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
Builder(GraphQlServiceGraphQlTransport transport) {
|
||||
this.service = transport.getGraphQlService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphQlServiceTester build() {
|
||||
GraphQlServiceGraphQlTransport transport = new GraphQlServiceGraphQlTransport(this.service);
|
||||
GraphQlTester tester = super.buildGraphQlTester(transport);
|
||||
return new DefaultGraphQlServiceTester(tester, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlTester} that builds and uses a {@link WebTestClient}
|
||||
* for request execution.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultHttpGraphQlTester extends AbstractDelegatingGraphQlTester implements HttpGraphQlTester {
|
||||
|
||||
private final WebTestClient webTestClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
private DefaultHttpGraphQlTester(GraphQlTester graphQlTester, WebTestClient webTestClient,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlTester);
|
||||
this.webTestClient = webTestClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.webTestClient.mutate());
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlTester.Builder} implementation.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlTesterBuilder<Builder>
|
||||
implements HttpGraphQlTester.Builder<Builder> {
|
||||
|
||||
private final WebTestClient.Builder webTestClientBuilder;
|
||||
|
||||
Builder(WebTestClient.Builder clientBuilder) {
|
||||
this.webTestClientBuilder = clientBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(String url) {
|
||||
this.webTestClientBuilder.baseUrl(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(URI url) {
|
||||
UriBuilderFactory factory = new DefaultUriBuilderFactory(UriComponentsBuilder.fromUri(url));
|
||||
this.webTestClientBuilder.uriBuilderFactory(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder header(String name, String... values) {
|
||||
this.webTestClientBuilder.defaultHeader(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.webTestClientBuilder.defaultHeaders(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder codecConfigurer(Consumer<CodecConfigurer> codecConsumer) {
|
||||
this.webTestClientBuilder.codecs(codecConsumer::accept);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder webTestClient(Consumer<WebTestClient.Builder> configurer) {
|
||||
configurer.accept(this.webTestClientBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
WebTestClient client = this.webTestClientBuilder.build();
|
||||
GraphQlTester tester = super.buildGraphQlTester(new WebTestClientTransport(client));
|
||||
return new DefaultHttpGraphQlTester(tester, client, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.webTestClientBuilder.codecs(codecConfigurer ->
|
||||
configureJsonPathConfig(config -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer);
|
||||
return config.mappingProvider(provider);
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlTester.Builder} implementation, simply wraps a
|
||||
* {@link WebTestClient.Builder}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultHttpGraphQlTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultHttpGraphQlTesterBuilder>
|
||||
implements HttpGraphQlTester.Builder<DefaultHttpGraphQlTesterBuilder> {
|
||||
|
||||
private final WebTestClient.Builder webTestClientBuilder;
|
||||
|
||||
|
||||
DefaultHttpGraphQlTesterBuilder(WebTestClient.Builder clientBuilder) {
|
||||
this.webTestClientBuilder = clientBuilder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder url(String url) {
|
||||
this.webTestClientBuilder.baseUrl(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder url(URI url) {
|
||||
UriBuilderFactory factory = new DefaultUriBuilderFactory(UriComponentsBuilder.fromUri(url));
|
||||
this.webTestClientBuilder.uriBuilderFactory(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder header(String name, String... values) {
|
||||
this.webTestClientBuilder.defaultHeader(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.webTestClientBuilder.defaultHeaders(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder codecConfigurer(Consumer<CodecConfigurer> codecConsumer) {
|
||||
this.webTestClientBuilder.codecs(codecConsumer::accept);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder webTestClient(Consumer<WebTestClient.Builder> configurer) {
|
||||
configurer.accept(this.webTestClientBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
WebTestClient client = this.webTestClientBuilder.build();
|
||||
GraphQlTester tester = super.buildGraphQlTester(new WebTestClientTransport(client));
|
||||
return new DefaultHttpGraphQlTester(tester, client, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.webTestClientBuilder.codecs(codecConfigurer ->
|
||||
configureJsonPathConfig(config -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer);
|
||||
return config.mappingProvider(provider);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlTester} that builds and uses a {@link WebTestClient}
|
||||
* for request execution.
|
||||
*/
|
||||
private static class DefaultHttpGraphQlTester extends AbstractDelegatingGraphQlTester implements HttpGraphQlTester {
|
||||
|
||||
private final WebTestClient webTestClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
private DefaultHttpGraphQlTester(GraphQlTester graphQlTester, WebTestClient webTestClient,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlTester);
|
||||
this.webTestClient = webTestClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlTesterBuilder mutate() {
|
||||
DefaultHttpGraphQlTesterBuilder builder = new DefaultHttpGraphQlTesterBuilder(this.webTestClient.mutate());
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.rsocket.transport.ClientTransport;
|
||||
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.graphql.client.RSocketGraphQlClient;
|
||||
import org.springframework.messaging.rsocket.RSocketRequester;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlTester} that builds and uses an
|
||||
* {@link RSocketGraphQlClient} for request execution.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class DefaultRSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements RSocketGraphQlTester {
|
||||
|
||||
private final RSocketGraphQlClient rsocketGraphQlClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
DefaultRSocketGraphQlTester(
|
||||
GraphQlTester delegate, RSocketGraphQlClient rsocketGraphQlClient,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
this.rsocketGraphQlClient = rsocketGraphQlClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlTester.Builder<?> mutate() {
|
||||
Builder builder = new Builder(this.rsocketGraphQlClient);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@link GraphQlTester.Builder}.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlTesterBuilder<Builder> implements RSocketGraphQlTester.Builder<Builder> {
|
||||
|
||||
private final RSocketGraphQlClient.Builder<?> rsocketGraphQlClientBuilder;
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link RSocketGraphQlTester#builder()}.
|
||||
*/
|
||||
Builder() {
|
||||
this.rsocketGraphQlClientBuilder = RSocketGraphQlClient.builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link RSocketGraphQlTester#builder(RSocketRequester.Builder)}.
|
||||
*/
|
||||
Builder(RSocketRequester.Builder requesterBuilder) {
|
||||
this.rsocketGraphQlClientBuilder = RSocketGraphQlClient.builder(requesterBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param rsocketGraphQlClient the underlying client with the current state
|
||||
*/
|
||||
public Builder(RSocketGraphQlClient rsocketGraphQlClient) {
|
||||
this.rsocketGraphQlClientBuilder = rsocketGraphQlClient.mutate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder tcp(String host, int port) {
|
||||
this.rsocketGraphQlClientBuilder.tcp(host, port);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder webSocket(URI uri) {
|
||||
this.rsocketGraphQlClientBuilder.webSocket(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clientTransport(ClientTransport clientTransport) {
|
||||
this.rsocketGraphQlClientBuilder.clientTransport(clientTransport);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder dataMimeType(MimeType dataMimeType) {
|
||||
this.rsocketGraphQlClientBuilder.dataMimeType(dataMimeType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder route(String route) {
|
||||
this.rsocketGraphQlClientBuilder.route(route);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder rsocketRequester(Consumer<RSocketRequester.Builder> requesterConsumer) {
|
||||
this.rsocketGraphQlClientBuilder.rsocketRequester(requesterConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
RSocketGraphQlClient rsocketGraphQlClient = this.rsocketGraphQlClientBuilder.build();
|
||||
GraphQlTester graphQlTester = super.buildGraphQlTester(asTransport(rsocketGraphQlClient));
|
||||
return new DefaultRSocketGraphQlTester(graphQlTester, rsocketGraphQlClient, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.rsocketGraphQlClientBuilder.rsocketRequester(builder ->
|
||||
builder.rsocketStrategies(strategiesBuilder ->
|
||||
configureJsonPathConfig(config -> {
|
||||
RSocketStrategies strategies = strategiesBuilder.build();
|
||||
List<Encoder<?>> encoders = strategies.encoders();
|
||||
List<Decoder<?>> decoders = strategies.decoders();
|
||||
return config.mappingProvider(new EncoderDecoderMappingProvider(encoders, decoders));
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.rsocket.transport.ClientTransport;
|
||||
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.graphql.client.RSocketGraphQlClient;
|
||||
import org.springframework.messaging.rsocket.RSocketRequester;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@link RSocketGraphQlTester.Builder} that wraps
|
||||
* an {@link RSocketGraphQlClient.Builder}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class DefaultRSocketGraphQlTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultRSocketGraphQlTesterBuilder>
|
||||
implements RSocketGraphQlTester.Builder<DefaultRSocketGraphQlTesterBuilder> {
|
||||
|
||||
private final RSocketGraphQlClient.Builder<?> rsocketGraphQlClientBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link RSocketGraphQlTester#builder()}.
|
||||
*/
|
||||
DefaultRSocketGraphQlTesterBuilder() {
|
||||
this.rsocketGraphQlClientBuilder = RSocketGraphQlClient.builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link RSocketGraphQlTester#builder(RSocketRequester.Builder)}.
|
||||
*/
|
||||
DefaultRSocketGraphQlTesterBuilder(RSocketRequester.Builder requesterBuilder) {
|
||||
this.rsocketGraphQlClientBuilder = RSocketGraphQlClient.builder(requesterBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param rsocketGraphQlClient the underlying client with the current state
|
||||
*/
|
||||
public DefaultRSocketGraphQlTesterBuilder(RSocketGraphQlClient rsocketGraphQlClient) {
|
||||
this.rsocketGraphQlClientBuilder = rsocketGraphQlClient.mutate();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder tcp(String host, int port) {
|
||||
this.rsocketGraphQlClientBuilder.tcp(host, port);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder webSocket(URI uri) {
|
||||
this.rsocketGraphQlClientBuilder.webSocket(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder clientTransport(ClientTransport clientTransport) {
|
||||
this.rsocketGraphQlClientBuilder.clientTransport(clientTransport);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder dataMimeType(MimeType dataMimeType) {
|
||||
this.rsocketGraphQlClientBuilder.dataMimeType(dataMimeType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder route(String route) {
|
||||
this.rsocketGraphQlClientBuilder.route(route);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlTesterBuilder rsocketRequester(Consumer<RSocketRequester.Builder> requesterConsumer) {
|
||||
this.rsocketGraphQlClientBuilder.rsocketRequester(requesterConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
RSocketGraphQlClient rsocketGraphQlClient = this.rsocketGraphQlClientBuilder.build();
|
||||
GraphQlTester graphQlTester = super.buildGraphQlTester(asTransport(rsocketGraphQlClient));
|
||||
return new DefaultRSocketGraphQlTester(graphQlTester, rsocketGraphQlClient, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.rsocketGraphQlClientBuilder.rsocketRequester(builder ->
|
||||
builder.rsocketStrategies(strategiesBuilder ->
|
||||
configureJsonPathConfig(config -> {
|
||||
RSocketStrategies strategies = strategiesBuilder.build();
|
||||
List<Encoder<?>> encoders = strategies.encoders();
|
||||
List<Decoder<?>> decoders = strategies.decoders();
|
||||
return config.mappingProvider(new EncoderDecoderMappingProvider(encoders, decoders));
|
||||
})));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlTester} implementation.
|
||||
*/
|
||||
private static class DefaultRSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements RSocketGraphQlTester {
|
||||
|
||||
private final RSocketGraphQlClient rsocketGraphQlClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
DefaultRSocketGraphQlTester(
|
||||
GraphQlTester delegate, RSocketGraphQlClient rsocketGraphQlClient,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
this.rsocketGraphQlClient = rsocketGraphQlClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlTester.Builder<?> mutate() {
|
||||
DefaultRSocketGraphQlTesterBuilder builder = new DefaultRSocketGraphQlTesterBuilder(this.rsocketGraphQlClient);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.graphql.client.GraphQlTransport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlTester.Builder} with a given, externally prepared transport.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultTransportGraphQlTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultTransportGraphQlTesterBuilder> {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
|
||||
DefaultTransportGraphQlTesterBuilder(GraphQlTransport transport) {
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public GraphQlTester build() {
|
||||
GraphQlTester tester = super.buildGraphQlTester(this.transport);
|
||||
return new DefaultTransportGraphQlTester(tester, this.transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@link GraphQlTester} with a given transport.
|
||||
*/
|
||||
private static class DefaultTransportGraphQlTester extends AbstractDelegatingGraphQlTester {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
private DefaultTransportGraphQlTester(
|
||||
GraphQlTester delegate, GraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "'builderInitializer' is required");
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultTransportGraphQlTesterBuilder mutate() {
|
||||
DefaultTransportGraphQlTesterBuilder builder = new DefaultTransportGraphQlTesterBuilder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,114 +28,111 @@ import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebGraphQlTester} that uses {@link WebGraphQlHandler} for
|
||||
* request execution.
|
||||
* Default implementation for {@link WebGraphQlTester} that initializes a
|
||||
* {@link WebGraphQlHandler} for request execution.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultWebGraphQlTester extends AbstractDelegatingGraphQlTester implements WebGraphQlTester {
|
||||
final class DefaultWebGraphQlTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultWebGraphQlTesterBuilder>
|
||||
implements WebGraphQlTester.Builder<DefaultWebGraphQlTesterBuilder> {
|
||||
|
||||
private final WebGraphQlHandlerGraphQlTransport transport;
|
||||
private URI url = URI.create("");
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final WebGraphQlHandler handler;
|
||||
|
||||
private CodecConfigurer codecConfigurer = ClientCodecConfigurer.create();
|
||||
|
||||
|
||||
private DefaultWebGraphQlTester(GraphQlTester tester, WebGraphQlHandlerGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
DefaultWebGraphQlTesterBuilder(WebGraphQlHandler handler) {
|
||||
Assert.notNull(handler, "WebGraphQlHandler is required");
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
super(tester);
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
DefaultWebGraphQlTesterBuilder(WebGraphQlHandlerGraphQlTransport transport) {
|
||||
this.url = transport.getUrl();
|
||||
this.headers.putAll(transport.getHeaders());
|
||||
this.handler = transport.getGraphQlHandler();
|
||||
this.codecConfigurer = transport.getCodecConfigurer();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder<?> mutate() {
|
||||
Builder<?> builder = new Builder<>(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
public DefaultWebGraphQlTesterBuilder url(String url) {
|
||||
return url(new DefaultUriBuilderFactory().uriString(url).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebGraphQlTesterBuilder url(URI url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebGraphQlTesterBuilder header(String name, String... values) {
|
||||
this.headers.put(name, Arrays.asList(values));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebGraphQlTesterBuilder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
headersConsumer.accept(this.headers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebGraphQlTesterBuilder codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
codecConfigurerConsumer.accept(this.codecConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlTester build() {
|
||||
|
||||
registerJsonPathMappingProvider();
|
||||
|
||||
WebGraphQlHandlerGraphQlTransport transport =
|
||||
new WebGraphQlHandlerGraphQlTransport(this.url, this.headers, this.handler, this.codecConfigurer);
|
||||
|
||||
GraphQlTester tester = super.buildGraphQlTester(transport);
|
||||
return new DefaultWebGraphQlTester(tester, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
configureJsonPathConfig(jsonPathConfig -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(this.codecConfigurer);
|
||||
return jsonPathConfig.mappingProvider(provider);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base builder implementation for all Web transport extensions.
|
||||
* Default {@link WebGraphQlTester} implementation.
|
||||
*/
|
||||
static class Builder<B extends Builder<B>> extends AbstractGraphQlTesterBuilder<B>
|
||||
implements WebGraphQlTester.Builder<B> {
|
||||
private static class DefaultWebGraphQlTester extends AbstractDelegatingGraphQlTester implements WebGraphQlTester {
|
||||
|
||||
private URI url = URI.create("");
|
||||
private final WebGraphQlHandlerGraphQlTransport transport;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
private final WebGraphQlHandler handler;
|
||||
private DefaultWebGraphQlTester(GraphQlTester tester, WebGraphQlHandlerGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
private CodecConfigurer codecConfigurer = ClientCodecConfigurer.create();
|
||||
|
||||
Builder(WebGraphQlHandler handler) {
|
||||
Assert.notNull(handler, "WebGraphQlHandler is required");
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
Builder(WebGraphQlHandlerGraphQlTransport transport) {
|
||||
this.url = transport.getUrl();
|
||||
this.headers.putAll(transport.getHeaders());
|
||||
this.handler = transport.getGraphQlHandler();
|
||||
this.codecConfigurer = transport.getCodecConfigurer();
|
||||
super(tester);
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public B url(String url) {
|
||||
return url(new DefaultUriBuilderFactory().uriString(url).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public B url(URI url) {
|
||||
this.url = url;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B header(String name, String... values) {
|
||||
this.headers.put(name, Arrays.asList(values));
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
headersConsumer.accept(this.headers);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public B codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
codecConfigurerConsumer.accept(this.codecConfigurer);
|
||||
return self();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends B> T self() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlTester build() {
|
||||
|
||||
registerJsonPathMappingProvider();
|
||||
|
||||
WebGraphQlHandlerGraphQlTransport transport =
|
||||
new WebGraphQlHandlerGraphQlTransport(this.url, this.headers, this.handler, this.codecConfigurer);
|
||||
|
||||
GraphQlTester tester = super.buildGraphQlTester(transport);
|
||||
return new DefaultWebGraphQlTester(tester, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
configureJsonPathConfig(jsonPathConfig -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(this.codecConfigurer);
|
||||
return jsonPathConfig.mappingProvider(provider);
|
||||
});
|
||||
public DefaultWebGraphQlTesterBuilder mutate() {
|
||||
DefaultWebGraphQlTesterBuilder builder = new DefaultWebGraphQlTesterBuilder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,127 +28,130 @@ import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.socket.client.WebSocketClient;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlTester} that builds and uses a
|
||||
* {@link WebSocketGraphQlClient} for request execution.
|
||||
* Default {@link WebSocketGraphQlTester.Builder} implementation, wraps a
|
||||
* {@link WebSocketGraphQlClient.Builder}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultWebSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements WebSocketGraphQlTester {
|
||||
final class DefaultWebSocketGraphQlTesterBuilder
|
||||
extends AbstractGraphQlTesterBuilder<DefaultWebSocketGraphQlTesterBuilder>
|
||||
implements WebSocketGraphQlTester.Builder<DefaultWebSocketGraphQlTesterBuilder> {
|
||||
|
||||
private final WebSocketGraphQlClient webSocketGraphQlClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
private final WebSocketGraphQlClient.Builder<?> graphQlClientBuilder;
|
||||
|
||||
|
||||
private DefaultWebSocketGraphQlTester(
|
||||
GraphQlTester graphQlTester, WebSocketGraphQlClient webSocketGraphQlClient,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlTester#builder(String, WebSocketClient)}.
|
||||
*/
|
||||
DefaultWebSocketGraphQlTesterBuilder(String url, WebSocketClient webSocketClient) {
|
||||
Assert.notNull(webSocketClient, "WebSocketClient is required");
|
||||
this.graphQlClientBuilder = WebSocketGraphQlClient.builder(url, webSocketClient);
|
||||
}
|
||||
|
||||
super(graphQlTester);
|
||||
this.webSocketGraphQlClient = webSocketGraphQlClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlTester#builder(URI, WebSocketClient)}.
|
||||
*/
|
||||
DefaultWebSocketGraphQlTesterBuilder(URI url, WebSocketClient webSocketClient) {
|
||||
Assert.notNull(webSocketClient, "WebSocketClient is required");
|
||||
this.graphQlClientBuilder = WebSocketGraphQlClient.builder(url, webSocketClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param client the underlying client with the current state
|
||||
*/
|
||||
DefaultWebSocketGraphQlTesterBuilder(WebSocketGraphQlClient client) {
|
||||
Assert.notNull(client, "WebSocketGraphQlClient is required");
|
||||
this.graphQlClientBuilder = client.mutate();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Void> start() {
|
||||
return this.webSocketGraphQlClient.start();
|
||||
public DefaultWebSocketGraphQlTesterBuilder url(String url) {
|
||||
this.graphQlClientBuilder.url(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> stop() {
|
||||
return this.webSocketGraphQlClient.stop();
|
||||
public DefaultWebSocketGraphQlTesterBuilder url(URI url) {
|
||||
this.graphQlClientBuilder.url(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.webSocketGraphQlClient);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
public DefaultWebSocketGraphQlTesterBuilder header(String name, String... values) {
|
||||
this.graphQlClientBuilder.header(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlTesterBuilder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.graphQlClientBuilder.headers(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlTesterBuilder codecConfigurer(Consumer<CodecConfigurer> codecsConsumer) {
|
||||
this.graphQlClientBuilder.codecConfigurer(codecsConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
WebSocketGraphQlClient client = this.graphQlClientBuilder.build();
|
||||
GraphQlTester graphQlTester = super.buildGraphQlTester(asTransport(client));
|
||||
return new DefaultWebSocketGraphQlTester(graphQlTester, client, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.graphQlClientBuilder.codecConfigurer(codecConfigurer -> {
|
||||
configureJsonPathConfig(jsonPathConfig -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer);
|
||||
return jsonPathConfig.mappingProvider(provider);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlTester.Builder} implementation.
|
||||
* Default {@link WebSocketGraphQlTester} implementation.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlTesterBuilder<Builder> implements WebSocketGraphQlTester.Builder<Builder> {
|
||||
private static class DefaultWebSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements WebSocketGraphQlTester {
|
||||
|
||||
private final WebSocketGraphQlClient.Builder<?> graphQlClientBuilder;
|
||||
private final WebSocketGraphQlClient client;
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlTester#builder(String, WebSocketClient)}.
|
||||
*/
|
||||
Builder(String url, WebSocketClient webSocketClient) {
|
||||
Assert.notNull(webSocketClient, "WebSocketClient is required");
|
||||
this.graphQlClientBuilder = WebSocketGraphQlClient.builder(url, webSocketClient);
|
||||
}
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlTester#builder(URI, WebSocketClient)}.
|
||||
*/
|
||||
Builder(URI url, WebSocketClient webSocketClient) {
|
||||
Assert.notNull(webSocketClient, "WebSocketClient is required");
|
||||
this.graphQlClientBuilder = WebSocketGraphQlClient.builder(url, webSocketClient);
|
||||
}
|
||||
private DefaultWebSocketGraphQlTester(
|
||||
GraphQlTester graphQlTester, WebSocketGraphQlClient client,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param client the underlying client with the current state
|
||||
*/
|
||||
Builder(WebSocketGraphQlClient client) {
|
||||
Assert.notNull(client, "WebSocketGraphQlClient is required");
|
||||
this.graphQlClientBuilder = client.mutate();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder url(String url) {
|
||||
this.graphQlClientBuilder.url(url);
|
||||
return this;
|
||||
super(graphQlTester);
|
||||
this.client = client;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(URI url) {
|
||||
this.graphQlClientBuilder.url(url);
|
||||
return this;
|
||||
public Mono<Void> start() {
|
||||
return this.client.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder header(String name, String... values) {
|
||||
this.graphQlClientBuilder.header(name, values);
|
||||
return this;
|
||||
public Mono<Void> stop() {
|
||||
return this.client.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.graphQlClientBuilder.headers(headersConsumer);
|
||||
return this;
|
||||
public DefaultWebSocketGraphQlTesterBuilder mutate() {
|
||||
DefaultWebSocketGraphQlTesterBuilder builder = new DefaultWebSocketGraphQlTesterBuilder(this.client);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder codecConfigurer(Consumer<CodecConfigurer> codecsConsumer) {
|
||||
this.graphQlClientBuilder.codecConfigurer(codecsConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketGraphQlTester build() {
|
||||
registerJsonPathMappingProvider();
|
||||
WebSocketGraphQlClient client = this.graphQlClientBuilder.build();
|
||||
GraphQlTester graphQlTester = super.buildGraphQlTester(asTransport(client));
|
||||
return new DefaultWebSocketGraphQlTester(graphQlTester, client, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private void registerJsonPathMappingProvider() {
|
||||
this.graphQlClientBuilder.codecConfigurer(codecConfigurer -> {
|
||||
configureJsonPathConfig(jsonPathConfig -> {
|
||||
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer);
|
||||
return jsonPathConfig.mappingProvider(provider);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ package org.springframework.graphql.test.tester;
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
|
||||
/**
|
||||
* {@link GraphQlTester} that executes requests through a {@link ExecutionGraphQlService}
|
||||
* Use it for server-side tests, without a client.
|
||||
* {@link GraphQlTester} that executes requests through an
|
||||
* {@link ExecutionGraphQlService} on the server side, without a client.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface GraphQlServiceTester extends GraphQlTester {
|
||||
public interface ExecutionGraphQlServiceTester extends GraphQlTester {
|
||||
|
||||
|
||||
@Override
|
||||
@@ -33,30 +33,30 @@ public interface GraphQlServiceTester extends GraphQlTester {
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link GraphQlServiceTester} instance.
|
||||
* Create a {@link ExecutionGraphQlServiceTester} instance.
|
||||
*/
|
||||
static GraphQlServiceTester create(ExecutionGraphQlService service) {
|
||||
static ExecutionGraphQlServiceTester create(ExecutionGraphQlService service) {
|
||||
return builder(service).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a builder for {@link GraphQlServiceTester}.
|
||||
* Return a builder for {@link ExecutionGraphQlServiceTester}.
|
||||
*/
|
||||
static GraphQlServiceTester.Builder<?> builder(ExecutionGraphQlService service) {
|
||||
return new DefaultGraphQlServiceTester.Builder<>(service);
|
||||
static ExecutionGraphQlServiceTester.Builder<?> builder(ExecutionGraphQlService service) {
|
||||
return new DefaultExecutionGraphQlServiceTesterBuilder(service);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlServiceTester.Builder} implementation.
|
||||
* Default {@link ExecutionGraphQlServiceTester.Builder} implementation.
|
||||
*/
|
||||
interface Builder<B extends Builder<B>> extends GraphQlTester.Builder<B> {
|
||||
|
||||
/**
|
||||
* Build a {@link GraphQlServiceTester} instance.
|
||||
* Build a {@link ExecutionGraphQlServiceTester} instance.
|
||||
*/
|
||||
@Override
|
||||
GraphQlServiceTester build();
|
||||
ExecutionGraphQlServiceTester build();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.graphql.client.GraphQlTransport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link GraphQlTester} with a given, externally prepared transport.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class GenericGraphQlTester extends AbstractDelegatingGraphQlTester {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
private GenericGraphQlTester(
|
||||
GraphQlTester delegate, GraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlTesterBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "'builderInitializer' is required");
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlTester.Builder} with a given transport.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlTesterBuilder<Builder> {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
Builder(GraphQlTransport transport) {
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphQlTester build() {
|
||||
GraphQlTester tester = super.buildGraphQlTester(this.transport);
|
||||
return new GenericGraphQlTester(tester, this.transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* <p>To test on the server side, without a client, see the following:
|
||||
* <ul>
|
||||
* <li>{@link GraphQlServiceTester}
|
||||
* <li>{@link ExecutionGraphQlServiceTester}
|
||||
* <li>{@link WebGraphQlTester}
|
||||
* </ul>
|
||||
*
|
||||
@@ -88,7 +88,7 @@ public interface GraphQlTester {
|
||||
* @return the builder for further initialization
|
||||
*/
|
||||
static GraphQlTester.Builder<?> builder(GraphQlTransport transport) {
|
||||
return new GenericGraphQlTester.Builder(transport);
|
||||
return new DefaultTransportGraphQlTesterBuilder(transport);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public interface HttpGraphQlTester extends WebGraphQlTester {
|
||||
* the underlying {@link WebTestClient} through the given builder.
|
||||
*/
|
||||
static HttpGraphQlTester.Builder<?> builder(WebTestClient.Builder webTestClientBuilder) {
|
||||
return new DefaultHttpGraphQlTester.Builder(webTestClientBuilder);
|
||||
return new DefaultHttpGraphQlTesterBuilder(webTestClientBuilder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,14 +44,14 @@ public interface RSocketGraphQlTester extends GraphQlTester {
|
||||
* and adding JSON codecs.
|
||||
*/
|
||||
static RSocketGraphQlTester.Builder<?> builder() {
|
||||
return new DefaultRSocketGraphQlTester.Builder();
|
||||
return new DefaultRSocketGraphQlTesterBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start with a given {@link #builder()}.
|
||||
*/
|
||||
static RSocketGraphQlTester.Builder<?> builder(RSocketRequester.Builder requesterBuilder) {
|
||||
return new DefaultRSocketGraphQlTester.Builder(requesterBuilder);
|
||||
return new DefaultRSocketGraphQlTesterBuilder(requesterBuilder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.http.codec.CodecConfigurer;
|
||||
|
||||
/**
|
||||
* Server-side tester, without a client, that executes requests through a
|
||||
* {@link WebGraphQlHandler}. Similar to {@link GraphQlServiceTester} but also
|
||||
* {@link WebGraphQlHandler}. Similar to {@link ExecutionGraphQlServiceTester} but also
|
||||
* adding a web processing layer with a {@code WebGraphQlInterceptor}
|
||||
* chain.
|
||||
*
|
||||
@@ -53,7 +53,7 @@ public interface WebGraphQlTester extends GraphQlTester {
|
||||
* @param graphQlHandler the handler to execute requests
|
||||
*/
|
||||
static WebGraphQlTester.Builder<?> builder(WebGraphQlHandler graphQlHandler) {
|
||||
return new DefaultWebGraphQlTester.Builder<>(graphQlHandler);
|
||||
return new DefaultWebGraphQlTesterBuilder(graphQlHandler);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public interface WebSocketGraphQlTester extends WebGraphQlTester {
|
||||
* @param webSocketClient the underlying transport client to use
|
||||
*/
|
||||
static WebSocketGraphQlTester.Builder<?> builder(String url, WebSocketClient webSocketClient) {
|
||||
return new DefaultWebSocketGraphQlTester.Builder(url, webSocketClient);
|
||||
return new DefaultWebSocketGraphQlTesterBuilder(url, webSocketClient);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ public interface WebSocketGraphQlTester extends WebGraphQlTester {
|
||||
* @param webSocketClient the underlying transport client to use
|
||||
*/
|
||||
static WebSocketGraphQlTester.Builder<?> builder(URI url, WebSocketClient webSocketClient) {
|
||||
return new DefaultWebSocketGraphQlTester.Builder(url, webSocketClient);
|
||||
return new DefaultWebSocketGraphQlTesterBuilder(url, webSocketClient);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class GraphQlTesterTestSupport {
|
||||
|
||||
private final ExecutionGraphQlService graphQlService = mock(ExecutionGraphQlService.class);
|
||||
|
||||
private final GraphQlTester.Builder<?> graphQlTesterBuilder = GraphQlServiceTester.builder(this.graphQlService);
|
||||
private final GraphQlTester.Builder<?> graphQlTesterBuilder = ExecutionGraphQlServiceTester.builder(this.graphQlService);
|
||||
|
||||
private final GraphQlTester graphQlTester = this.graphQlTesterBuilder.build();
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlClient} implementation that builds the underlying
|
||||
* {@code HttpGraphQlTransport} to use.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultHttpGraphQlClient extends AbstractDelegatingGraphQlClient implements HttpGraphQlClient {
|
||||
|
||||
private final WebClient webClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
DefaultHttpGraphQlClient(GraphQlClient graphQlClient, WebClient webClient,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlClient);
|
||||
|
||||
Assert.notNull(webClient, "WebClient is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.webClient = webClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.webClient);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlClient.Builder} implementation, simply wrapping
|
||||
* and delegating to {@link WebClient.Builder}.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlClientBuilder<Builder> implements HttpGraphQlClient.Builder<Builder> {
|
||||
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
|
||||
/**
|
||||
* Constructor to start without a WebClient instance.
|
||||
*/
|
||||
Builder() {
|
||||
this(WebClient.builder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start with a pre-configured {@code WebClient}.
|
||||
*/
|
||||
Builder(WebClient client) {
|
||||
this(client.mutate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start with a pre-configured {@code WebClient}.
|
||||
*/
|
||||
Builder(WebClient.Builder clientBuilder) {
|
||||
this.webClientBuilder = clientBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(String url) {
|
||||
this.webClientBuilder.baseUrl(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(URI url) {
|
||||
UriBuilderFactory factory = new DefaultUriBuilderFactory(UriComponentsBuilder.fromUri(url));
|
||||
this.webClientBuilder.uriBuilderFactory(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder header(String name, String... values) {
|
||||
this.webClientBuilder.defaultHeader(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.webClientBuilder.defaultHeaders(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
this.webClientBuilder.codecs(codecConfigurerConsumer::accept);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder webClient(Consumer<WebClient.Builder> configurer) {
|
||||
configurer.accept(this.webClientBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpGraphQlClient build() {
|
||||
|
||||
// Pass the codecs to the parent for response decoding
|
||||
this.webClientBuilder.codecs(configurer ->
|
||||
setJsonCodecs(
|
||||
CodecDelegate.findJsonEncoder(configurer),
|
||||
CodecDelegate.findJsonDecoder(configurer)));
|
||||
|
||||
WebClient webClient = this.webClientBuilder.build();
|
||||
|
||||
GraphQlClient graphQlClient = super.buildGraphQlClient(new HttpGraphQlTransport(webClient));
|
||||
return new DefaultHttpGraphQlClient(graphQlClient, webClient, getBuilderInitializer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlClient.Builder} implementation, a simple wrapper
|
||||
* around a {@link WebClient.Builder}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultHttpGraphQlClientBuilder
|
||||
extends AbstractGraphQlClientBuilder<DefaultHttpGraphQlClientBuilder>
|
||||
implements HttpGraphQlClient.Builder<DefaultHttpGraphQlClientBuilder> {
|
||||
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to start without a WebClient instance.
|
||||
*/
|
||||
DefaultHttpGraphQlClientBuilder() {
|
||||
this(WebClient.builder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start with a pre-configured {@code WebClient}.
|
||||
*/
|
||||
DefaultHttpGraphQlClientBuilder(WebClient client) {
|
||||
this(client.mutate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start with a pre-configured {@code WebClient}.
|
||||
*/
|
||||
DefaultHttpGraphQlClientBuilder(WebClient.Builder clientBuilder) {
|
||||
this.webClientBuilder = clientBuilder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder url(String url) {
|
||||
this.webClientBuilder.baseUrl(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder url(URI url) {
|
||||
UriBuilderFactory factory = new DefaultUriBuilderFactory(UriComponentsBuilder.fromUri(url));
|
||||
this.webClientBuilder.uriBuilderFactory(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder header(String name, String... values) {
|
||||
this.webClientBuilder.defaultHeader(name, values);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
this.webClientBuilder.defaultHeaders(headersConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
this.webClientBuilder.codecs(codecConfigurerConsumer::accept);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultHttpGraphQlClientBuilder webClient(Consumer<WebClient.Builder> configurer) {
|
||||
configurer.accept(this.webClientBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpGraphQlClient build() {
|
||||
|
||||
// Pass the codecs to the parent for response decoding
|
||||
this.webClientBuilder.codecs(configurer ->
|
||||
setJsonCodecs(
|
||||
CodecDelegate.findJsonEncoder(configurer),
|
||||
CodecDelegate.findJsonDecoder(configurer)));
|
||||
|
||||
WebClient webClient = this.webClientBuilder.build();
|
||||
|
||||
GraphQlClient graphQlClient = super.buildGraphQlClient(new HttpGraphQlTransport(webClient));
|
||||
return new DefaultHttpGraphQlClient(graphQlClient, webClient, getBuilderInitializer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link HttpGraphQlClient} implementation.
|
||||
*/
|
||||
private static class DefaultHttpGraphQlClient extends AbstractDelegatingGraphQlClient implements HttpGraphQlClient {
|
||||
|
||||
private final WebClient webClient;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
DefaultHttpGraphQlClient(
|
||||
GraphQlClient delegate, WebClient webClient,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
|
||||
Assert.notNull(webClient, "WebClient is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.webClient = webClient;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
public DefaultHttpGraphQlClientBuilder mutate() {
|
||||
DefaultHttpGraphQlClientBuilder builder = new DefaultHttpGraphQlClientBuilder(this.webClient);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.rsocket.transport.ClientTransport;
|
||||
import io.rsocket.transport.netty.client.TcpClientTransport;
|
||||
import io.rsocket.transport.netty.client.WebsocketClientTransport;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.rsocket.RSocketRequester;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlClient} implementation that builds the underlying
|
||||
* {@code RSocketGraphQlTransport} to use.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultRSocketGraphQlClient extends AbstractDelegatingGraphQlClient implements RSocketGraphQlClient {
|
||||
|
||||
private final RSocketRequester.Builder requesterBuilder;
|
||||
|
||||
private final ClientTransport clientTransport;
|
||||
|
||||
private final String route;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
DefaultRSocketGraphQlClient(
|
||||
GraphQlClient graphQlClient, RSocketRequester.Builder requesterBuilder,
|
||||
ClientTransport clientTransport, String route,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlClient);
|
||||
|
||||
this.requesterBuilder = requesterBuilder;
|
||||
this.clientTransport = clientTransport;
|
||||
this.route = route;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlClient.Builder<?> mutate() {
|
||||
Builder builder = new Builder(this.requesterBuilder);
|
||||
builder.clientTransport(this.clientTransport);
|
||||
builder.route(this.route);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlClient.Builder} implementation.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlClientBuilder<Builder> implements RSocketGraphQlClient.Builder<Builder> {
|
||||
|
||||
private final RSocketRequester.Builder requesterBuilder;
|
||||
|
||||
@Nullable
|
||||
private ClientTransport clientTransport;
|
||||
|
||||
private String route;
|
||||
|
||||
Builder() {
|
||||
this(initRSocketRequestBuilder());
|
||||
}
|
||||
|
||||
Builder(RSocketRequester.Builder requesterBuilder) {
|
||||
Assert.notNull(requesterBuilder, "RSocketRequester.Builder is required");
|
||||
this.requesterBuilder = requesterBuilder;
|
||||
this.route = "graphql";
|
||||
}
|
||||
|
||||
private static RSocketRequester.Builder initRSocketRequestBuilder() {
|
||||
MimeType mimeType = MimeType.valueOf("application/graphql+json");
|
||||
RSocketRequester.Builder requesterBuilder = RSocketRequester.builder().dataMimeType(mimeType);
|
||||
if (jackson2Present) {
|
||||
requesterBuilder.rsocketStrategies(
|
||||
RSocketStrategies.builder()
|
||||
.encoder(DefaultJackson2Codecs.encoder())
|
||||
.decoder(DefaultJackson2Codecs.decoder())
|
||||
.build());
|
||||
}
|
||||
return requesterBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder tcp(String host, int port) {
|
||||
this.clientTransport = TcpClientTransport.create(host, port);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder webSocket(URI uri) {
|
||||
this.clientTransport = WebsocketClientTransport.create(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clientTransport(ClientTransport clientTransport) {
|
||||
this.clientTransport = clientTransport;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder dataMimeType(MimeType dataMimeType) {
|
||||
this.requesterBuilder.dataMimeType(dataMimeType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder route(String route) {
|
||||
Assert.notNull(route, "'route' is required");
|
||||
this.route = route;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder rsocketRequester(Consumer<RSocketRequester.Builder> requesterConsumer) {
|
||||
requesterConsumer.accept(this.requesterBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlClient build() {
|
||||
|
||||
// Pass the codecs to the parent for response decoding
|
||||
this.requesterBuilder.rsocketStrategies(builder -> {
|
||||
builder.decoders(decoders -> setJsonDecoder(CodecDelegate.findJsonDecoder(decoders)));
|
||||
builder.encoders(encoders -> setJsonEncoder(CodecDelegate.findJsonEncoder(encoders)));
|
||||
});
|
||||
|
||||
Assert.state(this.clientTransport != null, "Neither WebSocket nor TCP networking configured");
|
||||
RSocketRequester requester = this.requesterBuilder.transport(this.clientTransport);
|
||||
RSocketGraphQlTransport graphQlTransport = new RSocketGraphQlTransport(this.route, requester, getJsonDecoder());
|
||||
|
||||
return new DefaultRSocketGraphQlClient(
|
||||
super.buildGraphQlClient(graphQlTransport),
|
||||
this.requesterBuilder, this.clientTransport, this.route, getBuilderInitializer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.rsocket.transport.ClientTransport;
|
||||
import io.rsocket.transport.netty.client.TcpClientTransport;
|
||||
import io.rsocket.transport.netty.client.WebsocketClientTransport;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.rsocket.RSocketRequester;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlClient.Builder} implementation that wraps
|
||||
* a {@link RSocketRequester.Builder}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultRSocketGraphQlClientBuilder
|
||||
extends AbstractGraphQlClientBuilder<DefaultRSocketGraphQlClientBuilder>
|
||||
implements RSocketGraphQlClient.Builder<DefaultRSocketGraphQlClientBuilder> {
|
||||
|
||||
private final RSocketRequester.Builder requesterBuilder;
|
||||
|
||||
@Nullable
|
||||
private ClientTransport clientTransport;
|
||||
|
||||
private String route;
|
||||
|
||||
|
||||
DefaultRSocketGraphQlClientBuilder() {
|
||||
this(initRSocketRequestBuilder());
|
||||
}
|
||||
|
||||
DefaultRSocketGraphQlClientBuilder(RSocketRequester.Builder requesterBuilder) {
|
||||
Assert.notNull(requesterBuilder, "RSocketRequester.Builder is required");
|
||||
this.requesterBuilder = requesterBuilder;
|
||||
this.route = "graphql";
|
||||
}
|
||||
|
||||
private static RSocketRequester.Builder initRSocketRequestBuilder() {
|
||||
MimeType mimeType = MimeType.valueOf("application/graphql+json");
|
||||
RSocketRequester.Builder requesterBuilder = RSocketRequester.builder().dataMimeType(mimeType);
|
||||
if (jackson2Present) {
|
||||
requesterBuilder.rsocketStrategies(
|
||||
RSocketStrategies.builder()
|
||||
.encoder(DefaultJackson2Codecs.encoder())
|
||||
.decoder(DefaultJackson2Codecs.decoder())
|
||||
.build());
|
||||
}
|
||||
return requesterBuilder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder tcp(String host, int port) {
|
||||
this.clientTransport = TcpClientTransport.create(host, port);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder webSocket(URI uri) {
|
||||
this.clientTransport = WebsocketClientTransport.create(uri);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder clientTransport(ClientTransport clientTransport) {
|
||||
this.clientTransport = clientTransport;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder dataMimeType(MimeType dataMimeType) {
|
||||
this.requesterBuilder.dataMimeType(dataMimeType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder route(String route) {
|
||||
Assert.notNull(route, "'route' is required");
|
||||
this.route = route;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRSocketGraphQlClientBuilder rsocketRequester(Consumer<RSocketRequester.Builder> requesterConsumer) {
|
||||
requesterConsumer.accept(this.requesterBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlClient build() {
|
||||
|
||||
// Pass the codecs to the parent for response decoding
|
||||
this.requesterBuilder.rsocketStrategies(builder -> {
|
||||
builder.decoders(decoders -> setJsonDecoder(CodecDelegate.findJsonDecoder(decoders)));
|
||||
builder.encoders(encoders -> setJsonEncoder(CodecDelegate.findJsonEncoder(encoders)));
|
||||
});
|
||||
|
||||
Assert.state(this.clientTransport != null, "Neither WebSocket nor TCP networking configured");
|
||||
RSocketRequester requester = this.requesterBuilder.transport(this.clientTransport);
|
||||
RSocketGraphQlTransport graphQlTransport = new RSocketGraphQlTransport(this.route, requester, getJsonDecoder());
|
||||
|
||||
return new DefaultRSocketGraphQlClient(
|
||||
super.buildGraphQlClient(graphQlTransport),
|
||||
this.requesterBuilder, this.clientTransport, this.route, getBuilderInitializer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link RSocketGraphQlClient} implementation.
|
||||
*/
|
||||
private static class DefaultRSocketGraphQlClient extends AbstractDelegatingGraphQlClient implements RSocketGraphQlClient {
|
||||
|
||||
private final RSocketRequester.Builder requesterBuilder;
|
||||
|
||||
private final ClientTransport clientTransport;
|
||||
|
||||
private final String route;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
DefaultRSocketGraphQlClient(
|
||||
GraphQlClient graphQlClient, RSocketRequester.Builder requesterBuilder,
|
||||
ClientTransport clientTransport, String route, Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlClient);
|
||||
|
||||
this.requesterBuilder = requesterBuilder;
|
||||
this.clientTransport = clientTransport;
|
||||
this.route = route;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RSocketGraphQlClient.Builder<?> mutate() {
|
||||
DefaultRSocketGraphQlClientBuilder builder = new DefaultRSocketGraphQlClientBuilder(this.requesterBuilder);
|
||||
builder.clientTransport(this.clientTransport);
|
||||
builder.route(this.route);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlClient.Builder} with a given, externally, prepared transport.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultTransportGraphQlClientBuilder
|
||||
extends AbstractGraphQlClientBuilder<DefaultTransportGraphQlClientBuilder> {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
|
||||
DefaultTransportGraphQlClientBuilder(GraphQlTransport transport) {
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public GraphQlClient build() {
|
||||
GraphQlClient client = buildGraphQlClient(this.transport);
|
||||
return new DefaultTransportGraphQlClient(client, this.transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default GraphQL client with a given transport.
|
||||
*/
|
||||
private static class DefaultTransportGraphQlClient extends AbstractDelegatingGraphQlClient {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
DefaultTransportGraphQlClient(
|
||||
GraphQlClient graphQlClient, GraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlClient);
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "'builderInitializer' is required");
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultTransportGraphQlClientBuilder mutate() {
|
||||
DefaultTransportGraphQlClientBuilder builder = new DefaultTransportGraphQlClientBuilder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.socket.client.WebSocketClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlClient} implementation that builds the underlying
|
||||
* {@code WebSocketGraphQlTransport} to use.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultWebSocketGraphQlClient extends AbstractDelegatingGraphQlClient implements WebSocketGraphQlClient {
|
||||
|
||||
private final WebSocketGraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
DefaultWebSocketGraphQlClient(GraphQlClient delegate, WebSocketGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
|
||||
Assert.notNull(transport, "WebSocketGraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Void> start() {
|
||||
return this.transport.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> stop() {
|
||||
return this.transport.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlClient.Builder} implementation.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlClientBuilder<Builder>
|
||||
implements WebSocketGraphQlClient.Builder<Builder> {
|
||||
|
||||
private URI url;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final WebSocketClient webSocketClient;
|
||||
|
||||
private final CodecConfigurer codecConfigurer;
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlClient#builder(String, WebSocketClient)}.
|
||||
*/
|
||||
Builder(String url, WebSocketClient client) {
|
||||
this(toURI(url), client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlClient#builder(URI, WebSocketClient)}.
|
||||
*/
|
||||
Builder(URI url, WebSocketClient client) {
|
||||
this.url = url;
|
||||
this.webSocketClient = client;
|
||||
this.codecConfigurer = ClientCodecConfigurer.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param transport the underlying transport with the current state
|
||||
*/
|
||||
Builder(WebSocketGraphQlTransport transport) {
|
||||
this.url = transport.getUrl();
|
||||
this.headers.putAll(transport.getHeaders());
|
||||
this.webSocketClient = transport.getWebSocketClient();
|
||||
this.codecConfigurer = transport.getCodecConfigurer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(String url) {
|
||||
return url(toURI(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder url(URI url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
private static URI toURI(String url) {
|
||||
return new DefaultUriBuilderFactory().uriString(url).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder header(String name, String... values) {
|
||||
this.headers.put(name, Arrays.asList(values));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
headersConsumer.accept(this.headers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
codecConfigurerConsumer.accept(this.codecConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketGraphQlClient build() {
|
||||
|
||||
setJsonCodecs(
|
||||
CodecDelegate.findJsonEncoder(this.codecConfigurer),
|
||||
CodecDelegate.findJsonDecoder(this.codecConfigurer));
|
||||
|
||||
WebSocketGraphQlTransport transport = new WebSocketGraphQlTransport(
|
||||
this.url, this.headers, this.webSocketClient, this.codecConfigurer, getInterceptor());
|
||||
|
||||
GraphQlClient graphQlClient = super.buildGraphQlClient(transport);
|
||||
return new DefaultWebSocketGraphQlClient(graphQlClient, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private WebSocketGraphQlClientInterceptor getInterceptor() {
|
||||
|
||||
List<WebSocketGraphQlClientInterceptor> interceptors = getInterceptors().stream()
|
||||
.filter(interceptor -> interceptor instanceof WebSocketGraphQlClientInterceptor)
|
||||
.map(interceptor -> (WebSocketGraphQlClientInterceptor) interceptor)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assert.state(interceptors.size() <= 1,
|
||||
"Only a single interceptor of type WebSocketGraphQlClientInterceptor may be configured");
|
||||
|
||||
return (!interceptors.isEmpty() ? interceptors.get(0) : new WebSocketGraphQlClientInterceptor() {});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.socket.client.WebSocketClient;
|
||||
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlClient.Builder} that builds the underlying
|
||||
* {@code WebSocketGraphQlTransport}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class DefaultWebSocketGraphQlClientBuilder
|
||||
extends AbstractGraphQlClientBuilder<DefaultWebSocketGraphQlClientBuilder>
|
||||
implements WebSocketGraphQlClient.Builder<DefaultWebSocketGraphQlClientBuilder> {
|
||||
|
||||
private URI url;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final WebSocketClient webSocketClient;
|
||||
|
||||
private final CodecConfigurer codecConfigurer;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlClient#builder(String, WebSocketClient)}.
|
||||
*/
|
||||
DefaultWebSocketGraphQlClientBuilder(String url, WebSocketClient client) {
|
||||
this(toURI(url), client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to start via {@link WebSocketGraphQlClient#builder(URI, WebSocketClient)}.
|
||||
*/
|
||||
DefaultWebSocketGraphQlClientBuilder(URI url, WebSocketClient client) {
|
||||
this.url = url;
|
||||
this.webSocketClient = client;
|
||||
this.codecConfigurer = ClientCodecConfigurer.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to mutate.
|
||||
* @param transport the underlying transport with the current state
|
||||
*/
|
||||
DefaultWebSocketGraphQlClientBuilder(WebSocketGraphQlTransport transport) {
|
||||
this.url = transport.getUrl();
|
||||
this.headers.putAll(transport.getHeaders());
|
||||
this.webSocketClient = transport.getWebSocketClient();
|
||||
this.codecConfigurer = transport.getCodecConfigurer();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder url(String url) {
|
||||
return url(toURI(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder url(URI url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
private static URI toURI(String url) {
|
||||
return new DefaultUriBuilderFactory().uriString(url).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder header(String name, String... values) {
|
||||
this.headers.put(name, Arrays.asList(values));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
headersConsumer.accept(this.headers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder codecConfigurer(Consumer<CodecConfigurer> codecConfigurerConsumer) {
|
||||
codecConfigurerConsumer.accept(this.codecConfigurer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketGraphQlClient build() {
|
||||
|
||||
setJsonCodecs(
|
||||
CodecDelegate.findJsonEncoder(this.codecConfigurer),
|
||||
CodecDelegate.findJsonDecoder(this.codecConfigurer));
|
||||
|
||||
WebSocketGraphQlTransport transport = new WebSocketGraphQlTransport(
|
||||
this.url, this.headers, this.webSocketClient, this.codecConfigurer, getInterceptor());
|
||||
|
||||
GraphQlClient graphQlClient = super.buildGraphQlClient(transport);
|
||||
return new DefaultWebSocketGraphQlClient(graphQlClient, transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
private WebSocketGraphQlClientInterceptor getInterceptor() {
|
||||
|
||||
List<WebSocketGraphQlClientInterceptor> interceptors = getInterceptors().stream()
|
||||
.filter(interceptor -> interceptor instanceof WebSocketGraphQlClientInterceptor)
|
||||
.map(interceptor -> (WebSocketGraphQlClientInterceptor) interceptor)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assert.state(interceptors.size() <= 1,
|
||||
"Only a single interceptor of type WebSocketGraphQlClientInterceptor may be configured");
|
||||
|
||||
return (!interceptors.isEmpty() ? interceptors.get(0) : new WebSocketGraphQlClientInterceptor() {});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link WebSocketGraphQlClient} implementation.
|
||||
*/
|
||||
private static class DefaultWebSocketGraphQlClient extends AbstractDelegatingGraphQlClient implements WebSocketGraphQlClient {
|
||||
|
||||
private final WebSocketGraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
DefaultWebSocketGraphQlClient(GraphQlClient delegate, WebSocketGraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(delegate);
|
||||
|
||||
Assert.notNull(transport, "WebSocketGraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "`builderInitializer` is required");
|
||||
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> start() {
|
||||
return this.transport.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> stop() {
|
||||
return this.transport.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultWebSocketGraphQlClientBuilder mutate() {
|
||||
DefaultWebSocketGraphQlClientBuilder builder = new DefaultWebSocketGraphQlClientBuilder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* GraphQL client with a given, externally prepared transport.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class GenericGraphQlClient extends AbstractDelegatingGraphQlClient {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
private final Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer;
|
||||
|
||||
|
||||
GenericGraphQlClient(
|
||||
GraphQlClient graphQlClient, GraphQlTransport transport,
|
||||
Consumer<AbstractGraphQlClientBuilder<?>> builderInitializer) {
|
||||
|
||||
super(graphQlClient);
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
Assert.notNull(builderInitializer, "'builderInitializer' is required");
|
||||
this.transport = transport;
|
||||
this.builderInitializer = builderInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
Builder builder = new Builder(this.transport);
|
||||
this.builderInitializer.accept(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default {@link GraphQlClient.Builder} with a given transport.
|
||||
*/
|
||||
static final class Builder extends AbstractGraphQlClientBuilder<Builder> {
|
||||
|
||||
private final GraphQlTransport transport;
|
||||
|
||||
Builder(GraphQlTransport transport) {
|
||||
Assert.notNull(transport, "GraphQlTransport is required");
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphQlClient build() {
|
||||
GraphQlClient client = buildGraphQlClient(this.transport);
|
||||
return new GenericGraphQlClient(client, this.transport, getBuilderInitializer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public interface GraphQlClient {
|
||||
* @return the builder for further initialization
|
||||
*/
|
||||
static Builder<?> builder(GraphQlTransport transport) {
|
||||
return new GenericGraphQlClient.Builder(transport);
|
||||
return new DefaultTransportGraphQlClientBuilder(transport);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient {
|
||||
* Return a builder to initialize an {@link HttpGraphQlClient} with.
|
||||
*/
|
||||
static Builder<?> builder() {
|
||||
return new DefaultHttpGraphQlClient.Builder();
|
||||
return new DefaultHttpGraphQlClientBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient {
|
||||
* to mutate and customize further through the returned builder.
|
||||
*/
|
||||
static Builder<?> builder(WebClient.Builder webClientBuilder) {
|
||||
return new DefaultHttpGraphQlClient.Builder(webClientBuilder);
|
||||
return new DefaultHttpGraphQlClientBuilder(webClientBuilder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,14 +44,14 @@ public interface RSocketGraphQlClient extends GraphQlClient {
|
||||
* and adding JSON codecs.
|
||||
*/
|
||||
static Builder<?> builder() {
|
||||
return new DefaultRSocketGraphQlClient.Builder();
|
||||
return new DefaultRSocketGraphQlClientBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start with a given {@link #builder()}.
|
||||
*/
|
||||
static Builder<?> builder(RSocketRequester.Builder requesterBuilder) {
|
||||
return new DefaultRSocketGraphQlClient.Builder(requesterBuilder);
|
||||
return new DefaultRSocketGraphQlClientBuilder(requesterBuilder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public interface WebSocketGraphQlClient extends WebGraphQlClient {
|
||||
* @param webSocketClient the underlying transport client to use
|
||||
*/
|
||||
static Builder<?> builder(String url, WebSocketClient webSocketClient) {
|
||||
return new DefaultWebSocketGraphQlClient.Builder(url, webSocketClient);
|
||||
return new DefaultWebSocketGraphQlClientBuilder(url, webSocketClient);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ public interface WebSocketGraphQlClient extends WebGraphQlClient {
|
||||
* @param webSocketClient the underlying transport client to use
|
||||
*/
|
||||
static Builder<?> builder(URI url, WebSocketClient webSocketClient) {
|
||||
return new DefaultWebSocketGraphQlClient.Builder(url, webSocketClient);
|
||||
return new DefaultWebSocketGraphQlClientBuilder(url, webSocketClient);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user