diff --git a/connectors/http-connector/pom.xml b/connectors/http-connector/pom.xml index 7c960e717..7dc2af2d4 100644 --- a/connectors/http-connector/pom.xml +++ b/connectors/http-connector/pom.xml @@ -4,7 +4,7 @@ com.github.openstack4j.core.connectors openstack4j-connectors - 3.12 + co-3.12.4 OpenStack4j HttpURL Connector openstack4j-http-connector diff --git a/connectors/httpclient/pom.xml b/connectors/httpclient/pom.xml index 852a70f0f..c620d898d 100644 --- a/connectors/httpclient/pom.xml +++ b/connectors/httpclient/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core.connectors openstack4j-connectors - 3.12 + co-3.12.4 4.0.0 openstack4j-httpclient diff --git a/connectors/jersey2-jakarta/pom.xml b/connectors/jersey2-jakarta/pom.xml new file mode 100644 index 000000000..19450cf63 --- /dev/null +++ b/connectors/jersey2-jakarta/pom.xml @@ -0,0 +1,74 @@ + + + com.github.openstack4j.core.connectors + openstack4j-connectors + co-3.12.4 + + 4.0.0 + openstack4j-jersey2-jakarta + OpenStack4j Jersey2 Jakarta Connector + https://github.com/openstack4j/openstack4j/ + jar + + + 3.1.10 + + + + + org.glassfish.jersey.core + jersey-client + ${jersey-version} + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + jakarta.ws.rs + jakarta.ws.rs-api + 4.0.0 + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.name} + + org.openstack4j.connectors.jersey2 + + + !org.openstack4j.connectors.jersey2, + * + + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + + + osgi.serviceloader; osgi.serviceloader=org.openstack4j.core.transport.HttpExecutorService + + + + + + + diff --git a/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/ClientFactory.java b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/ClientFactory.java new file mode 100644 index 000000000..e3e1cf9f1 --- /dev/null +++ b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/ClientFactory.java @@ -0,0 +1,140 @@ +package org.openstack4j.connectors.jersey2; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.Proxy.Type; +import java.net.URL; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientRequestFilter; +import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.HttpUrlConnectorProvider; +import org.glassfish.jersey.client.HttpUrlConnectorProvider.ConnectionFactory; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.openstack4j.api.exceptions.ConnectionException; +import org.openstack4j.core.transport.ClientConstants; +import org.openstack4j.core.transport.Config; +import org.openstack4j.core.transport.ObjectMapperSingleton; +import org.openstack4j.core.transport.UntrustedSSL; + +/** + * A factory for creating a rest Client which is mapped to Jackson for JSON processing. + * + * @author Jeremy Unruh + */ +class ClientFactory { + + private static final CustomContextResolver RESOLVER = new CustomContextResolver(); + private static LoadingCache CACHE = CacheBuilder.newBuilder() + .expireAfterAccess(20, TimeUnit.MINUTES) + .build(new CacheLoader() { + @Override + public Client load(Config config) throws Exception { + return buildClientFromConfig(config); + } + }); + + /** + * Creates or Returns a Client + * + * @param config the configuration to use for the given client + * @return the client + */ + static Client create(Config config) { + try { + return CACHE.get(config); + } catch (ExecutionException e) { + throw new ConnectionException("Issue creating Jersey 2 Client: " + e.getMessage(), 0, e); + } + } + + private static Client buildClientFromConfig(Config config) { + ClientConfig clientConfig = new ClientConfig(); + + if (config.getProxy() != null) { + addProxy(clientConfig, config); + } + + ClientBuilder cb = ClientBuilder.newBuilder() + .withConfig(clientConfig) + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, "true") + .register(JacksonFeature.class) + .register(RESOLVER) + .register(new RequestFilter()); + + if (config.getSslContext() != null) { + cb.sslContext(config.getSslContext()); + } else if (config.isIgnoreSSLVerification()) { + cb.sslContext(UntrustedSSL.getSSLContext()); + } + + if (config.getHostNameVerifier() != null) { + cb.hostnameVerifier(config.getHostNameVerifier()); + } else if (config.isIgnoreSSLVerification()) { + cb.hostnameVerifier(UntrustedSSL.getHostnameVerifier()); + } + + if (config.getReadTimeout() > 0) { + cb.property(ClientProperties.READ_TIMEOUT, config.getReadTimeout()); + } + + if (config.getConnectTimeout() > 0) { + cb.property(ClientProperties.CONNECT_TIMEOUT, config.getConnectTimeout()); + } + + return cb.build(); + } + + private static void addProxy(ClientConfig cc, Config config) { + if (config.getProxy() != null) { + HttpUrlConnectorProvider cp = new HttpUrlConnectorProvider(); + cc.connectorProvider(cp); + final Proxy proxy = new Proxy(Type.HTTP, + new InetSocketAddress(config.getProxy().getRawHost(), config.getProxy().getPort())); + + cp.connectionFactory(new ConnectionFactory() { + + @Override + public HttpURLConnection getConnection(URL url) throws IOException { + return (HttpURLConnection) url.openConnection(proxy); + } + }); + } + } + + private static final class RequestFilter implements ClientRequestFilter { + + /** + * {@inheritDoc} + */ + @Override + public void filter(ClientRequestContext requestContext) throws IOException { + requestContext.getHeaders().remove(ClientConstants.HEADER_CONTENT_LANGUAGE); + requestContext.getHeaders().remove(ClientConstants.HEADER_CONTENT_ENCODING); + } + } + + private static final class CustomContextResolver implements ContextResolver { + + /** + * {@inheritDoc} + */ + @Override + public ObjectMapper getContext(Class type) { + return ObjectMapperSingleton.getContext(type); + } + + } +} diff --git a/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpCommand.java b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpCommand.java new file mode 100644 index 000000000..51e5b4d7e --- /dev/null +++ b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpCommand.java @@ -0,0 +1,156 @@ +package org.openstack4j.connectors.jersey2; + +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.HttpUrlConnectorProvider; +import org.glassfish.jersey.client.RequestEntityProcessing; +import org.glassfish.jersey.logging.LoggingFeature; +import org.openstack4j.core.transport.ClientConstants; +import org.openstack4j.core.transport.HttpRequest; +import org.openstack4j.core.transport.internal.HttpLoggingFilter; + +/** + * HttpCommand is responsible for executing the actual request driven by the HttpExecutor. + */ +public final class HttpCommand { + + private HttpRequest request; + private Entity entity; + private Invocation.Builder invocation; + private int retries; + + private HttpCommand(HttpRequest request) { + this.request = request; + } + + /** + * Creates a new HttpCommand from the given request + * + * @param request the request + * @return the command + */ + public static HttpCommand create(HttpRequest request) { + HttpCommand command = new HttpCommand(request); + command.initialize(); + return command; + } + + private void initialize() { + Client client = ClientFactory.create(request.getConfig()); + //try to set unsupported HTTP method. In our case used for PATCH. + if ("PATCH".equals(request.getMethod().name())) { + client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); + } + + WebTarget target = client.target(request.getEndpoint()).path(request.getPath()); + + if (HttpLoggingFilter.isLoggingEnabled()) { + target.register(new LoggingFeature(Logger.getLogger("os"), 10000)); + } + + target = populateQueryParams(target, request); + invocation = target.request(MediaType.APPLICATION_JSON); + + populateHeaders(invocation, request); + + entity = (request.getEntity() == null) ? null: Entity.entity(request.getEntity(), request.getContentType()); + } + + /** + * Executes the command and returns the Response + * + * @return the response + */ + public Response execute() { + Response response = null; + + if (hasEntity()) { + if (isInputStreamEntity()) { + // Issue #20 - Out of Memory in Jersey for large streams + invocation.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024); + invocation.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED); + } + response = invocation.method(request.getMethod().name(), getEntity()); + } else if (request.hasJson()) { + response = invocation.method(request.getMethod().name(), Entity.entity(request.getJson(), ClientConstants.CONTENT_TYPE_JSON)); + } else { + response = invocation.method(request.getMethod().name()); + } + + return response; + } + + private boolean isInputStreamEntity() { + return (hasEntity() && InputStream.class.isAssignableFrom(entity.getEntity().getClass())); + } + + /** + * @return the request entity or null + */ + public Entity getEntity() { + return entity; + } + + /** + * @return true if a request entity has been set + */ + public boolean hasEntity() { + return entity != null; + } + + /** + * @return current retry execution count for this command + */ + public int getRetries() { + return retries; + } + + /** + * @return incremement's the retry count and returns self + */ + public HttpCommand incrementRetriesAndReturn() { + initialize(); + retries++; + return this; + } + + public HttpRequest getRequest() { + return request; + } + + private WebTarget populateQueryParams(WebTarget target, HttpRequest request) { + + if (!request.hasQueryParams()) { + return target; + } + + for (Map.Entry> entry : request.getQueryParams().entrySet()) { + for (Object o : entry.getValue()) { + target = target.queryParam(entry.getKey(), o); + } + } + return target; + } + + private void populateHeaders(Invocation.Builder invocation, HttpRequest request) { + + if (!request.hasHeaders()) { + return; + } + + for (Map.Entry h : request.getHeaders().entrySet()) { + invocation.header(h.getKey(), h.getValue()); + } + } +} diff --git a/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpExecutorServiceImpl.java b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpExecutorServiceImpl.java new file mode 100644 index 000000000..328a97eaf --- /dev/null +++ b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpExecutorServiceImpl.java @@ -0,0 +1,77 @@ +package org.openstack4j.connectors.jersey2; + +import jakarta.ws.rs.ClientErrorException; +import jakarta.ws.rs.ProcessingException; +import jakarta.ws.rs.core.Response; + +import org.openstack4j.api.exceptions.ConnectionException; +import org.openstack4j.api.exceptions.ResponseException; +import org.openstack4j.core.transport.ClientConstants; +import org.openstack4j.core.transport.HttpExecutorService; +import org.openstack4j.core.transport.HttpRequest; +import org.openstack4j.core.transport.HttpResponse; +import org.openstack4j.openstack.internal.OSAuthenticator; +import org.openstack4j.openstack.internal.OSClientSession; + +/** + * HttpExecutor is the default implementation for HttpExecutorService which is responsible for interfacing with Jersey and mapping common status codes, requests and responses + * back to the common API + * + * @author Jeremy Unruh + */ +public class HttpExecutorServiceImpl implements HttpExecutorService { + + private static final String NAME = "Jersey 2 Connector"; + + + /** + * {@inheritDoc} + */ + @Override + public HttpResponse execute(HttpRequest request) { + try { + return invoke(request); + } catch (ResponseException re) { + throw re; + } catch (Exception e) { + throw new ConnectionException("Error during execution: " + e, 0, e); + } + } + + /** + * Invokes the given request + * + * @param the return type + * @param request the request to invoke + * @return the response + * @throws Exception the exception + */ + private HttpResponse invoke(HttpRequest request) throws Exception { + + HttpCommand command = HttpCommand.create(request); + + try { + return invokeRequest(command); + } catch (ProcessingException pe) { + throw new ConnectionException(pe.getMessage(), 0, pe); + } catch (ClientErrorException e) { + throw ResponseException.mapException(e.getResponse().getStatusInfo().toString(), e.getResponse().getStatus(), e); + } + } + + private HttpResponse invokeRequest(HttpCommand command) throws Exception { + Response response = command.execute(); + if (command.getRetries() == 0 && response.getStatus() == 401 && !command.getRequest().getHeaders().containsKey(ClientConstants.HEADER_OS4J_AUTH)) { + OSAuthenticator.reAuthenticate(); + command.getRequest().getHeaders().put(ClientConstants.HEADER_X_AUTH_TOKEN, OSClientSession.getCurrent().getTokenId()); + return invokeRequest(command.incrementRetriesAndReturn()); + } + return HttpResponseImpl.wrap(response); + } + + @Override + public String getExecutorDisplayName() { + return NAME; + } + +} diff --git a/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpResponseImpl.java b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpResponseImpl.java new file mode 100644 index 000000000..1854437af --- /dev/null +++ b/connectors/jersey2-jakarta/src/main/java/org/openstack4j/connectors/jersey2/HttpResponseImpl.java @@ -0,0 +1,125 @@ +package org.openstack4j.connectors.jersey2; + +import jakarta.ws.rs.core.Response; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.openstack4j.core.transport.ClientConstants; +import org.openstack4j.core.transport.ExecutionOptions; +import org.openstack4j.core.transport.HttpEntityHandler; +import org.openstack4j.core.transport.HttpResponse; + +public class HttpResponseImpl implements HttpResponse { + + private final Response response; + + private HttpResponseImpl(Response response) { + this.response = response; + } + + /** + * Wrap the given REsponse + * + * @param response the response + * @return the HttpResponse + */ + public static HttpResponseImpl wrap(Response response) { + return new HttpResponseImpl(response); + } + + /** + * Unwrap and return the original Response + * + * @return the response + */ + public Response unwrap() { + return response; + } + + /** + * Gets the entity and Maps any errors which will result in a ResponseException + * + * @param the generic type + * @param returnType the return type + * @return the entity + */ + public T getEntity(Class returnType) { + return getEntity(returnType, null); + } + + /** + * Gets the entity and Maps any errors which will result in a ResponseException + * + * @param the generic type + * @param returnType the return type + * @param options the execution options + * @return the entity + */ + @Override + public T getEntity(Class returnType, ExecutionOptions options) { + return HttpEntityHandler.handle(this, returnType, options); + } + + /** + * Gets the status from the previous Request + * + * @return the status code + */ + public int getStatus() { + return response.getStatus(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getStatusMessage() { + return response.getStatusInfo().getReasonPhrase(); + } + + /** + * @return the input stream + */ + public InputStream getInputStream() { + return (InputStream) response.getEntity(); + } + + /** + * Returns a Header value from the specified name key + * + * @param name the name of the header to query for + * @return the header as a String or null if not found + */ + public String header(String name) { + return response.getHeaderString(name); + } + + /** + * @return the a Map of Header Name to Header Value + */ + public Map headers() { + Map headers = new HashMap(); + for (String k : response.getHeaders().keySet()) { + headers.put(k, response.getHeaderString(k)); + } + return headers; + } + + @Override + public T readEntity(Class typeToReadAs) { + return response.readEntity(typeToReadAs); + } + + @Override + public void close() throws IOException { + // Jersey handles this automatically in all cases - no-op + } + + @Override + public String getContentType() { + return header(ClientConstants.HEADER_CONTENT_TYPE); + } +} diff --git a/connectors/jersey2-jakarta/src/main/resources/META-INF/services/org.openstack4j.core.transport.HttpExecutorService b/connectors/jersey2-jakarta/src/main/resources/META-INF/services/org.openstack4j.core.transport.HttpExecutorService new file mode 100644 index 000000000..3a8606e14 --- /dev/null +++ b/connectors/jersey2-jakarta/src/main/resources/META-INF/services/org.openstack4j.core.transport.HttpExecutorService @@ -0,0 +1 @@ +org.openstack4j.connectors.jersey2.HttpExecutorServiceImpl diff --git a/connectors/jersey2/pom.xml b/connectors/jersey2/pom.xml index 87fcc6ffd..24948140a 100644 --- a/connectors/jersey2/pom.xml +++ b/connectors/jersey2/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core.connectors openstack4j-connectors - 3.12 + co-3.12.4 4.0.0 openstack4j-jersey2 diff --git a/connectors/okhttp/pom.xml b/connectors/okhttp/pom.xml index 07f4daba6..fc3c11c24 100644 --- a/connectors/okhttp/pom.xml +++ b/connectors/okhttp/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core.connectors openstack4j-connectors - 3.12 + co-3.12.4 4.0.0 openstack4j-okhttp diff --git a/connectors/okhttp/src/main/java/org/openstack4j/connectors/okhttp/HttpCommand.java b/connectors/okhttp/src/main/java/org/openstack4j/connectors/okhttp/HttpCommand.java index b18a5cdf0..dd0907bf7 100644 --- a/connectors/okhttp/src/main/java/org/openstack4j/connectors/okhttp/HttpCommand.java +++ b/connectors/okhttp/src/main/java/org/openstack4j/connectors/okhttp/HttpCommand.java @@ -49,22 +49,26 @@ private void initialize() { new InetSocketAddress(config.getProxy().getRawHost(), config.getProxy().getPort()))); } - if (config.getConnectTimeout() > 0) - okHttpClientBuilder.connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS); + if (config.getConnectTimeout() > 0) { + okHttpClientBuilder.connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS); + } - if (config.getReadTimeout() > 0) - okHttpClientBuilder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS); + if (config.getReadTimeout() > 0) { + okHttpClientBuilder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS); + } if (config.isIgnoreSSLVerification()) { okHttpClientBuilder.hostnameVerifier(UntrustedSSL.getHostnameVerifier()); okHttpClientBuilder.sslSocketFactory(UntrustedSSL.getSSLContext().getSocketFactory(), UntrustedSSL.getTrustManager()); } - if (config.getSslContext() != null) - okHttpClientBuilder.sslSocketFactory(config.getSslContext().getSocketFactory()); + if (config.getSslContext() != null) { + okHttpClientBuilder.sslSocketFactory(config.getSslContext().getSocketFactory()); + } - if (config.getHostNameVerifier() != null) - okHttpClientBuilder.hostnameVerifier(config.getHostNameVerifier()); + if (config.getHostNameVerifier() != null) { + okHttpClientBuilder.hostnameVerifier(config.getHostNameVerifier()); + } if (HttpLoggingFilter.isLoggingEnabled()) { okHttpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)); } @@ -148,7 +152,9 @@ private void populateQueryParams(HttpRequest request) { private void populateHeaders(HttpRequest request) { - if (!request.hasHeaders()) return; + if (!request.hasHeaders()) { + return; + } for (Map.Entry h : request.getHeaders().entrySet()) { clientReq.addHeader(h.getKey(), String.valueOf(h.getValue())); diff --git a/connectors/pom.xml b/connectors/pom.xml index 855df53b9..a2f2a573c 100644 --- a/connectors/pom.xml +++ b/connectors/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 4.0.0 com.github.openstack4j.core.connectors @@ -48,6 +48,7 @@ httpclient + jersey2-jakarta okhttp resteasy @@ -91,6 +92,7 @@ maven-surefire-plugin 2.18.1 + --add-opens java.base/java.net=ALL-UNNAMED ../../core-test/src/main/resources/all.xml diff --git a/connectors/resteasy/pom.xml b/connectors/resteasy/pom.xml index 0cb34b6d2..8ccb92439 100644 --- a/connectors/resteasy/pom.xml +++ b/connectors/resteasy/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core.connectors openstack4j-connectors - 3.12 + co-3.12.4 4.0.0 openstack4j-resteasy diff --git a/core-integration-test/it-httpclient/pom.xml b/core-integration-test/it-httpclient/pom.xml index a347af915..389428b92 100644 --- a/core-integration-test/it-httpclient/pom.xml +++ b/core-integration-test/it-httpclient/pom.xml @@ -3,7 +3,7 @@ com.github.openstack4j.core openstack4j-core-integration-test - 3.12 + co-3.12.4 it-httpclient OpenStack4j IntegrationTest Apache HttpClient diff --git a/core-integration-test/it-jersey2-jakarta/pom.xml b/core-integration-test/it-jersey2-jakarta/pom.xml new file mode 100644 index 000000000..0a500bf16 --- /dev/null +++ b/core-integration-test/it-jersey2-jakarta/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + com.github.openstack4j.core + openstack4j-core-integration-test + co-3.12.4 + + it-jersey2-jakarta + OpenStack4j IntegrationTest Jersey2 Jakarta Connector + + false + + + + + com.github.openstack4j.core.connectors + openstack4j-jersey2-jakarta + ${project.version} + test + + + com.github.openstack4j.core + openstack4j-core-integration-test + ${project.version} + test-jar + test + + + + + + + maven-surefire-plugin + 2.19 + + + integrationtest + integration-test + + test + + false + + + com.github.openstack4j.core:openstack4j-core-integration-test + + + + + + + + diff --git a/core-integration-test/it-jersey2/pom.xml b/core-integration-test/it-jersey2/pom.xml index e5bc5a1b3..730e57f53 100644 --- a/core-integration-test/it-jersey2/pom.xml +++ b/core-integration-test/it-jersey2/pom.xml @@ -3,7 +3,7 @@ com.github.openstack4j.core openstack4j-core-integration-test - 3.12 + co-3.12.4 it-jersey2 OpenStack4j IntegrationTest Jersey2 Connector diff --git a/core-integration-test/it-okhttp/pom.xml b/core-integration-test/it-okhttp/pom.xml index 9d4852be8..ae6f65204 100644 --- a/core-integration-test/it-okhttp/pom.xml +++ b/core-integration-test/it-okhttp/pom.xml @@ -3,7 +3,7 @@ com.github.openstack4j.core openstack4j-core-integration-test - 3.12 + co-3.12.4 it-okhttp OpenStack4j IntegrationTest OKHttp Connector diff --git a/core-integration-test/it-resteasy/pom.xml b/core-integration-test/it-resteasy/pom.xml index 91c5eb956..c4f072956 100644 --- a/core-integration-test/it-resteasy/pom.xml +++ b/core-integration-test/it-resteasy/pom.xml @@ -3,7 +3,7 @@ com.github.openstack4j.core openstack4j-core-integration-test - 3.12 + co-3.12.4 it-resteasy OpenStack4j IntegrationTest RestEasy Connector diff --git a/core-integration-test/pom.xml b/core-integration-test/pom.xml index 4e4272adf..d709f6f42 100644 --- a/core-integration-test/pom.xml +++ b/core-integration-test/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 4.0.0 openstack4j-core-integration-test @@ -17,12 +17,46 @@ - - it-jersey2 - it-resteasy - it-okhttp - it-httpclient - + + + java-11 + + 11 + + + it-httpclient + it-jersey2 + it-okhttp + it-resteasy + + + + java-17 + + 17 + + + it-httpclient + + it-okhttp + it-resteasy + + + + java-21 + + 21 + + + + it-httpclient + + it-jersey2-jakarta + it-okhttp + it-resteasy + + + diff --git a/core-test/pom.xml b/core-test/pom.xml index 6295a3ee9..62b8384dc 100644 --- a/core-test/pom.xml +++ b/core-test/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 4.0.0 openstack4j-core-test diff --git a/core/pom.xml b/core/pom.xml index de5415160..f2fae0d91 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -2,11 +2,10 @@ com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 4.0.0 openstack4j-core - co-3.12.3 OpenStack4j Core OpenStack Java API https://github.com/openstack4j/openstack4j/ diff --git a/core/src/main/java/org/openstack4j/openstack/internal/OSAuthenticator.java b/core/src/main/java/org/openstack4j/openstack/internal/OSAuthenticator.java index 78983a029..c4f524358 100644 --- a/core/src/main/java/org/openstack4j/openstack/internal/OSAuthenticator.java +++ b/core/src/main/java/org/openstack4j/openstack/internal/OSAuthenticator.java @@ -143,8 +143,9 @@ private static OSClientV2 authenticateV2(org.openstack4j.openstack.identity.v2.d access = access.applyContext(info.endpoint, (org.openstack4j.openstack.identity.v2.domain.TokenAuth) auth); } - if (!info.reLinkToExistingSession) - return OSClientSession.OSClientSessionV2.createSession(access, info.perspective, info.provider, config); + if (!info.reLinkToExistingSession) { + return OSClientSessionV2.createSession(access, info.perspective, info.provider, config); + } OSClientSession.OSClientSessionV2 current = (OSClientSessionV2) OSClientSession.getCurrent(); current.access = access; @@ -156,24 +157,30 @@ private static OSClientV3 authenticateV3(KeystoneAuth auth, SessionInfo info, Co Map headers = new HashMap<>(); Authentication.Scope.Project project = auth.getScope().getProject(); if (project != null) { - if (!isEmpty(project.getId())) - headers.put(ClientConstants.HEADER_X_PROJECT_ID, project.getId()); - if (!isEmpty(project.getName())) - headers.put(ClientConstants.HEADER_X_PROJECT_NAME, project.getName()); + if (!isEmpty(project.getId())) { + headers.put(ClientConstants.HEADER_X_PROJECT_ID, project.getId()); + } + if (!isEmpty(project.getName())) { + headers.put(ClientConstants.HEADER_X_PROJECT_NAME, project.getName()); + } Authentication.Scope.Domain domain = project.getDomain(); if (domain != null) { - if (!isEmpty(domain.getId())) - headers.put(ClientConstants.HEADER_X_PROJECT_DOMAIN_ID, domain.getId()); - if (!isEmpty(domain.getName())) - headers.put(ClientConstants.HEADER_X_PROJECT_DOMAIN_NAME, domain.getName()); + if (!isEmpty(domain.getId())) { + headers.put(ClientConstants.HEADER_X_PROJECT_DOMAIN_ID, domain.getId()); + } + if (!isEmpty(domain.getName())) { + headers.put(ClientConstants.HEADER_X_PROJECT_DOMAIN_NAME, domain.getName()); + } } } else { Authentication.Scope.Domain domain = auth.getScope().getDomain(); if (domain != null) { - if (!isEmpty(domain.getId())) - headers.put(ClientConstants.HEADER_X_DOMAIN_ID, domain.getId()); - if (!isEmpty(domain.getName())) - headers.put(ClientConstants.HEADER_X_DOMAIN_NAME, domain.getName()); + if (!isEmpty(domain.getId())) { + headers.put(ClientConstants.HEADER_X_DOMAIN_ID, domain.getId()); + } + if (!isEmpty(domain.getName())) { + headers.put(ClientConstants.HEADER_X_DOMAIN_NAME, domain.getName()); + } } } KeystoneToken keystoneToken = new KeystoneToken(); @@ -230,8 +237,9 @@ private static OSClientV3 authenticateV3(KeystoneAuth auth, SessionInfo info, Co } private static boolean isEmpty(String str) { - if (str != null && str.length() > 0) - return false; + if (str != null && str.length() > 0) { + return false; + } return true; } diff --git a/distribution/pom.xml b/distribution/pom.xml index 8b414d82f..f9bb3a922 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -2,7 +2,7 @@ com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 4.0.0 openstack4j diff --git a/pom.xml b/pom.xml index d6748cc9d..e3fe30eed 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.github.openstack4j.core openstack4j-parent - 3.12 + co-3.12.4 OpenStack4j Parent OpenStack Java API https://github.com/openstack4j/openstack4j/