Skip to content

Commit 3268e8e

Browse files
authored
#279 async service client (#280)
1 parent 3228d8f commit 3268e8e

76 files changed

Lines changed: 3556 additions & 373 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
language: java
22
dist: trusty
33
jdk:
4-
- openjdk8
54
- openjdk11
65
cache:
76
directories:
@@ -19,6 +18,7 @@ env:
1918
- secure: kJD4+ZMSvJT8W041hR90kxkrkdk/b5A1AkG/7M1W+2OlWz/IBO+lil9yyzVG0Uy7pEa6u7RHRoApy+N2kgnqOOS7Rgc8MRObPyK9SoBXmYH9WNTQIDjYGlfsJcyaCAb1NV0SxWrCKFdEdoVmca8a+qJjhM8Dix92REB7txmvJvq3t0pHIYT3YU2W8pvn4yCORjThipdIRn7cMkr5lhpwSfUyQ/Dal+1bAIsAg3GSAt2k5PeQ/pdlmcLYfSCgdsd7+vXllLXsIP+xSY0A2Sz5QTMQyxTYS8te+o6xJQERyt4HlBiLsjDznPVIMrmiDPciteDtgwJlDzKJ7hJHQxmrIZbZNyXbKqB3rdukspK276/k3YVya6rCwQd9GAUwLMXl1/c2ebFXBvMCjaMaHgf/EVbHQCHrAwy2J/IvtRlKNT4sQfovLmi7NYtKZ0+VStxxDkth/+dSN1lXm+KVmffjinAe9pIDhVFLPFBPR21igigSM+BU2lH6x3TYEJJQNZW8WRHk7qslP6tBmW6RGx41R+05J1qsqrFR4gNfKTMQ6Rg/ooXdo3nwQRM2jrvIGgJLJ8t1CD5WpV5js9QI2yNeQzyIKpDXeaZspKMkh/EUsK/ntfpBsNLfH6+WfKJOi1d/BLro9A9XEjvfkCIS6FyagCJxnewKmei+reEknULQmdo=
2019
- secure: Sog4Iy1swDx4rYGgOBPM8iDxcRbCWdqE7ngUxbxUgr5fzDki4yI2JGjecIK7BO6TFbCcWuhu3IGsvdY8k2W1DfScEo2tUlWRqPlw/nU89XEUqe8E4zghPyUhFHPAlGt4/TVnkQIxdotcSgJLrmqLQ638/KZHbXJ/HLjnoQfb0BWNWoqRIeduyqivhRJXw2Zd4HhEGaSfm6UN4FBGCmpEkRJOR8kjB4CqWx72G3VXXIjIII9i+l4032ERyJkUdFx7nyABID5/kS9VmFfChirFnzurbPHGYtYwqV4QFm5ZjNnsIh0OIO9Xt4inoIDQy/uELo4gRAJ9S+J8GkSh6UIMGLu6tuUXxxJJKDJuTz4hJ5eBQeO8GGpTkRknrdwRAr/KD0uFjdyUs8yhQ4KAtEhmXzM971zagAdFb2S8yruPOvO6dTWIIvQxvTDWhX5srDr+VZBb3DIPoXbl1oiUjMzo/V8AhK83qmfaqjFTesIEKGTRhAWHpeFEgE3rwT1e2STYNE0m+M7fjcY5/eAbuLMpOpgiBiMAhexgs67yZJanLgmuAscEnGVLgcYP8CJXLJK5sKYAV5Y4peobmnFLcvyeIQDyh+/h/ElOkiq5hmsRtWi+UO73CbTnK6ysTAibS8hGI8KlKB+LcxTOrGcxv/PqdmDGthe36PJttq0LKhWHuUY=
2120
- secure: HH/mp+PT7xtiLC0JJS73BLPPEt154oeXYMP+N9SqT+q6L6warGGzejhee/yi/WNMrRqt9cFUdEEmWDuNxrakGizJ0YHc4ty430FBcYBGguemJzI/Vl31rLKFI1JnkqsiWskPilrWyClzWyUDp233FQXO0ZXPyhDGPHfSGeDgCtdFqBXz7KUSPQfHiPwRPt6TO/z7JPQe5+b0apSuNWiHjKnCelgjb7QJjC4+9dlYCBe6qJfhHptqZs4yLvSexCzWqfHumhkx1APazjLHQvojukbD01PMWGBCyTWaDrF1CJO4J36nWHnHpvAibnAqVYNHuASQY77BGT6Pt6yx8mXjTbeV/D58JPDqHnGEoZq3Sp8OVkPmwaF1CIOmkBrROk3N2JJ5SLfpOvXmBDz7bhf9WiTVUxQpQABOfIMZkJvjnPP09WXRw5/iow/VwGezkM0z8qR+93/5EooJ7JBqvecOqrxoHnkv76fV54aY0wwwK7VEw4JzldIH7gF6mAMjWA2LYUS+ceU2dG21ok/fffc8bmroLItac8WnT5lu1tU6te6tev9tI7Q6Jm3ZRc+3HFNQUKLApJMcbDc9pt04JHXn3YvENL7hBXBuGYh1ajCc9PPdm8qKf+Xuh4fpMcm/G2FlUpDCwnVOLEBk9qc1QjyIk8y2Ssry4sxBmNVe23xPqsM=
21+
install: skip
2222
stages:
2323
- name: Build
2424
- name: Documentation

boms/minimal/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@
130130
<artifactId>devon4j-cxf-server-ws</artifactId>
131131
<version>${project.version}</version>
132132
</dependency>
133+
<dependency>
134+
<groupId>com.devonfw.java.modules</groupId>
135+
<artifactId>devon4j-http-client</artifactId>
136+
<version>${project.version}</version>
137+
</dependency>
138+
<dependency>
139+
<groupId>com.devonfw.java.modules</groupId>
140+
<artifactId>devon4j-http-client-rest</artifactId>
141+
<version>${project.version}</version>
142+
</dependency>
133143
<dependency>
134144
<groupId>com.devonfw.java.modules</groupId>
135145
<artifactId>devon4j-jpa-basic</artifactId>
@@ -221,6 +231,11 @@
221231
<artifactId>devon4j-starter-security-jwt</artifactId>
222232
<version>${project.version}</version>
223233
</dependency>
234+
<dependency>
235+
<groupId>com.devonfw.java.starters</groupId>
236+
<artifactId>devon4j-starter-http-client-rest-async</artifactId>
237+
<version>${project.version}</version>
238+
</dependency>
224239
</dependencies>
225240
</dependencyManagement>
226241

documentation/guide-service-client.asciidoc

Lines changed: 121 additions & 47 deletions
Large diffs are not rendered by default.

modules/cxf-client-rest/src/main/java/com/devonfw/module/cxf/common/impl/client/rest/CxfRestClientAutoConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import org.springframework.context.annotation.Bean;
44
import org.springframework.context.annotation.Configuration;
55

6-
import com.devonfw.module.service.common.api.sync.SyncServiceClientFactory;
6+
import com.devonfw.module.service.common.api.client.sync.SyncServiceClientFactory;
77

88
/**
99
* {@link Configuration} for REST (JAX-RS) clients using Apache CXF.
@@ -14,7 +14,7 @@
1414
public class CxfRestClientAutoConfiguration {
1515

1616
/**
17-
* @return an implemenation of {@link SyncServiceClientFactory} based on CXF for REST (JAX-RS).
17+
* @return an implementation of {@link SyncServiceClientFactory} based on CXF for REST (JAX-RS).
1818
*/
1919
@Bean
2020
public SyncServiceClientFactory syncServiceClientFactoryCxfRest() {
Lines changed: 21 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,57 @@
11
package com.devonfw.module.cxf.common.impl.client.rest;
22

3-
import java.io.IOException;
4-
import java.util.Map;
5-
import java.util.UUID;
3+
import java.net.URI;
64

5+
import javax.ws.rs.core.MediaType;
76
import javax.ws.rs.core.Response;
87
import javax.ws.rs.ext.Provider;
98

10-
import net.sf.mmm.util.exception.api.ServiceInvocationFailedException;
11-
129
import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
1310

14-
import com.devonfw.module.service.common.api.constants.ServiceConstants;
15-
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import com.devonfw.module.service.common.api.client.ServiceClientErrorFactory;
12+
import com.devonfw.module.service.common.api.client.context.ServiceContext;
1613

1714
/**
18-
* An Implementation of {@link ResponseExceptionMapper} that converts a REST failure {@link Response} compliant with
19-
* <a href="https://github.com/devonfw/devon4j/blob/develop/documentation/guide-rest.asciidoc#error-results">devonfw REST error specification</a>
20-
* to a {@link ServiceInvocationFailedException}.
15+
* An Implementation of {@link ResponseExceptionMapper} that converts a failure response back to a {@link Throwable}
16+
* using {@link ServiceClientErrorFactory}.
2117
*
2218
* @since 3.0.0
2319
*/
2420
@Provider
2521
public class RestServiceExceptionMapper implements ResponseExceptionMapper<Throwable> {
2622

27-
private String serviceName;
23+
private final ServiceClientErrorFactory errorUnmarshaller;
24+
25+
private final ServiceContext<?> context;
2826

2927
/**
3028
* The constructor.
3129
*
32-
* @param service the name (e.g. {@link Class#getName() qualified name}) of the
33-
* {@link com.devonfw.module.service.common.api.Service} that failed.
30+
* @param errorUnmarshaller the {@link ServiceClientErrorFactory}.
31+
* @param context the {@link ServiceContext}.
3432
*/
35-
public RestServiceExceptionMapper(String service) {
33+
public RestServiceExceptionMapper(ServiceClientErrorFactory errorUnmarshaller, ServiceContext<?> context) {
3634

3735
super();
38-
this.serviceName = service;
36+
this.errorUnmarshaller = errorUnmarshaller;
37+
this.context = context;
3938
}
4039

4140
@Override
4241
public Throwable fromResponse(Response response) {
4342

4443
response.bufferEntity();
4544
if (response.hasEntity()) {
46-
String json = response.readEntity(String.class);
47-
if ((json != null) && !json.isEmpty()) {
48-
try {
49-
ObjectMapper objectMapper = new ObjectMapper();
50-
Map<String, Object> jsonMap = objectMapper.readValue(json, Map.class);
51-
return createException(jsonMap);
52-
} catch (IOException e) {
53-
return new ServiceInvocationFailedTechnicalException(e, e.getMessage(), e.getClass().getSimpleName(), null,
54-
this.serviceName);
55-
}
45+
String data = response.readEntity(String.class);
46+
if ((data != null) && !data.isEmpty()) {
47+
MediaType mediaType = response.getMediaType();
48+
URI url = response.getLocation();
49+
String operation = null;
50+
String serviceDetails = this.context.getServiceDescription(operation, url.toString());
51+
return this.errorUnmarshaller.unmarshall(data, mediaType.toString(), response.getStatus(), serviceDetails);
5652
}
5753
}
5854
return null;
5955
}
6056

61-
private Throwable createException(Map<String, Object> jsonMap) {
62-
63-
String code = (String) jsonMap.get(ServiceConstants.KEY_CODE);
64-
String message = (String) jsonMap.get(ServiceConstants.KEY_MESSAGE);
65-
String uuidStr = (String) jsonMap.get(ServiceConstants.KEY_UUID);
66-
UUID uuid = uuidStr != null ? UUID.fromString(uuidStr) : null;
67-
68-
return createException(code, message, uuid);
69-
}
70-
71-
private Throwable createException(String code, String message, UUID uuid) {
72-
73-
return new ServiceInvocationFailedException(message, code, uuid, this.serviceName);
74-
}
75-
76-
/**
77-
* Extends {@link ServiceInvocationFailedException} as {@link #isTechnical() technical} exception.
78-
*/
79-
private static final class ServiceInvocationFailedTechnicalException extends ServiceInvocationFailedException {
80-
81-
private static final long serialVersionUID = 1L;
82-
83-
/**
84-
* The constructor.
85-
*
86-
* @param cause the {@link #getCause() cause} of this exception.
87-
* @param message the {@link #getMessage() message}.
88-
* @param code the {@link #getCode() code}.
89-
* @param uuid {@link UUID} the {@link #getUuid() UUID}.
90-
* @param service the name (e.g. {@link Class#getName() qualified name}) of the service that failed.
91-
*/
92-
private ServiceInvocationFailedTechnicalException(Throwable cause, String message, String code, UUID uuid,
93-
String service) {
94-
95-
super(cause, message, code, uuid, service);
96-
}
97-
98-
@Override
99-
public boolean isForUser() {
100-
101-
return false;
102-
}
103-
}
104-
10557
}

modules/cxf-client-rest/src/main/java/com/devonfw/module/cxf/common/impl/client/rest/SyncServiceClientFactoryCxfRest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
import com.devonfw.module.cxf.common.impl.client.SyncServiceClientFactoryCxf;
1616
import com.devonfw.module.service.common.api.client.context.ServiceContext;
17+
import com.devonfw.module.service.common.api.client.sync.SyncServiceClientFactory;
1718
import com.devonfw.module.service.common.api.constants.ServiceConstants;
18-
import com.devonfw.module.service.common.api.sync.SyncServiceClientFactory;
1919
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
2020

2121
/**
@@ -31,6 +31,7 @@ public class SyncServiceClientFactoryCxfRest extends SyncServiceClientFactoryCxf
3131
* The constructor.
3232
*/
3333
public SyncServiceClientFactoryCxfRest() {
34+
3435
super();
3536
}
3637

@@ -44,18 +45,18 @@ public void setJsonProvider(JacksonJsonProvider jsonProvider) {
4445
}
4546

4647
@Override
47-
protected <S> void applyAspects(ServiceContext<S> context, S serviceClient, String serviceName) {
48+
protected <S> void applyAspects(ServiceContext<S> context, S serviceClient) {
4849

4950
ClientConfiguration clientConfig = WebClient.getConfig(serviceClient);
50-
applyInterceptors(context, clientConfig, serviceName);
51+
applyInterceptors(context, clientConfig);
5152
applyClientPolicy(context, clientConfig.getHttpConduit());
5253
applyHeaders(context, serviceClient);
5354
}
5455

5556
@Override
56-
protected <S> S createService(ServiceContext<S> context, String url, String serviceName) {
57+
protected <S> S createService(ServiceContext<S> context, String url) {
5758

58-
List<Object> providers = createProviderList(context, serviceName);
59+
List<Object> providers = createProviderList(context);
5960
return JAXRSClientFactory.create(url, context.getApi(), providers);
6061
}
6162

@@ -85,16 +86,15 @@ protected boolean isResponsibleForService(ServiceContext<?> context) {
8586

8687
/**
8788
* @param context the {@link ServiceContext}.
88-
* @param serviceName the {@link #createServiceName(ServiceContext) service name}.
8989
* @return the {@link List} of {@link javax.ws.rs.ext.Provider}s.
9090
*/
91-
protected List<Object> createProviderList(ServiceContext<?> context, String serviceName) {
91+
protected List<Object> createProviderList(ServiceContext<?> context) {
9292

9393
List<Object> providers = new ArrayList<>();
9494
if (this.jsonProvider != null) {
9595
providers.add(this.jsonProvider);
9696
}
97-
providers.add(new RestServiceExceptionMapper(serviceName));
97+
providers.add(new RestServiceExceptionMapper(getErrorFactory(), context));
9898
return providers;
9999
}
100100

modules/cxf-client-ws/src/main/java/com/devonfw/module/cxf/common/impl/client/ws/CxfWsClientAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import org.springframework.context.annotation.Bean;
44
import org.springframework.context.annotation.Configuration;
55

6-
import com.devonfw.module.service.common.api.sync.SyncServiceClientFactory;
6+
import com.devonfw.module.service.common.api.client.sync.SyncServiceClientFactory;
77

88
/**
99
* {@link Configuration} for SOAP (JAX-WS) clients using Apache CXF.

modules/cxf-client-ws/src/main/java/com/devonfw/module/cxf/common/impl/client/ws/SyncServiceClientFactoryCxfWs.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222
import com.devonfw.module.cxf.common.impl.client.SyncServiceClientFactoryCxf;
2323
import com.devonfw.module.service.common.api.client.context.ServiceContext;
24+
import com.devonfw.module.service.common.api.client.sync.SyncServiceClientFactory;
2425
import com.devonfw.module.service.common.api.config.ServiceConfig;
2526
import com.devonfw.module.service.common.api.constants.ServiceConstants;
26-
import com.devonfw.module.service.common.api.sync.SyncServiceClientFactory;
2727

2828
/**
2929
* Implementation of {@link SyncServiceClientFactory} for JAX-WS SOAP service clients using Apache CXF.
@@ -35,7 +35,7 @@ public class SyncServiceClientFactoryCxfWs extends SyncServiceClientFactoryCxf {
3535
private static final String WSDL_SUFFIX = "?wsdl";
3636

3737
@Override
38-
protected <S> S createService(ServiceContext<S> context, String url, String serviceName) {
38+
protected <S> S createService(ServiceContext<S> context, String url) {
3939

4040
Class<S> api = context.getApi();
4141
WebService webService = api.getAnnotation(WebService.class);
@@ -59,10 +59,10 @@ protected <S> S createService(ServiceContext<S> context, String url, String serv
5959
}
6060

6161
@Override
62-
protected <S> void applyAspects(ServiceContext<S> context, S serviceClient, String serviceName) {
62+
protected <S> void applyAspects(ServiceContext<S> context, S serviceClient) {
6363

6464
Client cxfClient = ClientProxy.getClient(serviceClient);
65-
applyInterceptors(context, cxfClient, serviceName);
65+
applyInterceptors(context, cxfClient);
6666
Conduit conduit = cxfClient.getConduit();
6767
if (conduit instanceof HTTPConduit) {
6868
HTTPConduit httpConduit = (HTTPConduit) conduit;
Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,17 @@
11
package com.devonfw.module.cxf.common.impl.client;
22

3-
import org.springframework.context.annotation.Bean;
43
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.context.annotation.Import;
55

6-
import com.devonfw.module.service.common.api.client.ServiceClientFactory;
7-
import com.devonfw.module.service.common.api.client.discovery.ServiceDiscoverer;
8-
import com.devonfw.module.service.common.api.config.ServiceConfig;
9-
import com.devonfw.module.service.common.api.header.ServiceHeaderCustomizer;
10-
import com.devonfw.module.service.common.base.config.ServiceConfigProperties;
11-
import com.devonfw.module.service.common.impl.ServiceClientFactoryImpl;
12-
import com.devonfw.module.service.common.impl.discovery.ServiceDiscovererImplConfig;
13-
import com.devonfw.module.service.common.impl.header.ServiceHeaderCustomizerAuthForward;
14-
import com.devonfw.module.service.common.impl.header.ServiceHeaderCustomizerBasicAuth;
15-
import com.devonfw.module.service.common.impl.header.ServiceHeaderCustomizerCorrelationId;
16-
import com.devonfw.module.service.common.impl.header.ServiceHeaderCustomizerOAuth;
6+
import com.devonfw.module.service.common.impl.client.ServiceClientAutoConfiguration;
177

188
/**
199
* {@link Configuration} for REST (JAX-RS) clients using Apache CXF.
2010
*
2111
* @since 3.0.0
2212
*/
2313
@Configuration
24-
// @Import(ServiceClientSpringFactory.class)
14+
@Import(ServiceClientAutoConfiguration.class)
2515
public class CxfClientAutoConfiguration {
2616

27-
/**
28-
* @return the implementation of {@link ServiceClientFactory}.
29-
*/
30-
@Bean
31-
public ServiceClientFactory serviceClientFactory() {
32-
33-
return new ServiceClientFactoryImpl();
34-
}
35-
36-
/**
37-
* @return the implementation of {@link ServiceConfig}.
38-
*/
39-
@Bean
40-
public ServiceConfig serviceClientConfig() {
41-
42-
return new ServiceConfigProperties();
43-
}
44-
45-
/**
46-
* @return an implementation of {@link ServiceDiscoverer} based on {@link #serviceClientConfig()}.
47-
*/
48-
@Bean
49-
public ServiceDiscoverer serviceDiscovererConfig() {
50-
51-
return new ServiceDiscovererImplConfig();
52-
}
53-
54-
/**
55-
* @return an implementation of {@link ServiceHeaderCustomizer} passing correlation ID.
56-
*/
57-
@Bean
58-
public ServiceHeaderCustomizer serviceHeaderCustomizerCorrelationId() {
59-
60-
return new ServiceHeaderCustomizerCorrelationId();
61-
}
62-
63-
/**
64-
* @return an implementation of {@link ServiceHeaderCustomizer} for basic authentication support.
65-
*/
66-
@Bean
67-
public ServiceHeaderCustomizer serviceHeaderCustomizerBasicAuth() {
68-
69-
return new ServiceHeaderCustomizerBasicAuth();
70-
}
71-
72-
/**
73-
* @return an implementation of {@link ServiceHeaderCustomizer} for OAuth support.
74-
*/
75-
@Bean
76-
public ServiceHeaderCustomizer serviceHeaderCustomizerOAuth() {
77-
78-
return new ServiceHeaderCustomizerOAuth();
79-
}
80-
81-
/**
82-
* @return an implementation of {@link ServiceHeaderCustomizer} for JWT support.
83-
*/
84-
@Bean
85-
public ServiceHeaderCustomizer serviceHeaderCustomizerAuthForward() {
86-
87-
return new ServiceHeaderCustomizerAuthForward();
88-
}
8917
}

0 commit comments

Comments
 (0)