Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update javax dependencies in the client to jakarta #235

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'

gr4cza marked this conversation as resolved.
Show resolved Hide resolved
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
Loading