Skip to content

Commit

Permalink
Merge pull request #235 from gr4cza/feat/update_to_jakarta_in_client
Browse files Browse the repository at this point in the history
Update javax dependencies in the client to jakarta
  • Loading branch information
v1r3n authored Sep 4, 2024
2 parents 9fef8fd + 1815e13 commit 6f988f1
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 281 deletions.
6 changes: 3 additions & 3 deletions client/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -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"
Expand Down
141 changes: 57 additions & 84 deletions client/src/main/java/com/netflix/conductor/client/http/ClientBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,19 +29,19 @@
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;

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 {
Expand Down Expand Up @@ -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<Object> 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);
}
}

Expand All @@ -139,7 +142,7 @@ protected <T> T postForEntity(
request,
queryParams,
responseType,
builder -> builder.post(responseType),
builder -> builder.post(Entity.json(request), responseType),
uriVariables);
}

Expand All @@ -154,7 +157,7 @@ protected <T> T postForEntity(
request,
queryParams,
responseType,
builder -> builder.post(responseType),
builder -> builder.post(Entity.json(request), responseType),
uriVariables);
}

Expand All @@ -163,14 +166,17 @@ private <T> T postForEntity(
Object request,
Object[] queryParams,
Object responseType,
Function<Builder, T> postWithEntity,
Function<Invocation.Builder, T> 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);
Expand All @@ -185,29 +191,29 @@ private <T> T postForEntity(
protected <T> T getForEntity(
String url, Object[] queryParams, Class<T> responseType, Object... uriVariables) {
return getForEntity(
url, queryParams, response -> response.getEntity(responseType), uriVariables);
url, queryParams, response -> response.readEntity(responseType), uriVariables);
}

protected <T> T getForEntity(
String url, Object[] queryParams, GenericType<T> responseType, Object... uriVariables) {
return getForEntity(
url, queryParams, response -> response.getEntity(responseType), uriVariables);
url, queryParams, response -> response.readEntity(responseType), uriVariables);
}

private <T> T getForEntity(
String url,
Object[] queryParams,
Function<ClientResponse, T> entityProvider,
Function<Response, T> 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);
Expand Down Expand Up @@ -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(
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Conductor Authors.
* Copyright 2024 Conductor Authors.
* <p>
* 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
Expand All @@ -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
Expand All @@ -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);
}

Expand Down
Loading

0 comments on commit 6f988f1

Please sign in to comment.