From 1815e13b79c6e630a5456664630e0369940df59a Mon Sep 17 00:00:00 2001 From: David Gracza <37271364+gr4cza@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:47:39 +0200 Subject: [PATCH] Update javax dependencies in the client to jakarta Replaced `javax.ws.rs` with `jakarta.ws.rs` and updated related imports and client request handling logic. Modified several classes to use Jakarta libraries instead of deprecated javax libraries and updated dependencies to the latest versions. --- client/build.gradle | 6 +- .../conductor/client/http/ClientBase.java | 141 +++++++----------- .../client/http/ClientRequestHandler.java | 58 +++---- .../conductor/client/http/EventClient.java | 39 ++--- .../conductor/client/http/MetadataClient.java | 34 ++--- .../conductor/client/http/PayloadStorage.java | 9 +- .../conductor/client/http/TaskClient.java | 34 ++--- .../conductor/client/http/WorkflowClient.java | 34 ++--- .../client/http/EventClientSpec.groovy | 25 +++- .../client/http/MetadataClientSpec.groovy | 12 +- .../client/http/TaskClientSpec.groovy | 18 +-- .../client/http/WorkflowClientSpec.groovy | 18 +-- dependencies.gradle | 8 +- java-sdk/build.gradle | 5 +- .../workflow/executor/WorkflowExecutor.java | 15 +- test-harness/build.gradle | 2 +- 16 files changed, 177 insertions(+), 281 deletions(-) diff --git a/client/build.gradle b/client/build.gradle index 2ffd092ed..03ce9ca78 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -19,8 +19,8 @@ dependencies { compileOnly 'org.jetbrains:annotations:23.0.0' implementation project(':conductor-common') - implementation "com.sun.jersey:jersey-client:${revJersey}" - implementation "javax.ws.rs:javax.ws.rs-api:${revJAXRS}" + implementation "org.glassfish.jersey.core:jersey-client:${revJersey}" + implementation "jakarta.ws.rs:jakarta.ws.rs-api:${revJAXRS}" implementation "org.glassfish.jersey.core:jersey-common:${revJerseyCommon}" implementation "com.netflix.spectator:spectator-api:${revSpectator}" @@ -29,7 +29,7 @@ dependencies { } implementation "com.amazonaws:aws-java-sdk-core:${revAwsSdk}" - implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider" + implementation "com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" implementation "org.apache.commons:commons-lang3" diff --git a/client/src/main/java/com/netflix/conductor/client/http/ClientBase.java b/client/src/main/java/com/netflix/conductor/client/http/ClientBase.java index 5326abe4d..42d4d7858 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/ClientBase.java +++ b/client/src/main/java/com/netflix/conductor/client/http/ClientBase.java @@ -20,8 +20,6 @@ import java.util.Map; import java.util.function.Function; -import javax.ws.rs.core.UriBuilder; - import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; @@ -31,7 +29,6 @@ import com.netflix.conductor.client.config.DefaultConductorClientConfiguration; import com.netflix.conductor.client.exception.ConductorClientException; import com.netflix.conductor.common.config.ObjectMapperProvider; -import com.netflix.conductor.common.model.BulkResponse; import com.netflix.conductor.common.run.ExternalStorageLocation; import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.common.validation.ErrorResponse; @@ -39,11 +36,12 @@ import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource.Builder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; +import lombok.Getter; /** Abstract client for the REST server */ public abstract class ClientBase { @@ -86,35 +84,40 @@ protected void delete(String url, Object... uriVariables) { protected void deleteWithUriVariables( Object[] queryParams, String url, Object... uriVariables) { - delete(queryParams, url, uriVariables, null); - } - - protected BulkResponse deleteWithRequestBody(Object[] queryParams, String url, Object body) { - return delete(queryParams, url, null, body); + delete(queryParams, url, uriVariables); } - private BulkResponse delete( - Object[] queryParams, String url, Object[] uriVariables, Object body) { + private void delete(Object[] queryParams, String url, Object[] uriVariables) { URI uri = null; - BulkResponse response = null; try { uri = getURIBuilder(root + url, queryParams).build(uriVariables); - response = requestHandler.delete(uri, body); + Response response = requestHandler.delete(uri); + if (response.getStatus() >= 300) { + throw new UniformInterfaceException(response); + } } catch (UniformInterfaceException e) { handleUniformInterfaceException(e, uri); } catch (RuntimeException e) { handleRuntimeException(e, uri); } - return response; } protected void put(String url, Object[] queryParams, Object request, Object... uriVariables) { URI uri = null; try { uri = getURIBuilder(root + url, queryParams).build(uriVariables); - requestHandler.getWebResourceBuilder(uri, request).put(); + Entity entity; + if (request != null) { + entity = Entity.json(request); + } else { + entity = Entity.text(""); + } + Response response = requestHandler.getWebResourceBuilder(uri).put(entity); + if (response.getStatus() >= 300) { + throw new UniformInterfaceException(response); + } } catch (RuntimeException e) { - handleException(uri, e); + handleException(e, uri); } } @@ -139,7 +142,7 @@ protected T postForEntity( request, queryParams, responseType, - builder -> builder.post(responseType), + builder -> builder.post(Entity.json(request), responseType), uriVariables); } @@ -154,7 +157,7 @@ protected T postForEntity( request, queryParams, responseType, - builder -> builder.post(responseType), + builder -> builder.post(Entity.json(request), responseType), uriVariables); } @@ -163,14 +166,17 @@ private T postForEntity( Object request, Object[] queryParams, Object responseType, - Function postWithEntity, + Function postWithEntity, Object... uriVariables) { URI uri = null; try { uri = getURIBuilder(root + url, queryParams).build(uriVariables); - Builder webResourceBuilder = requestHandler.getWebResourceBuilder(uri, request); + Invocation.Builder webResourceBuilder = requestHandler.getWebResourceBuilder(uri); if (responseType == null) { - webResourceBuilder.post(); + Response response = webResourceBuilder.post(Entity.json(request)); + if (response.getStatus() >= 300) { + throw new UniformInterfaceException(response); + } return null; } return postWithEntity.apply(webResourceBuilder); @@ -185,29 +191,29 @@ private T postForEntity( protected T getForEntity( String url, Object[] queryParams, Class responseType, Object... uriVariables) { return getForEntity( - url, queryParams, response -> response.getEntity(responseType), uriVariables); + url, queryParams, response -> response.readEntity(responseType), uriVariables); } protected T getForEntity( String url, Object[] queryParams, GenericType responseType, Object... uriVariables) { return getForEntity( - url, queryParams, response -> response.getEntity(responseType), uriVariables); + url, queryParams, response -> response.readEntity(responseType), uriVariables); } private T getForEntity( String url, Object[] queryParams, - Function entityProvider, + Function entityProvider, Object... uriVariables) { URI uri = null; - ClientResponse clientResponse; + Response response; try { uri = getURIBuilder(root + url, queryParams).build(uriVariables); - clientResponse = requestHandler.get(uri); - if (clientResponse.getStatus() < 300) { - return entityProvider.apply(clientResponse); + response = requestHandler.get(uri); + if (response.getStatus() < 300) { + return entityProvider.apply(response); } else { - throw new UniformInterfaceException(clientResponse); + throw new UniformInterfaceException(response); } } catch (UniformInterfaceException e) { handleUniformInterfaceException(e, uri); @@ -296,15 +302,6 @@ protected boolean isNewerJacksonVersion() { return version.getMajorVersion() == 2 && version.getMinorVersion() >= 12; } - private void handleClientHandlerException(ClientHandlerException exception, URI uri) { - String errorMessage = - String.format( - "Unable to invoke Conductor API with uri: %s, failure to process request or response", - uri); - LOGGER.error(errorMessage, exception); - throw new ConductorClientException(errorMessage, exception); - } - private void handleRuntimeException(RuntimeException exception, URI uri) { String errorMessage = String.format( @@ -315,73 +312,49 @@ private void handleRuntimeException(RuntimeException exception, URI uri) { } private void handleUniformInterfaceException(UniformInterfaceException exception, URI uri) { - ClientResponse clientResponse = exception.getResponse(); - if (clientResponse == null) { - throw new ConductorClientException( - String.format("Unable to invoke Conductor API with uri: %s", uri)); - } - try { - if (clientResponse.getStatus() < 300) { + Response response = exception.getResponse(); + try (response) { + if (response == null) { + throw new ConductorClientException( + String.format("Unable to invoke Conductor API with uri: %s", uri)); + } + if (response.getStatus() < 300) { return; } - String errorMessage = clientResponse.getEntity(String.class); + String errorMessage = response.readEntity(String.class); LOGGER.warn( "Unable to invoke Conductor API with uri: {}, unexpected response from server: statusCode={}, responseBody='{}'.", uri, - clientResponse.getStatus(), + response.getStatus(), errorMessage); ErrorResponse errorResponse; try { errorResponse = objectMapper.readValue(errorMessage, ErrorResponse.class); } catch (IOException e) { - throw new ConductorClientException(clientResponse.getStatus(), errorMessage); + throw new ConductorClientException(response.getStatus(), errorMessage); } - throw new ConductorClientException(clientResponse.getStatus(), errorResponse); + throw new ConductorClientException(response.getStatus(), errorResponse); } catch (ConductorClientException e) { throw e; - } catch (ClientHandlerException e) { - handleClientHandlerException(e, uri); } catch (RuntimeException e) { handleRuntimeException(e, uri); - } finally { - clientResponse.close(); } } - private void handleException(URI uri, RuntimeException e) { + private void handleException(RuntimeException e, URI uri) { if (e instanceof UniformInterfaceException) { handleUniformInterfaceException(((UniformInterfaceException) e), uri); - } else if (e instanceof ClientHandlerException) { - handleClientHandlerException((ClientHandlerException) e, uri); } else { handleRuntimeException(e, uri); } } - /** - * Converts ClientResponse object to string with detailed debug information including status - * code, media type, response headers, and response body if exists. - */ - private String clientResponseToString(ClientResponse response) { - if (response == null) { - return null; - } - StringBuilder builder = new StringBuilder(); - builder.append("[status: ").append(response.getStatus()); - builder.append(", media type: ").append(response.getType()); - if (response.getStatus() != 404) { - try { - String responseBody = response.getEntity(String.class); - if (responseBody != null) { - builder.append(", response body: ").append(responseBody); - } - } catch (RuntimeException ignore) { - // Ignore if there is no response body, or IO error - it may have already been read - // in certain scenario. - } + @Getter + static class UniformInterfaceException extends RuntimeException { + private final Response response; + + public UniformInterfaceException(Response response) { + this.response = response; } - builder.append(", response headers: ").append(response.getHeaders()); - builder.append("]"); - return builder.toString(); } } diff --git a/client/src/main/java/com/netflix/conductor/client/http/ClientRequestHandler.java b/client/src/main/java/com/netflix/conductor/client/http/ClientRequestHandler.java index 164cb579b..527059ea5 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/ClientRequestHandler.java +++ b/client/src/main/java/com/netflix/conductor/client/http/ClientRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Conductor Authors. + * Copyright 2024 Conductor Authors. *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -14,27 +14,25 @@ import java.net.URI; -import javax.ws.rs.core.MediaType; +import org.glassfish.jersey.client.ClientConfig; import com.netflix.conductor.common.config.ObjectMapperProvider; -import com.netflix.conductor.common.model.BulkResponse; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; public class ClientRequestHandler { private final Client client; - public ClientRequestHandler( - ClientConfig config, ClientHandler handler, ClientFilter... filters) { + public ClientRequestHandler(ClientConfig config, ClientRequestFilter... filters) { ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); // https://github.com/FasterXML/jackson-databind/issues/2683 @@ -43,40 +41,26 @@ public ClientRequestHandler( } JacksonJsonProvider provider = new JacksonJsonProvider(objectMapper); - config.getSingletons().add(provider); + config.register(provider); - if (handler == null) { - this.client = Client.create(config); - } else { - this.client = new Client(handler, config); - } + this.client = ClientBuilder.newClient(config); - for (ClientFilter filter : filters) { - this.client.addFilter(filter); + for (ClientRequestFilter filter : filters) { + this.client.register(filter); } } - public BulkResponse delete(URI uri, Object body) { - if (body != null) { - return client.resource(uri) - .type(MediaType.APPLICATION_JSON_TYPE) - .delete(BulkResponse.class, body); - } else { - client.resource(uri).delete(); - } - return null; + public Response delete(URI uri) { + return client.target(uri).request().delete(); } - public ClientResponse get(URI uri) { - return client.resource(uri) - .accept(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN) - .get(ClientResponse.class); + public Response get(URI uri) { + return client.target(uri).request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN).get(); } - public WebResource.Builder getWebResourceBuilder(URI URI, Object entity) { - return client.resource(URI) - .type(MediaType.APPLICATION_JSON) - .entity(entity) + public Invocation.Builder getWebResourceBuilder(URI uri) { + return client.target(uri) + .request(MediaType.APPLICATION_JSON) .accept(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON); } diff --git a/client/src/main/java/com/netflix/conductor/client/http/EventClient.java b/client/src/main/java/com/netflix/conductor/client/http/EventClient.java index 1782d0177..5cf964189 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/EventClient.java +++ b/client/src/main/java/com/netflix/conductor/client/http/EventClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Conductor Authors. + * Copyright 2024 Conductor Authors. *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,67 +15,50 @@ import java.util.List; import org.apache.commons.lang3.Validate; +import org.glassfish.jersey.client.ClientConfig; import com.netflix.conductor.client.config.ConductorClientConfiguration; import com.netflix.conductor.client.config.DefaultConductorClientConfiguration; import com.netflix.conductor.common.metadata.events.EventHandler; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.core.GenericType; // Client class for all Event Handler operations public class EventClient extends ClientBase { - private static final GenericType> eventHandlerList = - new GenericType>() {}; + private static final GenericType> eventHandlerList = new GenericType<>() {}; /** Creates a default metadata client */ public EventClient() { - this(new DefaultClientConfig(), new DefaultConductorClientConfiguration(), null); + this(new ClientConfig(), new DefaultConductorClientConfiguration()); } /** * @param clientConfig REST Client configuration */ public EventClient(ClientConfig clientConfig) { - this(clientConfig, new DefaultConductorClientConfiguration(), null); - } - - /** - * @param clientConfig REST Client configuration - * @param clientHandler Jersey client handler. Useful when plugging in various http client - * interaction modules (e.g. ribbon) - */ - public EventClient(ClientConfig clientConfig, ClientHandler clientHandler) { - this(clientConfig, new DefaultConductorClientConfiguration(), clientHandler); + this(clientConfig, new DefaultConductorClientConfiguration()); } /** * @param config config REST Client configuration - * @param handler handler Jersey client handler. Useful when plugging in various http client - * interaction modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ - public EventClient(ClientConfig config, ClientHandler handler, ClientFilter... filters) { - this(config, new DefaultConductorClientConfiguration(), handler, filters); + public EventClient(ClientConfig config, ClientRequestFilter... filters) { + this(config, new DefaultConductorClientConfiguration(), filters); } /** * @param config REST Client configuration * @param clientConfiguration Specific properties configured for the client, see {@link * ConductorClientConfiguration} - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ public EventClient( ClientConfig config, ConductorClientConfiguration clientConfiguration, - ClientHandler handler, - ClientFilter... filters) { - super(new ClientRequestHandler(config, handler, filters), clientConfiguration); + ClientRequestFilter... filters) { + super(new ClientRequestHandler(config, filters), clientConfiguration); } EventClient(ClientRequestHandler requestHandler) { diff --git a/client/src/main/java/com/netflix/conductor/client/http/MetadataClient.java b/client/src/main/java/com/netflix/conductor/client/http/MetadataClient.java index 2db8df237..c2ae5e1cc 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/MetadataClient.java +++ b/client/src/main/java/com/netflix/conductor/client/http/MetadataClient.java @@ -15,17 +15,15 @@ import java.util.List; import org.apache.commons.lang3.Validate; +import org.glassfish.jersey.client.ClientConfig; import com.netflix.conductor.client.config.ConductorClientConfiguration; import com.netflix.conductor.client.config.DefaultConductorClientConfiguration; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.core.GenericType; public class MetadataClient extends ClientBase { @@ -34,49 +32,35 @@ public class MetadataClient extends ClientBase { /** Creates a default metadata client */ public MetadataClient() { - this(new DefaultClientConfig(), new DefaultConductorClientConfiguration(), null); + this(new ClientConfig(), new DefaultConductorClientConfiguration()); } /** * @param clientConfig REST Client configuration */ public MetadataClient(ClientConfig clientConfig) { - this(clientConfig, new DefaultConductorClientConfiguration(), null); - } - - /** - * @param clientConfig REST Client configuration - * @param clientHandler Jersey client handler. Useful when plugging in various http client - * interaction modules (e.g. ribbon) - */ - public MetadataClient(ClientConfig clientConfig, ClientHandler clientHandler) { - this(clientConfig, new DefaultConductorClientConfiguration(), clientHandler); + this(clientConfig, new DefaultConductorClientConfiguration()); } /** * @param config config REST Client configuration - * @param handler handler Jersey client handler. Useful when plugging in various http client - * interaction modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ - public MetadataClient(ClientConfig config, ClientHandler handler, ClientFilter... filters) { - this(config, new DefaultConductorClientConfiguration(), handler, filters); + public MetadataClient(ClientConfig config, ClientRequestFilter... filters) { + this(config, new DefaultConductorClientConfiguration(), filters); } /** * @param config REST Client configuration * @param clientConfiguration Specific properties configured for the client, see {@link * ConductorClientConfiguration} - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ public MetadataClient( ClientConfig config, ConductorClientConfiguration clientConfiguration, - ClientHandler handler, - ClientFilter... filters) { - super(new ClientRequestHandler(config, handler, filters), clientConfiguration); + ClientRequestFilter... filters) { + super(new ClientRequestHandler(config, filters), clientConfiguration); } MetadataClient(ClientRequestHandler requestHandler) { diff --git a/client/src/main/java/com/netflix/conductor/client/http/PayloadStorage.java b/client/src/main/java/com/netflix/conductor/client/http/PayloadStorage.java index 668e50047..98f54cf0e 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/PayloadStorage.java +++ b/client/src/main/java/com/netflix/conductor/client/http/PayloadStorage.java @@ -15,13 +15,7 @@ import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; - -import javax.ws.rs.core.Response; +import java.net.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,6 +25,7 @@ import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.amazonaws.util.IOUtils; +import jakarta.ws.rs.core.Response; /** An implementation of {@link ExternalPayloadStorage} for storing large JSON payload data. */ class PayloadStorage implements ExternalPayloadStorage { diff --git a/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java b/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java index 35d48b2e3..7b4e120fb 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java +++ b/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java @@ -22,6 +22,7 @@ import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; +import org.glassfish.jersey.client.ClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,11 +39,8 @@ import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.core.GenericType; /** Client for conductor task management including polling for task, updating task status etc. */ public class TaskClient extends ClientBase { @@ -68,49 +66,35 @@ public class TaskClient extends ClientBase { /** Creates a default task client */ public TaskClient() { - this(new DefaultClientConfig(), new DefaultConductorClientConfiguration(), null); + this(new ClientConfig(), new DefaultConductorClientConfiguration()); } /** * @param config REST Client configuration */ public TaskClient(ClientConfig config) { - this(config, new DefaultConductorClientConfiguration(), null); + this(config, new DefaultConductorClientConfiguration()); } /** * @param config REST Client configuration - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) - */ - public TaskClient(ClientConfig config, ClientHandler handler) { - this(config, new DefaultConductorClientConfiguration(), handler); - } - - /** - * @param config REST Client configuration - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ - public TaskClient(ClientConfig config, ClientHandler handler, ClientFilter... filters) { - this(config, new DefaultConductorClientConfiguration(), handler, filters); + public TaskClient(ClientConfig config, ClientRequestFilter... filters) { + this(config, new DefaultConductorClientConfiguration(), filters); } /** * @param config REST Client configuration * @param clientConfiguration Specific properties configured for the client, see {@link * ConductorClientConfiguration} - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ public TaskClient( ClientConfig config, ConductorClientConfiguration clientConfiguration, - ClientHandler handler, - ClientFilter... filters) { - super(new ClientRequestHandler(config, handler, filters), clientConfiguration); + ClientRequestFilter... filters) { + super(new ClientRequestHandler(config, filters), clientConfiguration); } TaskClient(ClientRequestHandler requestHandler) { diff --git a/client/src/main/java/com/netflix/conductor/client/http/WorkflowClient.java b/client/src/main/java/com/netflix/conductor/client/http/WorkflowClient.java index 14deabff3..a16ae421f 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/WorkflowClient.java +++ b/client/src/main/java/com/netflix/conductor/client/http/WorkflowClient.java @@ -18,6 +18,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; +import org.glassfish.jersey.client.ClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,11 +35,8 @@ import com.netflix.conductor.common.run.WorkflowTestRequest; import com.netflix.conductor.common.utils.ExternalPayloadStorage; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.GenericType; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.core.GenericType; public class WorkflowClient extends ClientBase { @@ -52,49 +50,35 @@ public class WorkflowClient extends ClientBase { /** Creates a default workflow client */ public WorkflowClient() { - this(new DefaultClientConfig(), new DefaultConductorClientConfiguration(), null); + this(new ClientConfig(), new DefaultConductorClientConfiguration()); } /** * @param config REST Client configuration */ public WorkflowClient(ClientConfig config) { - this(config, new DefaultConductorClientConfiguration(), null); + this(config, new DefaultConductorClientConfiguration()); } /** * @param config REST Client configuration - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) - */ - public WorkflowClient(ClientConfig config, ClientHandler handler) { - this(config, new DefaultConductorClientConfiguration(), handler); - } - - /** - * @param config REST Client configuration - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ - public WorkflowClient(ClientConfig config, ClientHandler handler, ClientFilter... filters) { - this(config, new DefaultConductorClientConfiguration(), handler, filters); + public WorkflowClient(ClientConfig config, ClientRequestFilter... filters) { + this(config, new DefaultConductorClientConfiguration(), filters); } /** * @param config REST Client configuration * @param clientConfiguration Specific properties configured for the client, see {@link * ConductorClientConfiguration} - * @param handler Jersey client handler. Useful when plugging in various http client interaction - * modules (e.g. ribbon) * @param filters Chain of client side filters to be applied per request */ public WorkflowClient( ClientConfig config, ConductorClientConfiguration clientConfiguration, - ClientHandler handler, - ClientFilter... filters) { - super(new ClientRequestHandler(config, handler, filters), clientConfiguration); + ClientRequestFilter... filters) { + super(new ClientRequestHandler(config, filters), clientConfiguration); } WorkflowClient(ClientRequestHandler requestHandler) { diff --git a/client/src/test/groovy/com/netflix/conductor/client/http/EventClientSpec.groovy b/client/src/test/groovy/com/netflix/conductor/client/http/EventClientSpec.groovy index bb121c56d..ec1602736 100644 --- a/client/src/test/groovy/com/netflix/conductor/client/http/EventClientSpec.groovy +++ b/client/src/test/groovy/com/netflix/conductor/client/http/EventClientSpec.groovy @@ -14,8 +14,8 @@ package com.netflix.conductor.client.http import com.netflix.conductor.common.metadata.events.EventHandler -import com.sun.jersey.api.client.ClientResponse -import com.sun.jersey.api.client.WebResource +import jakarta.ws.rs.client.Invocation +import jakarta.ws.rs.core.Response import spock.lang.Subject import spock.lang.Unroll @@ -33,36 +33,47 @@ class EventClientSpec extends ClientSpecification { given: EventHandler handler = new EventHandler() URI uri = createURI("event") + Invocation.Builder builder = Mock(Invocation.Builder.class) + Response response = Mock(Response.class) + when: eventClient.registerEventHandler(handler) then: - 1 * requestHandler.getWebResourceBuilder(uri, handler) >> Mock(WebResource.Builder.class) + 1 * requestHandler.getWebResourceBuilder(uri) >> builder + 1 * builder.post(_) >> response + 1 * response.getStatus() >> 200 } def "update event handler"() { given: EventHandler handler = new EventHandler() URI uri = createURI("event") + Invocation.Builder builder = Mock(Invocation.Builder.class) + Response response = Mock(Response.class) when: eventClient.updateEventHandler(handler) then: - 1 * requestHandler.getWebResourceBuilder(uri, handler) >> Mock(WebResource.Builder.class) + 1 * requestHandler.getWebResourceBuilder(uri) >> builder + 1 * builder.put(_) >> response + 1 * response.getStatus() >> 200 } def "unregister event handler"() { given: String eventName = "test" URI uri = createURI("event/$eventName") + Response response = Mock(Response.class) when: eventClient.unregisterEventHandler(eventName) then: - 1 * requestHandler.delete(uri, null) + 1 * requestHandler.delete(uri) >> response + 1 * response.getStatus() >> 200 } @Unroll @@ -77,8 +88,8 @@ class EventClientSpec extends ClientSpecification { then: eventHandlers && eventHandlers.size() == 2 - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> handlers + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> handlers } where: diff --git a/client/src/test/groovy/com/netflix/conductor/client/http/MetadataClientSpec.groovy b/client/src/test/groovy/com/netflix/conductor/client/http/MetadataClientSpec.groovy index 13790d3fc..3e010fadd 100644 --- a/client/src/test/groovy/com/netflix/conductor/client/http/MetadataClientSpec.groovy +++ b/client/src/test/groovy/com/netflix/conductor/client/http/MetadataClientSpec.groovy @@ -15,7 +15,7 @@ package com.netflix.conductor.client.http import com.netflix.conductor.client.exception.ConductorClientException import com.netflix.conductor.common.metadata.workflow.WorkflowDef -import com.sun.jersey.api.client.ClientResponse +import jakarta.ws.rs.core.Response import spock.lang.Subject class MetadataClientSpec extends ClientSpecification { @@ -33,12 +33,14 @@ class MetadataClientSpec extends ClientSpecification { String workflowName = 'test' int version = 1 URI uri = createURI("metadata/workflow/$workflowName/$version") + Response response = Mock(Response.class) when: metadataClient.unregisterWorkflowDef(workflowName, version) then: - 1 * requestHandler.delete(uri, null) + 1 * requestHandler.delete(uri) >> response + 1 * response.getStatus() >> 200 } def "workflow delete throws exception"() { @@ -51,7 +53,7 @@ class MetadataClientSpec extends ClientSpecification { metadataClient.unregisterWorkflowDef(workflowName, version) then: - 1 * requestHandler.delete(uri, null) >> { throw new RuntimeException(clientResponse) } + 1 * requestHandler.delete(uri) >> { throw new RuntimeException() } def ex = thrown(ConductorClientException.class) ex.message == "Unable to invoke Conductor API with uri: $uri, runtime exception occurred" } @@ -87,8 +89,8 @@ class MetadataClientSpec extends ClientSpecification { metadataClient.getAllWorkflowsWithLatestVersions() then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + getEntity() >> result } } } diff --git a/client/src/test/groovy/com/netflix/conductor/client/http/TaskClientSpec.groovy b/client/src/test/groovy/com/netflix/conductor/client/http/TaskClientSpec.groovy index 2caba4490..2d924deeb 100644 --- a/client/src/test/groovy/com/netflix/conductor/client/http/TaskClientSpec.groovy +++ b/client/src/test/groovy/com/netflix/conductor/client/http/TaskClientSpec.groovy @@ -16,7 +16,7 @@ import com.netflix.conductor.common.metadata.tasks.Task import com.netflix.conductor.common.run.SearchResult import com.netflix.conductor.common.run.TaskSummary -import com.sun.jersey.api.client.ClientResponse +import jakarta.ws.rs.core.Response import spock.lang.Subject class TaskClientSpec extends ClientSpecification { @@ -42,8 +42,8 @@ class TaskClientSpec extends ClientSpecification { SearchResult searchResult = taskClient.search(query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -64,8 +64,8 @@ class TaskClientSpec extends ClientSpecification { SearchResult searchResult = taskClient.searchV2('my_complex_query') then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -90,8 +90,8 @@ class TaskClientSpec extends ClientSpecification { SearchResult searchResult = taskClient.search(start, size, sort, freeText, query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -116,8 +116,8 @@ class TaskClientSpec extends ClientSpecification { SearchResult searchResult = taskClient.searchV2(start, size, sort, freeText, query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits diff --git a/client/src/test/groovy/com/netflix/conductor/client/http/WorkflowClientSpec.groovy b/client/src/test/groovy/com/netflix/conductor/client/http/WorkflowClientSpec.groovy index b4f30aeb1..eea105b60 100644 --- a/client/src/test/groovy/com/netflix/conductor/client/http/WorkflowClientSpec.groovy +++ b/client/src/test/groovy/com/netflix/conductor/client/http/WorkflowClientSpec.groovy @@ -17,7 +17,7 @@ import com.netflix.conductor.common.run.SearchResult import com.netflix.conductor.common.run.Workflow import com.netflix.conductor.common.run.WorkflowSummary -import com.sun.jersey.api.client.ClientResponse +import jakarta.ws.rs.core.Response import spock.lang.Subject class WorkflowClientSpec extends ClientSpecification { @@ -43,8 +43,8 @@ class WorkflowClientSpec extends ClientSpecification { SearchResult searchResult = workflowClient.search(query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -65,8 +65,8 @@ class WorkflowClientSpec extends ClientSpecification { SearchResult searchResult = workflowClient.searchV2('my_complex_query') then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -91,8 +91,8 @@ class WorkflowClientSpec extends ClientSpecification { SearchResult searchResult = workflowClient.search(start, size, sort, freeText, query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits @@ -117,8 +117,8 @@ class WorkflowClientSpec extends ClientSpecification { SearchResult searchResult = workflowClient.searchV2(start, size, sort, freeText, query) then: - 1 * requestHandler.get(uri) >> Mock(ClientResponse.class) { - getEntity(_) >> result + 1 * requestHandler.get(uri) >> Mock(Response.class) { + readEntity(_) >> result } searchResult.totalHits == result.totalHits diff --git a/dependencies.gradle b/dependencies.gradle index 9c6343a77..e4033cba5 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -26,7 +26,7 @@ ext { revDynoQueues = '2.0.20' revElasticSearch6 = '6.8.23' revEmbeddedRedis = '0.6' - revEurekaClient = '1.10.10' + revEurekaClient = '2.0.2' revGroovy = '4.0.9' revGrpc = '1.57.2' revGuava = '33.2.1-jre' @@ -36,10 +36,10 @@ ext { revProtoBuf = '3.21.12' revJakartaAnnotation = '2.1.1' revJAXB = '4.0.1' - revJAXRS = '2.1.1' + revJAXRS = '4.0.0' revJedis = '3.3.0' - revJersey = '1.19.4' - revJerseyCommon = '2.22.2' + revJersey = '3.1.7' + revJerseyCommon = '3.1.7' revJsonPath = '2.4.0' revJq = '0.0.13' revJsr311Api = '1.1.1' diff --git a/java-sdk/build.gradle b/java-sdk/build.gradle index 91ce0f4cb..9c16f6da7 100644 --- a/java-sdk/build.gradle +++ b/java-sdk/build.gradle @@ -8,8 +8,8 @@ dependencies { implementation "com.fasterxml.jackson.core:jackson-databind:${revFasterXml}" implementation "com.google.guava:guava:${revGuava}" implementation "cglib:cglib:3.3.0" - implementation "com.sun.jersey:jersey-client:${revJersey}" - implementation "javax.ws.rs:javax.ws.rs-api:${revJAXRS}" + implementation "org.glassfish.jersey.core:jersey-client:${revJersey}" + implementation "jakarta.ws.rs:jakarta.ws.rs-api:${revJAXRS}" implementation "org.glassfish.jersey.core:jersey-common:${revJerseyCommon}" implementation "org.openjdk.nashorn:nashorn-core:15.4" @@ -30,4 +30,3 @@ test { } } sourceSets.main.java.srcDirs += ['example/java', 'example/resources'] - diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java index d80d55928..f71073a3a 100644 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java +++ b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.concurrent.*; +import org.glassfish.jersey.client.ClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,9 +39,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; +import jakarta.ws.rs.client.ClientRequestFilter; public class WorkflowExecutor { @@ -91,17 +90,15 @@ public WorkflowExecutor(String apiServerURL) { } public WorkflowExecutor( - String apiServerURL, int pollingInterval, ClientFilter... clientFilter) { + String apiServerURL, int pollingInterval, ClientRequestFilter... clientFilter) { - taskClient = new TaskClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); + taskClient = new TaskClient(new ClientConfig(), clientFilter); taskClient.setRootURI(apiServerURL); - workflowClient = - new WorkflowClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); + workflowClient = new WorkflowClient(new ClientConfig(), clientFilter); workflowClient.setRootURI(apiServerURL); - metadataClient = - new MetadataClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); + metadataClient = new MetadataClient(new ClientConfig(), clientFilter); metadataClient.setRootURI(apiServerURL); annotatedWorkerExecutor = new AnnotatedWorkerExecutor(taskClient, pollingInterval); diff --git a/test-harness/build.gradle b/test-harness/build.gradle index c250eddf6..db73b2706 100644 --- a/test-harness/build.gradle +++ b/test-harness/build.gradle @@ -38,6 +38,6 @@ dependencies { testImplementation "org.testcontainers:elasticsearch:${revTestContainer}" testImplementation('junit:junit:4.13.2') testImplementation "org.junit.vintage:junit-vintage-engine" - testImplementation "javax.ws.rs:javax.ws.rs-api:${revJAXRS}" + testImplementation "jakarta.ws.rs:jakarta.ws.rs-api:${revJAXRS}" testImplementation "org.glassfish.jersey.core:jersey-common:${revJerseyCommon}" }