Skip to content

Commit

Permalink
[SYNCOPE-1763] Upgrading to CXF 4.0.2 + reviewing client usage (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgrosso committed Jun 16, 2023
1 parent 5aa5bf6 commit 7e76aa8
Show file tree
Hide file tree
Showing 45 changed files with 643 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class SyncopeCoreHealthIndicator implements HealthIndicator {

protected final boolean useGZIPCompression;

private UserSelfService service;

public SyncopeCoreHealthIndicator(
final ServiceOps serviceOps,
final String anonymousUser,
Expand All @@ -53,16 +55,25 @@ public SyncopeCoreHealthIndicator(
this.useGZIPCompression = useGZIPCompression;
}

protected UserSelfService service() {
synchronized (this) {
if (service == null) {
service = new SyncopeClientFactoryBean().
setAddress(serviceOps.get(NetworkService.Type.CORE).getAddress()).
setUseCompression(useGZIPCompression).
create(new AnonymousAuthenticationHandler(anonymousUser, anonymousKey)).
getService(UserSelfService.class);
}
}
return service;
}

@Override
public Health health() {
Health.Builder builder = new Health.Builder();

try {
new SyncopeClientFactoryBean().
setAddress(serviceOps.get(NetworkService.Type.CORE).getAddress()).
setUseCompression(useGZIPCompression).
create(new AnonymousAuthenticationHandler(anonymousUser, anonymousKey)).
getService(UserSelfService.class).read();
service().read();
builder.status(Status.UP);
} catch (Exception e) {
LOG.debug("When attempting to connect to Syncope Core", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
org.apache.syncope.client.enduser.EnduserContext
org.apache.syncope.client.enduser.IdRepoEnduserContext
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.syncope.common.lib.info.NumbersInfo;
import org.apache.syncope.common.lib.info.PlatformInfo;
import org.apache.syncope.common.lib.info.SystemInfo;
Expand All @@ -44,9 +45,17 @@ public SyncopeAnonymousClient(
final RestClientExceptionMapper exceptionMapper,
final AnonymousAuthenticationHandler anonymousAuthHandler,
final boolean useCompression,
final HTTPClientPolicy httpClientPolicy,
final TLSClientParameters tlsClientParameters) {

super(mediaType, restClientFactory, exceptionMapper, anonymousAuthHandler, useCompression, tlsClientParameters);
super(
mediaType,
restClientFactory,
exceptionMapper,
anonymousAuthHandler,
useCompression,
httpClientPolicy,
tlsClientParameters);
this.anonymousAuthHandler = anonymousAuthHandler;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
Expand All @@ -38,7 +39,8 @@
import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
import org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.syncope.client.lib.batch.BatchRequest;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
Expand Down Expand Up @@ -76,6 +78,8 @@ public class SyncopeClient {

protected final boolean useCompression;

protected final HTTPClientPolicy httpClientPolicy;

protected final TLSClientParameters tlsClientParameters;

public SyncopeClient(
Expand All @@ -84,6 +88,7 @@ public SyncopeClient(
final RestClientExceptionMapper exceptionMapper,
final AuthenticationHandler authHandler,
final boolean useCompression,
final HTTPClientPolicy httpClientPolicy,
final TLSClientParameters tlsClientParameters) {

this.mediaType = mediaType;
Expand All @@ -93,6 +98,7 @@ public SyncopeClient(
}
this.exceptionMapper = exceptionMapper;
this.useCompression = useCompression;
this.httpClientPolicy = httpClientPolicy;
this.tlsClientParameters = tlsClientParameters;

init(authHandler);
Expand Down Expand Up @@ -279,30 +285,31 @@ public String getDomain() {
* @return service instance of the given reference class
*/
public <T> T getService(final Class<T> serviceClass) {
T serviceInstance;
synchronized (restClientFactory) {
restClientFactory.setServiceClass(serviceClass);
T serviceInstance = restClientFactory.create(serviceClass);

Client client = WebClient.client(serviceInstance);
client.type(mediaType).accept(mediaType);
if (serviceInstance instanceof AnyService || serviceInstance instanceof ExecutableService) {
client.accept(RESTHeaders.MULTIPART_MIXED);
}
serviceInstance = restClientFactory.create(serviceClass);
}

ClientConfiguration config = WebClient.getConfig(client);
config.getRequestContext().put(HEADER_SPLIT_PROPERTY, true);
config.getRequestContext().put(URLConnectionHTTPConduit.HTTPURL_CONNECTION_METHOD_REFLECTION, true);
if (useCompression) {
config.getInInterceptors().add(new GZIPInInterceptor());
config.getOutInterceptors().add(new GZIPOutInterceptor());
}
if (tlsClientParameters != null) {
HTTPConduit httpConduit = (HTTPConduit) config.getConduit();
httpConduit.setTlsClientParameters(tlsClientParameters);
}
Client client = WebClient.client(serviceInstance);
client.type(mediaType).accept(mediaType);
if (serviceInstance instanceof AnyService || serviceInstance instanceof ExecutableService) {
client.accept(RESTHeaders.MULTIPART_MIXED);
}

return serviceInstance;
ClientConfiguration config = WebClient.getConfig(client);
config.getRequestContext().put(HEADER_SPLIT_PROPERTY, true);
config.getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, Boolean.TRUE);
if (useCompression) {
config.getInInterceptors().add(new GZIPInInterceptor());
config.getOutInterceptors().add(new GZIPOutInterceptor());
}

HTTPConduit httpConduit = (HTTPConduit) config.getConduit();
Optional.ofNullable(httpClientPolicy).ifPresent(httpConduit::setClient);
Optional.ofNullable(tlsClientParameters).ifPresent(httpConduit::setTlsClientParameters);

return serviceInstance;
}

public Triple<Map<String, Set<String>>, List<String>, UserTO> self() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
import org.apache.cxf.transports.http.configuration.ConnectionType;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.syncope.common.lib.jackson.SyncopeJsonMapper;
import org.apache.syncope.common.lib.jackson.SyncopeXmlMapper;
import org.apache.syncope.common.lib.jackson.SyncopeYAMLMapper;
Expand Down Expand Up @@ -82,6 +84,8 @@ public static ContentType fromString(final String value) {

private boolean useCompression;

private HTTPClientPolicy httpClientPolicy;

private TLSClientParameters tlsClientParameters;

private JAXRSClientFactoryBean restClientFactoryBean;
Expand All @@ -102,6 +106,12 @@ protected static RestClientExceptionMapper defaultExceptionMapper() {
return new RestClientExceptionMapper();
}

protected static HTTPClientPolicy defaultHTTPClientPolicy() {
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnection(ConnectionType.CLOSE);
return policy;
}

protected JAXRSClientFactoryBean defaultRestClientFactoryBean() {
JAXRSClientFactoryBean defaultRestClientFactoryBean = new JAXRSClientFactoryBean();
defaultRestClientFactoryBean.setHeaders(new HashMap<>());
Expand Down Expand Up @@ -210,6 +220,15 @@ public boolean isUseCompression() {
return useCompression;
}

public SyncopeClientFactoryBean setHttpClientPolicy(final HTTPClientPolicy httpClientPolicy) {
this.httpClientPolicy = httpClientPolicy;
return this;
}

public HTTPClientPolicy getHttpClientPolicy() {
return Optional.ofNullable(httpClientPolicy).orElseGet(SyncopeClientFactoryBean::defaultHTTPClientPolicy);
}

/**
* Sets the client TLS configuration.
*
Expand Down Expand Up @@ -272,6 +291,7 @@ public SyncopeClient create(final AuthenticationHandler handler) {
getExceptionMapper(),
handler,
useCompression,
getHttpClientPolicy(),
tlsClientParameters);
}

Expand All @@ -289,6 +309,7 @@ public SyncopeAnonymousClient createAnonymous(final String username, final Strin
getExceptionMapper(),
new AnonymousAuthenticationHandler(username, password),
useCompression,
getHttpClientPolicy(),
tlsClientParameters);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public JAXRSClientFactoryBean selfKeymasterRESTClientFactoryBean(final Keymaster
restClientFactoryBean.setPassword(props.getPassword());
restClientFactoryBean.setThreadSafe(true);
restClientFactoryBean.setInheritHeaders(true);
restClientFactoryBean.setFeatures(List.of(new LoggingFeature()));
restClientFactoryBean.getFeatures().add(new LoggingFeature());
restClientFactoryBean.setProviders(List.of(
new JacksonJsonProvider(JsonMapper.builder().findAndAddModules().build()),
new SelfKeymasterClientExceptionMapper()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import jakarta.ws.rs.client.CompletionStageRxInvoker;
import jakarta.ws.rs.core.MediaType;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.jaxrs.client.Client;
Expand All @@ -28,29 +30,48 @@
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.ConnectionType;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

abstract class SelfKeymasterOps {

protected final Map<Class<?>, Object> services = Collections.synchronizedMap(new HashMap<>());

private final JAXRSClientFactoryBean clientFactory;

protected HTTPClientPolicy httpClientPolicy;

protected SelfKeymasterOps(final JAXRSClientFactoryBean clientFactory) {
this.clientFactory = clientFactory;

httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnection(ConnectionType.CLOSE);
}

protected <T> T client(final Class<T> serviceClass, final Map<String, String> headers) {
@SuppressWarnings("unchecked")
public <T> T client(final Class<T> serviceClass, final Map<String, String> headers) {
T service;
synchronized (clientFactory) {
clientFactory.setServiceClass(serviceClass);
clientFactory.setHeaders(headers);
service = clientFactory.create(serviceClass);
}
if (services.containsKey(serviceClass)) {
service = (T) services.get(serviceClass);
} else {
synchronized (clientFactory) {
clientFactory.setServiceClass(serviceClass);
clientFactory.setHeaders(headers);
service = clientFactory.create(serviceClass);
}
services.put(serviceClass, service);

Client client = WebClient.client(service);
client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
Client client = WebClient.client(service);
client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);

ClientConfiguration config = WebClient.getConfig(client);
config.getInInterceptors().add(new GZIPInInterceptor());
config.getOutInterceptors().add(new GZIPOutInterceptor());
ClientConfiguration config = WebClient.getConfig(client);
config.getInInterceptors().add(new GZIPInInterceptor());
config.getOutInterceptors().add(new GZIPOutInterceptor());

HTTPConduit httpConduit = (HTTPConduit) config.getConduit();
httpConduit.setClient(httpClientPolicy);
}

return service;
}
Expand Down
6 changes: 5 additions & 1 deletion core/idrepo/rest-cxf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ under the License.
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
Expand All @@ -67,6 +67,10 @@ under the License.
<artifactId>jackson-jakarta-rs-yaml-provider</artifactId>
</dependency>

<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.io.InputStream;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.Bus;
Expand Down Expand Up @@ -169,10 +170,8 @@ public Response batch() {
MediaType mediaType = MediaType.valueOf(messageContext.getHttpServletRequest().getContentType());
String boundary = mediaType.getParameters().get(RESTHeaders.BOUNDARY_PARAMETER);

Batch batch = batchDAO.find(boundary);
if (batch == null) {
throw new NotFoundException("Batch " + boundary);
}
Batch batch = Optional.ofNullable(batchDAO.find(boundary)).
orElseThrow(() -> new NotFoundException("Batch " + boundary));

if (batch.getResults() == null) {
return Response.accepted().
Expand Down
Loading

0 comments on commit 7e76aa8

Please sign in to comment.