{
25 | }
26 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/publisher/PublisherHttpClient.java:
--------------------------------------------------------------------------------
1 | package reactivefeign.publisher;
2 |
3 | import org.reactivestreams.Publisher;
4 | import reactivefeign.client.ReactiveHttpRequest;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | /**
9 | * @author Sergii Karpenko
10 | */
11 | public interface PublisherHttpClient {
12 |
13 | Publisher> executeRequest(ReactiveHttpRequest request);
14 | }
15 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/publisher/RetryPublisherHttpClient.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.publisher;
15 |
16 | import feign.MethodMetadata;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 | import reactor.core.publisher.Flux;
20 |
21 | import java.util.function.Function;
22 |
23 | import static reactivefeign.utils.FeignUtils.methodTag;
24 |
25 | /**
26 | * Wraps {@link PublisherHttpClient} with retry logic provided by retryFunction
27 | *
28 | * @author Sergii Karpenko
29 | */
30 | abstract public class RetryPublisherHttpClient implements PublisherHttpClient {
31 |
32 | private static final Logger logger = LoggerFactory.getLogger(RetryPublisherHttpClient.class);
33 |
34 | private final String feignMethodTag;
35 | protected final P publisherClient;
36 | protected final Function, Flux>> retryFunction;
37 |
38 | protected RetryPublisherHttpClient(P publisherClient,
39 | MethodMetadata methodMetadata,
40 | Function, Flux> retryFunction) {
41 | this.publisherClient = publisherClient;
42 | this.feignMethodTag = methodTag(methodMetadata);
43 | this.retryFunction = wrapWithLog(retryFunction, feignMethodTag);
44 | }
45 |
46 | protected Function outOfRetries() {
47 | return throwable -> {
48 | logger.debug("[{}]---> USED ALL RETRIES", feignMethodTag, throwable);
49 | return new OutOfRetriesException(throwable, feignMethodTag);
50 | };
51 | }
52 |
53 | protected static Function, Flux>> wrapWithLog(
54 | Function, Flux> retryFunction,
55 | String feignMethodTag) {
56 | return throwableFlux -> retryFunction.apply(throwableFlux)
57 | .doOnNext(throwable -> {
58 | if (logger.isDebugEnabled()) {
59 | logger.debug("[{}]---> RETRYING on error", feignMethodTag, throwable);
60 | }
61 | });
62 | }
63 |
64 | public static class OutOfRetriesException extends Exception {
65 | OutOfRetriesException(Throwable cause, String feignMethodTag) {
66 | super("All retries used for: " + feignMethodTag, cause);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/utils/FeignUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.utils;
15 |
16 | import feign.MethodMetadata;
17 | import org.reactivestreams.Publisher;
18 |
19 | import java.lang.reflect.ParameterizedType;
20 | import java.lang.reflect.Type;
21 |
22 | import static feign.Util.resolveLastTypeParameter;
23 | import static java.util.Optional.ofNullable;
24 |
25 | public class FeignUtils {
26 |
27 | public static String methodTag(MethodMetadata methodMetadata) {
28 | return methodMetadata.configKey().substring(0,
29 | methodMetadata.configKey().indexOf('('));
30 | }
31 |
32 | public static Class returnPublisherType(MethodMetadata methodMetadata) {
33 | final Type returnType = methodMetadata.returnType();
34 | return (Class)((ParameterizedType) returnType).getRawType();
35 | }
36 |
37 | public static Type returnActualType(MethodMetadata methodMetadata) {
38 | return resolveLastTypeParameter(methodMetadata.returnType(), returnPublisherType(methodMetadata));
39 | }
40 |
41 | public static Type bodyActualType(MethodMetadata methodMetadata) {
42 | return getBodyActualType(methodMetadata.bodyType());
43 | }
44 |
45 | public static Type getBodyActualType(Type bodyType) {
46 | return ofNullable(bodyType).map(type -> {
47 | if (type instanceof ParameterizedType) {
48 | Class> bodyClass = (Class>) ((ParameterizedType) type).getRawType();
49 | if (Publisher.class.isAssignableFrom(bodyClass)) {
50 | return resolveLastTypeParameter(bodyType, bodyClass);
51 | }
52 | else {
53 | return type;
54 | }
55 | }
56 | else {
57 | return type;
58 | }
59 | }).orElse(null);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/utils/HttpUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.utils;
15 |
16 | import static reactivefeign.utils.HttpUtils.StatusCodeFamily.*;
17 |
18 | public class HttpUtils {
19 |
20 | public static StatusCodeFamily familyOf(final int statusCode) {
21 | switch (statusCode / 100) {
22 | case 1:
23 | return INFORMATIONAL;
24 | case 2:
25 | return SUCCESSFUL;
26 | case 3:
27 | return REDIRECTION;
28 | case 4:
29 | return CLIENT_ERROR;
30 | case 5:
31 | return SERVER_ERROR;
32 | default:
33 | return OTHER;
34 | }
35 | }
36 |
37 | public enum StatusCodeFamily {
38 | INFORMATIONAL(false), SUCCESSFUL(false), REDIRECTION(false), CLIENT_ERROR(true), SERVER_ERROR(
39 | true), OTHER(false);
40 |
41 | private final boolean error;
42 |
43 | StatusCodeFamily(boolean error) {
44 | this.error = error;
45 | }
46 |
47 | public boolean isError() {
48 | return error;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/utils/MultiValueMapUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.utils;
15 |
16 | import java.util.ArrayList;
17 | import java.util.Collection;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | public class MultiValueMapUtils {
22 |
23 | public static void addAllOrdered(Map> multiMap, K key, List values) {
24 | multiMap.compute(key, (key_, values_) -> {
25 | List valuesMerged = values_ != null ? values_ : new ArrayList<>(values.size());
26 | valuesMerged.addAll(values);
27 | return valuesMerged;
28 | });
29 | }
30 |
31 | public static void addOrdered(Map> multiMap, K key, V value) {
32 | multiMap.compute(key, (key_, values_) -> {
33 | List valuesMerged = values_ != null ? values_ : new ArrayList<>(1);
34 | valuesMerged.add(value);
35 | return valuesMerged;
36 | });
37 | }
38 |
39 | public static void addAll(Map> multiMap, K key, Collection values) {
40 | multiMap.compute(key, (key_, values_) -> {
41 | Collection valuesMerged = values_ != null ? values_ : new ArrayList<>(values.size());
42 | valuesMerged.addAll(values);
43 | return valuesMerged;
44 | });
45 | }
46 |
47 | public static void add(Map> multiMap, K key, V value) {
48 | multiMap.compute(key, (key_, values_) -> {
49 | Collection valuesMerged = values_ != null ? values_ : new ArrayList<>(1);
50 | valuesMerged.add(value);
51 | return valuesMerged;
52 | });
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/main/java/reactivefeign/utils/Pair.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.utils;
15 |
16 | public class Pair {
17 | public final L left;
18 | public final R right;
19 |
20 | public Pair(L left, R right) {
21 | this.left = left;
22 | this.right = right;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/CompressionTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import com.github.tomakehurst.wiremock.common.Gzip;
18 | import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
19 | import org.junit.ClassRule;
20 | import org.junit.Test;
21 | import reactivefeign.testcase.IcecreamServiceApi;
22 | import reactivefeign.testcase.domain.Bill;
23 | import reactivefeign.testcase.domain.IceCreamOrder;
24 | import reactivefeign.testcase.domain.OrderGenerator;
25 | import reactor.core.publisher.Mono;
26 | import reactor.test.StepVerifier;
27 |
28 | import static com.github.tomakehurst.wiremock.client.WireMock.*;
29 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
30 | import static reactivefeign.TestUtils.equalsComparingFieldByFieldRecursively;
31 |
32 | /**
33 | * Test the new capability of Reactive Feign client to support both Feign Request.Options
34 | * (regression) and the new ReactiveOptions configuration.
35 | *
36 | * @author Sergii Karpenko
37 | */
38 |
39 | abstract public class CompressionTest {
40 |
41 | @ClassRule
42 | public static WireMockClassRule wireMockRule = new WireMockClassRule(
43 | wireMockConfig().dynamicPort());
44 |
45 | abstract protected ReactiveFeign.Builder builder(ReactiveOptions options);
46 |
47 | @Test
48 | public void testCompression() throws JsonProcessingException {
49 |
50 | IceCreamOrder order = new OrderGenerator().generate(20);
51 | Bill billExpected = Bill.makeBill(order);
52 |
53 | wireMockRule.stubFor(post(urlEqualTo("/icecream/orders"))
54 | .withHeader("Accept-Encoding", containing("gzip"))
55 | .withRequestBody(equalTo(TestUtils.MAPPER.writeValueAsString(order)))
56 | .willReturn(aResponse().withStatus(200)
57 | .withHeader("Content-Type", "application/json")
58 | .withHeader("Content-Encoding", "gzip")
59 | .withBody(Gzip.gzip(TestUtils.MAPPER.writeValueAsString(billExpected)))));
60 |
61 | IcecreamServiceApi client = builder(
62 | new ReactiveOptions.Builder()
63 | .setTryUseCompression(true)
64 | .build())
65 | .target(IcecreamServiceApi.class, "http://localhost:" + wireMockRule.port());
66 |
67 | Mono bill = client.makeOrder(order);
68 | StepVerifier.create(bill)
69 | .expectNextMatches(equalsComparingFieldByFieldRecursively(billExpected))
70 | .verifyComplete();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/ConnectionTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import org.hamcrest.Matchers;
17 | import org.junit.*;
18 | import org.junit.rules.ExpectedException;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | import java.io.IOException;
22 | import java.net.ConnectException;
23 | import java.net.ServerSocket;
24 | import java.net.Socket;
25 |
26 | /**
27 | * @author Sergii Karpenko
28 | */
29 | abstract public class ConnectionTimeoutTest {
30 |
31 | @Rule
32 | public ExpectedException expectedException = ExpectedException.none();
33 |
34 | private ServerSocket serverSocket;
35 | private Socket socket;
36 | private int port;
37 |
38 | abstract protected ReactiveFeign.Builder builder(ReactiveOptions options);
39 |
40 | @Before
41 | public void before() throws IOException {
42 | // server socket with single element backlog queue (1) and dynamicaly allocated
43 | // port (0)
44 | serverSocket = new ServerSocket(0, 1);
45 | // just get the allocated port
46 | port = serverSocket.getLocalPort();
47 | // fill backlog queue by this request so consequent requests will be blocked
48 | socket = new Socket();
49 | socket.connect(serverSocket.getLocalSocketAddress());
50 | }
51 |
52 | @After
53 | public void after() throws IOException {
54 | // some cleanup
55 | if (serverSocket != null && !serverSocket.isClosed()) {
56 | serverSocket.close();
57 | }
58 | }
59 |
60 | // TODO investigate why doesn't work on codecov.io but works locally
61 | @Ignore
62 | @Test
63 | public void shouldFailOnConnectionTimeout() {
64 |
65 | expectedException.expectCause(
66 |
67 | Matchers.any(ConnectException.class));
68 |
69 | IcecreamServiceApi client = builder(
70 | new ReactiveOptions.Builder()
71 | .setConnectTimeoutMillis(300)
72 | .setReadTimeoutMillis(100)
73 | .build())
74 | .target(IcecreamServiceApi.class, "http://localhost:" + port);
75 |
76 | client.findOrder(1).block();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/ContractTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import org.junit.Rule;
17 | import org.junit.Test;
18 | import org.junit.rules.ExpectedException;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 | import reactivefeign.testcase.IcecreamServiceApiBroken;
21 | import reactivefeign.testcase.IcecreamServiceApiBrokenByCopy;
22 |
23 | import static org.hamcrest.Matchers.containsString;
24 |
25 | /**
26 | * @author Sergii Karpenko
27 | */
28 |
29 | abstract public class ContractTest {
30 |
31 | @Rule
32 | public ExpectedException expectedException = ExpectedException.none();
33 |
34 | abstract protected ReactiveFeign.Builder builder();
35 |
36 | @Test
37 | public void shouldFailOnBrokenContract() {
38 |
39 | expectedException.expect(IllegalArgumentException.class);
40 | expectedException.expectMessage(containsString("Broken Contract"));
41 |
42 | this.builder()
43 | .contract(targetType -> {
44 | throw new IllegalArgumentException("Broken Contract");
45 | })
46 | .target(IcecreamServiceApi.class, "http://localhost:8888");
47 | }
48 |
49 | @Test
50 | public void shouldFailIfNotReactiveContract() {
51 |
52 | expectedException.expect(IllegalArgumentException.class);
53 | expectedException.expectMessage(containsString("IcecreamServiceApiBroken#findOrderBlocking(int)"));
54 |
55 | this.builder()
56 | .target(IcecreamServiceApiBroken.class, "http://localhost:8888");
57 | }
58 |
59 | @Test
60 | public void shouldFailIfMethodOperatesWithByteArray() {
61 |
62 | expectedException.expect(IllegalArgumentException.class);
63 | expectedException.expectMessage(containsString("IcecreamServiceApiBrokenByCopy#findOrderCopy(int)"));
64 |
65 | this.builder()
66 | .target(IcecreamServiceApiBrokenByCopy.class, "http://localhost:8888");
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/NotFoundTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
17 | import org.apache.http.HttpStatus;
18 | import org.junit.ClassRule;
19 | import org.junit.Test;
20 | import reactivefeign.testcase.IcecreamServiceApi;
21 | import reactor.test.StepVerifier;
22 |
23 | import static com.github.tomakehurst.wiremock.client.WireMock.*;
24 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
25 |
26 | /**
27 | * @author Sergii Karpenko
28 | */
29 | public abstract class NotFoundTest {
30 |
31 | @ClassRule
32 | public static WireMockClassRule wireMockRule = new WireMockClassRule(
33 | wireMockConfig().dynamicPort());
34 |
35 | abstract protected ReactiveFeign.Builder builder();
36 |
37 | @Test
38 | public void shouldReturnEmptyMono() {
39 |
40 | String orderUrl = "/icecream/orders/2";
41 | wireMockRule.stubFor(get(urlEqualTo(orderUrl))
42 | .withHeader("Accept", equalTo("application/json"))
43 | .willReturn(aResponse().withStatus(HttpStatus.SC_NOT_FOUND)));
44 |
45 | IcecreamServiceApi client = builder()
46 | .decode404()
47 | .target(IcecreamServiceApi.class, "http://localhost:" + wireMockRule.port());
48 |
49 | StepVerifier.create(client.findOrder(2))
50 | .expectNextCount(0)
51 | .verifyComplete();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/ReactivityTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
18 | import org.awaitility.Duration;
19 | import org.junit.ClassRule;
20 | import org.junit.Test;
21 | import reactivefeign.testcase.IcecreamServiceApi;
22 | import reactivefeign.testcase.domain.IceCreamOrder;
23 | import reactivefeign.testcase.domain.OrderGenerator;
24 |
25 | import java.util.concurrent.TimeUnit;
26 | import java.util.concurrent.atomic.AtomicInteger;
27 |
28 | import static com.github.tomakehurst.wiremock.client.WireMock.*;
29 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
30 | import static org.awaitility.Awaitility.waitAtMost;
31 |
32 | /**
33 | * @author Sergii Karpenko
34 | */
35 | abstract public class ReactivityTest {
36 |
37 | public static final int DELAY_IN_MILLIS = 500;
38 | public static final int CALLS_NUMBER = 500;
39 | public static final int REACTIVE_GAIN_RATIO = 10;
40 | @ClassRule
41 | public static WireMockClassRule wireMockRule = new WireMockClassRule(
42 | wireMockConfig()
43 | .asynchronousResponseEnabled(true)
44 | .dynamicPort());
45 |
46 | abstract protected ReactiveFeign.Builder builder();
47 |
48 | @Test
49 | public void shouldRunReactively() throws JsonProcessingException {
50 |
51 | IceCreamOrder orderGenerated = new OrderGenerator().generate(1);
52 | String orderStr = TestUtils.MAPPER.writeValueAsString(orderGenerated);
53 |
54 | wireMockRule.stubFor(get(urlEqualTo("/icecream/orders/1"))
55 | .withHeader("Accept", equalTo("application/json"))
56 | .willReturn(aResponse().withStatus(200)
57 | .withHeader("Content-Type", "application/json")
58 | .withBody(orderStr)
59 | .withFixedDelay(DELAY_IN_MILLIS)));
60 |
61 | IcecreamServiceApi client = builder()
62 | .target(IcecreamServiceApi.class,
63 | "http://localhost:" + wireMockRule.port());
64 |
65 | AtomicInteger counter = new AtomicInteger();
66 |
67 | new Thread(() -> {
68 | for (int i = 0; i < CALLS_NUMBER; i++) {
69 | client.findFirstOrder()
70 | .doOnNext(order -> counter.incrementAndGet())
71 | .subscribe();
72 | }
73 | }).start();
74 |
75 | waitAtMost(new Duration(timeToCompleteReactively(), TimeUnit.MILLISECONDS))
76 | .until(() -> counter.get() == CALLS_NUMBER);
77 | }
78 |
79 | public static int timeToCompleteReactively() {
80 | return CALLS_NUMBER * DELAY_IN_MILLIS / REACTIVE_GAIN_RATIO;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/ReadTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
17 | import org.junit.ClassRule;
18 | import org.junit.Test;
19 | import reactivefeign.client.ReadTimeoutException;
20 | import reactivefeign.testcase.IcecreamServiceApi;
21 | import reactor.test.StepVerifier;
22 |
23 | import static com.github.tomakehurst.wiremock.client.WireMock.*;
24 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
25 |
26 | /**
27 | * @author Sergii Karpenko
28 | */
29 | abstract public class ReadTimeoutTest {
30 |
31 | @ClassRule
32 | public static WireMockClassRule wireMockRule = new WireMockClassRule(
33 | wireMockConfig().dynamicPort());
34 |
35 | abstract protected ReactiveFeign.Builder builder(ReactiveOptions options);
36 |
37 | @Test
38 | public void shouldFailOnReadTimeout() {
39 |
40 | String orderUrl = "/icecream/orders/1";
41 |
42 | wireMockRule.stubFor(get(urlEqualTo(orderUrl))
43 | .withHeader("Accept", equalTo("application/json"))
44 | .willReturn(aResponse().withFixedDelay(200)));
45 |
46 | IcecreamServiceApi client = builder(
47 | new ReactiveOptions.Builder()
48 | .setConnectTimeoutMillis(300)
49 | .setReadTimeoutMillis(100)
50 | .build())
51 | .target(IcecreamServiceApi.class,
52 | "http://localhost:" + wireMockRule.port());
53 |
54 | StepVerifier.create(client.findOrder(1))
55 | .expectError(ReadTimeoutException.class)
56 | .verify();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/RequestInterceptorTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
18 | import feign.FeignException;
19 | import org.apache.http.HttpStatus;
20 | import org.junit.ClassRule;
21 | import org.junit.Test;
22 | import reactivefeign.testcase.IcecreamServiceApi;
23 | import reactivefeign.testcase.domain.IceCreamOrder;
24 | import reactivefeign.testcase.domain.OrderGenerator;
25 | import reactivefeign.utils.Pair;
26 | import reactor.test.StepVerifier;
27 |
28 | import static com.github.tomakehurst.wiremock.client.WireMock.*;
29 | import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
30 | import static java.util.Collections.singletonList;
31 | import static reactivefeign.TestUtils.equalsComparingFieldByFieldRecursively;
32 |
33 | /**
34 | * @author Sergii Karpenko
35 | */
36 | abstract public class RequestInterceptorTest {
37 |
38 | @ClassRule
39 | public static WireMockClassRule wireMockRule = new WireMockClassRule(
40 | wireMockConfig().dynamicPort());
41 |
42 | abstract protected ReactiveFeign.Builder builder();
43 |
44 | @Test
45 | public void shouldInterceptRequestAndSetAuthHeader() throws JsonProcessingException {
46 |
47 | String orderUrl = "/icecream/orders/1";
48 |
49 | IceCreamOrder orderGenerated = new OrderGenerator().generate(1);
50 | String orderStr = TestUtils.MAPPER.writeValueAsString(orderGenerated);
51 |
52 | wireMockRule.stubFor(get(urlEqualTo(orderUrl))
53 | .withHeader("Accept", equalTo("application/json"))
54 | .willReturn(aResponse().withStatus(HttpStatus.SC_UNAUTHORIZED)))
55 | .setPriority(100);
56 |
57 | wireMockRule.stubFor(get(urlEqualTo(orderUrl))
58 | .withHeader("Accept", equalTo("application/json"))
59 | .withHeader("Authorization", equalTo("Bearer mytoken123"))
60 | .willReturn(aResponse().withStatus(200)
61 | .withHeader("Content-Type", "application/json")
62 | .withBody(orderStr)))
63 | .setPriority(1);
64 |
65 | IcecreamServiceApi clientWithoutAuth = builder()
66 | .target(IcecreamServiceApi.class, "http://localhost:" + wireMockRule.port());
67 |
68 | StepVerifier.create(clientWithoutAuth.findFirstOrder())
69 | .expectError(notAuthorizedException())
70 | .verify();
71 |
72 | IcecreamServiceApi clientWithAuth = builder()
73 | .addHeaders(singletonList(new Pair<>("Authorization", "Bearer mytoken123")))
74 | .target(IcecreamServiceApi.class,
75 | "http://localhost:" + wireMockRule.port());
76 |
77 | StepVerifier.create(clientWithAuth.findFirstOrder())
78 | .expectNextMatches(equalsComparingFieldByFieldRecursively(orderGenerated))
79 | .expectComplete();
80 | }
81 |
82 | protected Class notAuthorizedException() {
83 | return FeignException.class;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/TestUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import com.fasterxml.jackson.databind.ObjectMapper;
18 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
19 |
20 | import java.util.function.Predicate;
21 |
22 | /**
23 | * Helper methods for tests.
24 | */
25 | class TestUtils {
26 | static final ObjectMapper MAPPER;
27 |
28 | static {
29 | MAPPER = new ObjectMapper();
30 | MAPPER.registerModule(new JavaTimeModule());
31 | }
32 |
33 | public static Predicate equalsComparingFieldByFieldRecursively(T rhs) {
34 | return lhs -> {
35 | try {
36 | return MAPPER.writeValueAsString(lhs).equals(MAPPER.writeValueAsString(rhs));
37 | } catch (JsonProcessingException e) {
38 | throw new RuntimeException(e);
39 | }
40 | };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/CompressionTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | /**
22 | * @author Sergii Karpenko
23 | */
24 | public class CompressionTest extends reactivefeign.CompressionTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
28 | return RestTemplateFakeReactiveFeign.builder().options(options);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/ConnectionTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | /**
22 | * @author Sergii Karpenko
23 | */
24 | public class ConnectionTimeoutTest extends reactivefeign.ConnectionTimeoutTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
28 | return RestTemplateFakeReactiveFeign.builder().options(options);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/ContractTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public class ContractTest extends reactivefeign.ContractTest {
23 |
24 | @Override
25 | protected ReactiveFeign.Builder builder() {
26 | return RestTemplateFakeReactiveFeign.builder();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/DefaultMethodTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | /**
22 | * @author Sergii Karpenko
23 | */
24 | public class DefaultMethodTest extends reactivefeign.DefaultMethodTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder() {
28 | return RestTemplateFakeReactiveFeign.builder();
29 | }
30 |
31 | @Override
32 | protected ReactiveFeign.Builder builder(Class apiClass) {
33 | return RestTemplateFakeReactiveFeign.builder();
34 | }
35 |
36 | @Override
37 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
38 | return RestTemplateFakeReactiveFeign.builder().options(options);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/LoggerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class LoggerTest extends reactivefeign.LoggerTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/NotFoundTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class NotFoundTest extends reactivefeign.NotFoundTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/ReactivityTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import org.awaitility.core.ConditionTimeoutException;
18 | import org.junit.Before;
19 | import org.junit.Test;
20 | import reactivefeign.ReactiveFeign;
21 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
22 | import reactivefeign.testcase.IcecreamServiceApi;
23 |
24 | public class ReactivityTest extends reactivefeign.ReactivityTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder() {
28 | return RestTemplateFakeReactiveFeign.builder();
29 | }
30 |
31 | @Test(expected = ConditionTimeoutException.class)
32 | @Override
33 | public void shouldRunReactively() throws JsonProcessingException {
34 | super.shouldRunReactively();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/ReadTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | /**
22 | * @author Sergii Karpenko
23 | */
24 | public class ReadTimeoutTest extends reactivefeign.ReadTimeoutTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
28 | return RestTemplateFakeReactiveFeign.builder().options(options);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/RequestInterceptorTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class RequestInterceptorTest extends reactivefeign.RequestInterceptorTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/RetryingTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class RetryingTest extends reactivefeign.RetryingTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/SmokeTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class SmokeTest extends reactivefeign.SmokeTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/StatusHandlerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.resttemplate.client.RestTemplateFakeReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class StatusHandlerTest extends reactivefeign.StatusHandlerTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return RestTemplateFakeReactiveFeign.builder();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/resttemplate/client/RestTemplateFakeReactiveFeign.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.resttemplate.client;
15 |
16 | import org.apache.http.impl.client.HttpClientBuilder;
17 | import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
18 | import org.springframework.web.client.RestTemplate;
19 | import reactivefeign.ReactiveFeign;
20 | import reactivefeign.ReactiveOptions;
21 |
22 | import static java.util.Optional.ofNullable;
23 |
24 | /**
25 | * {@link RestTemplate} based implementation
26 | *
27 | * @author Sergii Karpenko
28 | */
29 | public class RestTemplateFakeReactiveFeign {
30 |
31 | public static ReactiveFeign.Builder builder() {
32 | return new ReactiveFeign.Builder(){
33 |
34 | {
35 | clientFactory(methodMetadata -> new RestTemplateFakeReactiveHttpClient(
36 | methodMetadata, new RestTemplate(), false));
37 | }
38 |
39 | @Override
40 | public ReactiveFeign.Builder options(ReactiveOptions options) {
41 | HttpComponentsClientHttpRequestFactory requestFactory =
42 | new HttpComponentsClientHttpRequestFactory(
43 | HttpClientBuilder.create().build());
44 | if (options.getConnectTimeoutMillis() != null) {
45 | requestFactory.setConnectTimeout(options.getConnectTimeoutMillis().intValue());
46 | }
47 | if (options.getReadTimeoutMillis() != null) {
48 | requestFactory.setReadTimeout(options.getReadTimeoutMillis().intValue());
49 | }
50 |
51 | this.clientFactory(methodMetadata -> {
52 | boolean acceptGzip = ofNullable(options.isTryUseCompression()).orElse(false);
53 | return new RestTemplateFakeReactiveHttpClient(
54 | methodMetadata, new RestTemplate(requestFactory), acceptGzip);
55 | });
56 |
57 | return this;
58 | }
59 | };
60 | }
61 | }
62 |
63 |
64 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/IcecreamServiceApi.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase;
15 |
16 | import feign.Headers;
17 | import feign.Param;
18 | import feign.RequestLine;
19 | import reactivefeign.testcase.domain.Bill;
20 | import reactivefeign.testcase.domain.Flavor;
21 | import reactivefeign.testcase.domain.IceCreamOrder;
22 | import reactivefeign.testcase.domain.Mixin;
23 | import reactor.core.publisher.Flux;
24 | import reactor.core.publisher.Mono;
25 |
26 | /**
27 | * API of an iceream web service.
28 | *
29 | * @author Sergii Karpenko
30 | */
31 | @Headers({"Accept: application/json"})
32 | public interface IcecreamServiceApi {
33 |
34 | RuntimeException RUNTIME_EXCEPTION = new RuntimeException("tests exception");
35 |
36 | @RequestLine("GET /icecream/flavors")
37 | Flux getAvailableFlavors();
38 |
39 | @RequestLine("GET /icecream/mixins")
40 | Flux getAvailableMixins();
41 |
42 | @RequestLine("POST /icecream/orders")
43 | @Headers("Content-Type: application/json")
44 | Mono makeOrder(IceCreamOrder order);
45 |
46 | @RequestLine("GET /icecream/orders/{orderId}")
47 | Mono findOrder(@Param("orderId") int orderId);
48 |
49 | @RequestLine("POST /icecream/bills/pay")
50 | @Headers("Content-Type: application/json")
51 | Mono payBill(Bill bill);
52 |
53 | default Mono findFirstOrder() {
54 | return findOrder(1);
55 | }
56 |
57 | default Mono throwsException() {
58 | throw RUNTIME_EXCEPTION;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/IcecreamServiceApiBroken.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase;
15 |
16 | import feign.Headers;
17 | import feign.Param;
18 | import feign.RequestLine;
19 | import reactivefeign.ReactiveContract;
20 | import reactivefeign.testcase.domain.Bill;
21 | import reactivefeign.testcase.domain.Flavor;
22 | import reactivefeign.testcase.domain.IceCreamOrder;
23 | import reactivefeign.testcase.domain.Mixin;
24 | import reactor.core.publisher.Flux;
25 | import reactor.core.publisher.Mono;
26 |
27 | import java.util.Collection;
28 |
29 | /**
30 | * API of an iceream web service with one method that doesn't returns {@link Mono} or {@link Flux}
31 | * and violates {@link ReactiveContract}s rules.
32 | *
33 | * @author Sergii Karpenko
34 | */
35 | public interface IcecreamServiceApiBroken {
36 |
37 | @RequestLine("GET /icecream/orders/{orderId}")
38 | Mono findOrder(@Param("orderId") int orderId);
39 |
40 | /**
41 | * Method that doesn't respects contract.
42 | */
43 | @RequestLine("GET /icecream/orders/{orderId}")
44 | IceCreamOrder findOrderBlocking(@Param("orderId") int orderId);
45 | }
46 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/IcecreamServiceApiBrokenByCopy.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase;
15 |
16 | import feign.Headers;
17 | import feign.Param;
18 | import feign.RequestLine;
19 | import reactivefeign.ReactiveContract;
20 | import reactivefeign.testcase.domain.Bill;
21 | import reactivefeign.testcase.domain.Flavor;
22 | import reactivefeign.testcase.domain.IceCreamOrder;
23 | import reactivefeign.testcase.domain.Mixin;
24 | import reactor.core.publisher.Flux;
25 | import reactor.core.publisher.Mono;
26 |
27 | import java.nio.ByteBuffer;
28 | import java.util.Collection;
29 |
30 | /**
31 | * API of an iceream web service with one method that returns {@link Mono} or {@link Flux} of byte array
32 | * and violates {@link ReactiveContract}s rules.
33 | *
34 | * @author Sergii Karpenko
35 | */
36 | public interface IcecreamServiceApiBrokenByCopy {
37 |
38 | @RequestLine("GET /icecream/orders/{orderId}")
39 | Mono findOrder(@Param("orderId") int orderId);
40 |
41 | /**
42 | * Method that doesn't respects contract.
43 | */
44 | @RequestLine("GET /icecream/orders/{orderId}")
45 | Mono findOrderCopy(@Param("orderId") int orderId);
46 | }
47 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/domain/Bill.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase.domain;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | * Bill for consumed ice cream.
21 | */
22 | public class Bill {
23 | private static final Map PRICES = new HashMap<>();
24 |
25 | static {
26 | PRICES.put(1, (float) 2.00); // two euros for one ball (expensive!)
27 | PRICES.put(3, (float) 2.85); // 2.85€ for 3 balls
28 | PRICES.put(5, (float) 4.30); // 4.30€ for 5 balls
29 | PRICES.put(7, (float) 5); // only five euros for seven balls! Wow
30 | }
31 |
32 | private static final float MIXIN_PRICE = (float) 0.6; // price per mixin
33 |
34 | private Float price;
35 |
36 | public Bill() {}
37 |
38 | public Bill(final Float price) {
39 | this.price = price;
40 | }
41 |
42 | public Float getPrice() {
43 | return price;
44 | }
45 |
46 | public void setPrice(final Float price) {
47 | this.price = price;
48 | }
49 |
50 | /**
51 | * Makes a bill from an order.
52 | *
53 | * @param order ice cream order
54 | * @return bill
55 | */
56 | public static Bill makeBill(final IceCreamOrder order) {
57 | int nbBalls = order.getBalls().values().stream().mapToInt(Integer::intValue)
58 | .sum();
59 | Float price = PRICES.get(nbBalls) + order.getMixins().size() * MIXIN_PRICE;
60 | return new Bill(price);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/domain/Flavor.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase.domain;
15 |
16 | /**
17 | * Ice cream flavors.
18 | */
19 | public enum Flavor {
20 | STRAWBERRY, CHOCOLATE, BANANA, PISTACHIO, MELON, VANILLA
21 | }
22 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/domain/IceCreamOrder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase.domain;
15 |
16 | import java.time.Instant;
17 | import java.util.*;
18 |
19 | /**
20 | * Give me some ice-cream! :p
21 | */
22 | public class IceCreamOrder {
23 | private static Random random = new Random();
24 |
25 | private int id; // order id
26 | private Map balls; // how much balls of flavor
27 | private Set mixins; // and some mixins ...
28 | private Instant orderTimestamp; // and give it to me right now !
29 |
30 | IceCreamOrder() {}
31 |
32 | IceCreamOrder(int id) {
33 | this(id, Instant.now());
34 | }
35 |
36 | IceCreamOrder(int id, final Instant orderTimestamp) {
37 | this.id = id;
38 | this.balls = new HashMap<>();
39 | this.mixins = new HashSet<>();
40 | this.orderTimestamp = orderTimestamp;
41 | }
42 |
43 | IceCreamOrder addBall(final Flavor ballFlavor) {
44 | final Integer ballCount = balls.containsKey(ballFlavor)
45 | ? balls.get(ballFlavor) + 1
46 | : 1;
47 | balls.put(ballFlavor, ballCount);
48 | return this;
49 | }
50 |
51 | IceCreamOrder addMixin(final Mixin mixin) {
52 | mixins.add(mixin);
53 | return this;
54 | }
55 |
56 | IceCreamOrder withOrderTimestamp(final Instant orderTimestamp) {
57 | this.orderTimestamp = orderTimestamp;
58 | return this;
59 | }
60 |
61 | public int getId() {
62 | return id;
63 | }
64 |
65 | public Map getBalls() {
66 | return balls;
67 | }
68 |
69 | public Set getMixins() {
70 | return mixins;
71 | }
72 |
73 | public Instant getOrderTimestamp() {
74 | return orderTimestamp;
75 | }
76 |
77 | @Override
78 | public String toString() {
79 | return "IceCreamOrder{" + " id=" + id + ", balls=" + balls + ", mixins=" + mixins
80 | + ", orderTimestamp=" + orderTimestamp + '}';
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/domain/Mixin.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase.domain;
15 |
16 | /**
17 | * Ice cream mix-ins.
18 | */
19 | public enum Mixin {
20 | COOKIES, MNMS, CHOCOLATE_SIROP, STRAWBERRY_SIROP, NUTS, RAINBOW
21 | }
22 |
--------------------------------------------------------------------------------
/feign-reactor-core/src/test/java/reactivefeign/testcase/domain/OrderGenerator.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.testcase.domain;
15 |
16 | import java.time.Instant;
17 | import java.time.temporal.ChronoUnit;
18 | import java.util.Collection;
19 | import java.util.List;
20 | import java.util.Random;
21 | import java.util.stream.Collectors;
22 | import java.util.stream.IntStream;
23 |
24 | /**
25 | * Generator of random ice cream orders.
26 | */
27 | public class OrderGenerator {
28 | private static final int[] BALLS_NUMBER = {1, 3, 5, 7};
29 | private static final int[] MIXIN_NUMBER = {1, 2, 3};
30 |
31 | private static final Random random = new Random();
32 |
33 | public IceCreamOrder generate(int id) {
34 | final IceCreamOrder order = new IceCreamOrder(id);
35 | final int nbBalls = peekBallsNumber();
36 | final int nbMixins = peekMixinNumber();
37 |
38 | IntStream.rangeClosed(1, nbBalls).mapToObj(i -> this.peekFlavor())
39 | .forEach(order::addBall);
40 |
41 | IntStream.rangeClosed(1, nbMixins).mapToObj(i -> this.peekMixin())
42 | .forEach(order::addMixin);
43 |
44 | return order;
45 | }
46 |
47 | public Collection generateRange(int n) {
48 | Instant now = Instant.now();
49 |
50 | List orderTimestamps = IntStream.range(0, n)
51 | .mapToObj(minutes -> now.minus(minutes, ChronoUnit.MINUTES))
52 | .collect(Collectors.toList());
53 |
54 | return IntStream.range(0, n)
55 | .mapToObj(
56 | i -> this.generate(i).withOrderTimestamp(orderTimestamps.get(i)))
57 | .collect(Collectors.toList());
58 | }
59 |
60 | private int peekBallsNumber() {
61 | return BALLS_NUMBER[random.nextInt(BALLS_NUMBER.length)];
62 | }
63 |
64 | private int peekMixinNumber() {
65 | return MIXIN_NUMBER[random.nextInt(MIXIN_NUMBER.length)];
66 | }
67 |
68 | private Flavor peekFlavor() {
69 | return Flavor.values()[random.nextInt(Flavor.values().length)];
70 | }
71 |
72 | private Mixin peekMixin() {
73 | return Mixin.values()[random.nextInt(Mixin.values().length)];
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/main/java/reactivefeign/jetty/JettyReactiveFeign.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import com.fasterxml.jackson.core.async_.JsonFactory;
17 | import com.fasterxml.jackson.databind.ObjectMapper;
18 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
19 | import org.eclipse.jetty.client.HttpClient;
20 | import reactivefeign.ReactiveFeign;
21 | import reactivefeign.ReactiveOptions;
22 | import reactivefeign.jetty.client.JettyReactiveHttpClient;
23 |
24 | /**
25 | * Reactive Jetty client based implementation of reactive Feign
26 | *
27 | * @author Sergii Karpenko
28 | */
29 | public class JettyReactiveFeign {
30 |
31 | public static Builder builder() {
32 | try {
33 | HttpClient httpClient = new HttpClient();
34 | httpClient.start();
35 | ObjectMapper objectMapper = new ObjectMapper();
36 | objectMapper.registerModule(new JavaTimeModule());
37 | return new Builder<>(httpClient, new JsonFactory(), objectMapper);
38 | } catch (Exception e) {
39 | throw new RuntimeException(e);
40 | }
41 |
42 | }
43 |
44 | public static Builder builder(HttpClient httpClient, JsonFactory jsonFactory, ObjectMapper objectMapper) {
45 | return new Builder<>(httpClient, jsonFactory, objectMapper);
46 | }
47 |
48 | public static class Builder extends ReactiveFeign.Builder {
49 |
50 | protected HttpClient httpClient;
51 | protected JsonFactory jsonFactory;
52 | private ObjectMapper objectMapper;
53 | protected ReactiveOptions options;
54 |
55 | protected Builder(HttpClient httpClient, JsonFactory jsonFactory, ObjectMapper objectMapper) {
56 | setHttpClient(httpClient, jsonFactory, objectMapper);
57 | this.jsonFactory = jsonFactory;
58 | this.objectMapper = objectMapper;
59 | }
60 |
61 | @Override
62 | public Builder options(ReactiveOptions options) {
63 | if (options.getConnectTimeoutMillis() != null) {
64 | httpClient.setConnectTimeout(options.getConnectTimeoutMillis());
65 | }
66 | if (options.getReadTimeoutMillis() != null) {
67 | setHttpClient(httpClient, jsonFactory, objectMapper);
68 | }
69 | this.options = options;
70 | return this;
71 | }
72 |
73 | protected void setHttpClient(HttpClient httpClient, JsonFactory jsonFactory, ObjectMapper objectMapper){
74 | this.httpClient = httpClient;
75 | clientFactory(methodMetadata -> {
76 | JettyReactiveHttpClient jettyClient = JettyReactiveHttpClient.jettyClient(methodMetadata, httpClient, jsonFactory, objectMapper);
77 | if (options != null && options.getReadTimeoutMillis() != null) {
78 | jettyClient.setRequestTimeout(options.getReadTimeoutMillis());
79 | }
80 | return jettyClient;
81 | });
82 | }
83 | }
84 | }
85 |
86 |
87 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/main/java/reactivefeign/jetty/utils/ProxyPostProcessor.java:
--------------------------------------------------------------------------------
1 | package reactivefeign.jetty.utils;
2 |
3 | import org.eclipse.jetty.reactive.client.internal.AbstractSingleProcessor;
4 | import org.reactivestreams.Publisher;
5 | import org.reactivestreams.Subscriber;
6 |
7 | import java.util.function.BiConsumer;
8 |
9 | public class ProxyPostProcessor extends AbstractSingleProcessor{
10 |
11 | private final Publisher publisher;
12 | private final BiConsumer postProcessor;
13 |
14 | private ProxyPostProcessor(Publisher publisher, BiConsumer postProcessor) {
15 | this.publisher = publisher;
16 | this.postProcessor = postProcessor;
17 | }
18 |
19 | @Override
20 | public void onNext(I i) {
21 | try {
22 | downStreamOnNext(i);
23 | postProcessor.accept(i, null);
24 | } catch (Throwable err) {
25 | postProcessor.accept(i, err);
26 | }
27 | }
28 |
29 | @Override
30 | public void subscribe(Subscriber super I> s) {
31 | publisher.subscribe(this);
32 | super.subscribe(s);
33 | }
34 |
35 | public static Publisher postProcess(Publisher publisher, BiConsumer postProcessor){
36 | return new ProxyPostProcessor<>(publisher, postProcessor);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/CompressionTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class CompressionTest extends reactivefeign.CompressionTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
27 | return JettyReactiveFeign.builder().options(options);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/ConnectionTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class ConnectionTimeoutTest extends reactivefeign.ConnectionTimeoutTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
27 | return JettyReactiveFeign.builder().options(options);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/ContractTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 |
18 | /**
19 | * @author Sergii Karpenko
20 | */
21 | public class ContractTest extends reactivefeign.ContractTest {
22 |
23 | @Override
24 | protected ReactiveFeign.Builder builder() {
25 | return JettyReactiveFeign.builder();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/DefaultMethodTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class DefaultMethodTest extends reactivefeign.DefaultMethodTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder() {
27 | return JettyReactiveFeign.builder();
28 | }
29 |
30 | @Override
31 | protected ReactiveFeign.Builder builder(Class apiClass) {
32 | return JettyReactiveFeign.builder();
33 | }
34 |
35 | @Override
36 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
37 | return JettyReactiveFeign.builder().options(options);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/LoggerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.testcase.IcecreamServiceApi;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public class LoggerTest extends reactivefeign.LoggerTest {
23 |
24 | @Override
25 | protected ReactiveFeign.Builder builder() {
26 | return JettyReactiveFeign.builder();
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/NotFoundTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import com.fasterxml.jackson.databind.ObjectMapper;
18 | import org.junit.Test;
19 | import reactivefeign.ReactiveFeign;
20 | import reactivefeign.testcase.IcecreamServiceApi;
21 |
22 | /**
23 | * @author Sergii Karpenko
24 | */
25 | public class NotFoundTest extends reactivefeign.NotFoundTest {
26 |
27 | @Override
28 | protected ReactiveFeign.Builder builder() {
29 | return JettyReactiveFeign.builder();
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/ReactivityTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import com.fasterxml.jackson.core.JsonProcessingException;
17 | import reactivefeign.ReactiveFeign;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | public class ReactivityTest extends reactivefeign.ReactivityTest {
21 |
22 | @Override
23 | protected ReactiveFeign.Builder builder() {
24 | return JettyReactiveFeign.builder();
25 | }
26 |
27 | @Override
28 | public void shouldRunReactively() throws JsonProcessingException {
29 | super.shouldRunReactively();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/ReadTimeoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.ReactiveOptions;
18 | import reactivefeign.testcase.IcecreamServiceApi;
19 |
20 | /**
21 | * @author Sergii Karpenko
22 | */
23 | public class ReadTimeoutTest extends reactivefeign.ReadTimeoutTest {
24 |
25 | @Override
26 | protected ReactiveFeign.Builder builder(ReactiveOptions options) {
27 | return JettyReactiveFeign.builder().options(options);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/RequestInterceptorTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.testcase.IcecreamServiceApi;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public class RequestInterceptorTest extends reactivefeign.RequestInterceptorTest {
23 |
24 | @Override
25 | protected ReactiveFeign.Builder builder() {
26 | return JettyReactiveFeign.builder();
27 | }
28 |
29 | @Override
30 | protected Class notAuthorizedException() {
31 | return org.eclipse.jetty.client.HttpResponseException.class;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/RetryingTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import org.junit.Ignore;
17 | import org.junit.Test;
18 | import reactivefeign.ReactiveFeign;
19 | import reactivefeign.testcase.IcecreamServiceApi;
20 |
21 | /**
22 | * @author Sergii Karpenko
23 | */
24 | public class RetryingTest extends reactivefeign.RetryingTest {
25 |
26 | @Override
27 | protected ReactiveFeign.Builder builder() {
28 | return JettyReactiveFeign.builder();
29 | }
30 |
31 | @Test
32 | public void shouldFailAsNoMoreRetriesWithBackoff() {
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/SmokeTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.testcase.IcecreamServiceApi;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public class SmokeTest extends reactivefeign.SmokeTest {
23 |
24 | @Override
25 | protected ReactiveFeign.Builder builder() {
26 | return JettyReactiveFeign.builder();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/StatusHandlerTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.jetty;
15 |
16 | import reactivefeign.ReactiveFeign;
17 | import reactivefeign.testcase.IcecreamServiceApi;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public class StatusHandlerTest extends reactivefeign.StatusHandlerTest {
23 |
24 | @Override
25 | protected ReactiveFeign.Builder builder() {
26 | return JettyReactiveFeign.builder();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/java/reactivefeign/jetty/allfeatures/AllFeaturesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package reactivefeign.jetty.allfeatures;
18 |
19 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
20 | import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration;
21 | import reactivefeign.ReactiveFeign;
22 | import reactivefeign.jetty.JettyReactiveFeign;
23 |
24 | /**
25 | * @author Sergii Karpenko
26 | *
27 | * Tests ReactiveFeign in conjunction with WebFlux rest controller.
28 | */
29 | @EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration.class, ReactiveUserDetailsServiceAutoConfiguration.class})
30 | public class AllFeaturesTest extends reactivefeign.allfeatures.AllFeaturesTest {
31 |
32 | @Override
33 | protected ReactiveFeign.Builder builder() {
34 | return JettyReactiveFeign.builder();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/feign-reactor-jetty/src/test/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.github.reactivefeign
7 | feign-reactor
8 | 1.0.0-SNAPSHOT
9 |
10 |
11 | feign-reactor-rx2
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | io.projectreactor.addons
20 | reactor-adapter
21 |
22 |
23 |
24 | io.reactivex.rxjava2
25 | rxjava
26 |
27 |
28 |
29 | io.github.reactivefeign
30 | feign-reactor-webclient
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-webflux
36 |
37 |
38 | spring-boot-starter-logging
39 | org.springframework.boot
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-test
48 | test
49 |
50 |
51 | io.projectreactor
52 | reactor-test
53 | test
54 |
55 |
56 | junit
57 | junit
58 | test
59 |
60 |
61 |
62 | org.assertj
63 | assertj-core
64 | test
65 |
66 |
67 |
68 | com.github.tomakehurst
69 | wiremock
70 | test
71 |
72 |
73 |
74 | org.awaitility
75 | awaitility
76 | test
77 |
78 |
79 |
80 | com.google.guava
81 | guava
82 | test
83 |
84 |
85 |
86 | org.apache.logging.log4j
87 | log4j-slf4j-impl
88 | test
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/src/main/java/reactivefeign/rx2/Rx2Contract.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.rx2;
15 |
16 | import feign.Contract;
17 | import feign.MethodMetadata;
18 | import io.reactivex.Flowable;
19 | import io.reactivex.Maybe;
20 | import io.reactivex.Observable;
21 | import io.reactivex.Single;
22 | import reactor.core.publisher.Flux;
23 | import reactor.core.publisher.Mono;
24 |
25 | import java.lang.reflect.ParameterizedType;
26 | import java.lang.reflect.Type;
27 | import java.util.HashSet;
28 | import java.util.List;
29 | import java.util.Set;
30 |
31 | import static feign.Util.checkNotNull;
32 | import static java.util.Arrays.asList;
33 |
34 | /**
35 | * Contract allowing only {@link Mono} and {@link Flux} return type.
36 | *
37 | * @author Sergii Karpenko
38 | */
39 | public class Rx2Contract implements Contract {
40 |
41 | public static final Set RX2_TYPES = new HashSet<>(asList(
42 | Flowable.class, Observable.class, Single.class, Maybe.class));
43 |
44 | private final Contract delegate;
45 |
46 | public Rx2Contract(final Contract delegate) {
47 | this.delegate = checkNotNull(delegate, "delegate must not be null");
48 | }
49 |
50 | @Override
51 | public List parseAndValidatateMetadata(final Class> targetType) {
52 | final List methodsMetadata =
53 | this.delegate.parseAndValidatateMetadata(targetType);
54 |
55 | for (final MethodMetadata metadata : methodsMetadata) {
56 | final Type type = metadata.returnType();
57 | if (!isRx2Type(type)) {
58 | throw new IllegalArgumentException(String.format(
59 | "Method %s of contract %s doesn't returns rx2 types",
60 | metadata.configKey(), targetType.getSimpleName()));
61 | }
62 | }
63 |
64 | return methodsMetadata;
65 | }
66 |
67 | private boolean isRx2Type(final Type type) {
68 | return (type instanceof ParameterizedType)
69 | && RX2_TYPES.contains(((ParameterizedType) type).getRawType());
70 | }
71 |
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/src/main/java/reactivefeign/rx2/client/statushandler/Rx2ReactiveStatusHandler.java:
--------------------------------------------------------------------------------
1 | package reactivefeign.rx2.client.statushandler;
2 |
3 | import reactivefeign.client.ReactiveHttpResponse;
4 | import reactivefeign.client.statushandler.ReactiveStatusHandler;
5 | import reactor.core.publisher.Mono;
6 |
7 | import static reactor.adapter.rxjava.RxJava2Adapter.singleToMono;
8 |
9 | public class Rx2ReactiveStatusHandler implements ReactiveStatusHandler {
10 |
11 | private final Rx2StatusHandler statusHandler;
12 |
13 | public Rx2ReactiveStatusHandler(Rx2StatusHandler statusHandler) {
14 | this.statusHandler = statusHandler;
15 | }
16 |
17 | @Override
18 | public boolean shouldHandle(int status) {
19 | return statusHandler.shouldHandle(status);
20 | }
21 |
22 | @Override
23 | public Mono extends Throwable> decode(String methodKey, ReactiveHttpResponse response) {
24 | return singleToMono(statusHandler.decode(methodKey, response));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/src/main/java/reactivefeign/rx2/client/statushandler/Rx2StatusHandler.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.rx2.client.statushandler;
15 |
16 | import io.reactivex.Single;
17 | import reactivefeign.client.ReactiveHttpResponse;
18 |
19 | /**
20 | * @author Sergii Karpenko
21 | */
22 | public interface Rx2StatusHandler {
23 |
24 | boolean shouldHandle(int status);
25 |
26 | Single extends Throwable> decode(String methodKey, ReactiveHttpResponse response);
27 | }
28 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/src/main/java/reactivefeign/rx2/client/statushandler/Rx2StatusHandlers.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 The Feign Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package reactivefeign.rx2.client.statushandler;
15 |
16 | import io.reactivex.Single;
17 | import reactivefeign.client.ReactiveHttpResponse;
18 |
19 | import java.util.function.BiFunction;
20 | import java.util.function.Predicate;
21 |
22 | public class Rx2StatusHandlers {
23 |
24 |
25 | public static Rx2StatusHandler throwOnStatus(
26 | Predicate statusPredicate,
27 | BiFunction errorFunction) {
28 | return new Rx2StatusHandler() {
29 | @Override
30 | public boolean shouldHandle(int status) {
31 | return statusPredicate.test(status);
32 | }
33 |
34 | @Override
35 | public Single extends Throwable> decode(String methodKey, ReactiveHttpResponse response) {
36 | return Single.just(errorFunction.apply(methodKey, response));
37 | }
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/feign-reactor-rx2/src/main/java/reactivefeign/rx2/methodhandler/Rx2MethodHandler.java:
--------------------------------------------------------------------------------
1 | package reactivefeign.rx2.methodhandler;
2 |
3 | import io.reactivex.Flowable;
4 | import io.reactivex.Maybe;
5 | import io.reactivex.Observable;
6 | import io.reactivex.Single;
7 | import org.reactivestreams.Publisher;
8 | import reactivefeign.methodhandler.MethodHandler;
9 | import reactor.core.publisher.Flux;
10 | import reactor.core.publisher.Mono;
11 |
12 | import java.lang.reflect.Type;
13 | import static reactor.adapter.rxjava.RxJava2Adapter.*;
14 |
15 | public class Rx2MethodHandler implements MethodHandler {
16 |
17 | private final MethodHandler methodHandler;
18 | private final Type returnPublisherType;
19 |
20 | public Rx2MethodHandler(MethodHandler methodHandler, Type returnPublisherType) {
21 | this.methodHandler = methodHandler;
22 | this.returnPublisherType = returnPublisherType;
23 | }
24 |
25 | @Override
26 | @SuppressWarnings("unchecked")
27 | public Object invoke(final Object[] argv) {
28 | try {
29 | Publisher