From e530c328ecd81234945b54a3156e428b5356e363 Mon Sep 17 00:00:00 2001 From: jansupol Date: Fri, 19 Jun 2020 01:06:35 +0200 Subject: [PATCH] Implemented ClientBuilderListener Signed-off-by: jansupol --- .../jersey/client/JerseyClientBuilder.java | 34 ++++++++++- .../client/spi/ClientBuilderListener.java | 52 ++++++++++++++++ .../client/spi/ClientBuilderListenerTest.java | 61 +++++++++++++++++++ ...sh.jersey.client.spi.ClientBuilderListener | 3 + 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java create mode 100644 core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java create mode 100644 core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener diff --git a/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java b/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java index 5f1a5942af..8ad0eeaefb 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/JerseyClientBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -17,6 +17,9 @@ package org.glassfish.jersey.client; import java.security.KeyStore; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; @@ -30,8 +33,12 @@ import org.glassfish.jersey.SslConfigurator; import org.glassfish.jersey.client.internal.LocalizationMessages; +import org.glassfish.jersey.client.spi.ClientBuilderListener; +import org.glassfish.jersey.internal.ServiceFinder; import org.glassfish.jersey.internal.util.collection.UnsafeValue; import org.glassfish.jersey.internal.util.collection.Values; +import org.glassfish.jersey.model.internal.RankedComparator; +import org.glassfish.jersey.model.internal.RankedProvider; /** * Jersey provider of {@link javax.ws.rs.client.ClientBuilder JAX-RS client builder}. @@ -45,6 +52,23 @@ public class JerseyClientBuilder extends ClientBuilder { private SslConfigurator sslConfigurator; private SSLContext sslContext; + private static final List CLIENT_BUILDER_LISTENERS; + + static { + final List> listeners = new LinkedList<>(); + for (ClientBuilderListener listener : ServiceFinder.find(ClientBuilderListener.class)) { + listeners.add(new RankedProvider<>(listener)); + } + listeners.sort(new RankedComparator<>(RankedComparator.Order.ASCENDING)); + + final List sortedList = new LinkedList<>(); + for (RankedProvider listener : listeners) { + sortedList.add(listener.getProvider()); + } + + CLIENT_BUILDER_LISTENERS = Collections.unmodifiableList(sortedList); + } + /** * Create a new custom-configured {@link JerseyClient} instance. * @@ -72,6 +96,14 @@ public static JerseyClient createClient(Configuration configuration) { */ public JerseyClientBuilder() { this.config = new ClientConfig(); + + init(this); + } + + private static void init(ClientBuilder builder) { + for (ClientBuilderListener listener : CLIENT_BUILDER_LISTENERS) { + listener.onNewBuilder(builder); + } } @Override diff --git a/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java b/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java new file mode 100644 index 0000000000..10b25115a6 --- /dev/null +++ b/core-client/src/main/java/org/glassfish/jersey/client/spi/ClientBuilderListener.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.client.spi; + +import org.glassfish.jersey.Beta; + +import javax.ws.rs.client.ClientBuilder; + +/** + *

+ * Implementations of this interface will be notified when new ClientBuilder + * instances are being constructed. This will allow implementations to register + * providers on the ClientBuilder, and is intended for global providers. + *

+ *

+ * In order for the ClientBuilder to call implementations of this interface, + * the implementation must be specified such that a ServiceLoader can find it - + * i.e. it must be specified in the + * META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener + * file in an archive on the current thread's context classloader's + * class path. + *

+ *

+ * Note that the onNewBuilder method will be called when the + * ClientBuilder is constructed, not when it's build method is + * invoked. This allows the caller to override global providers if they desire. + *

+ *

+ * The ClientBuilderListener are invoked in an order given by it's {@code @Priority}. + * The default is {@code Priorities.USER}. + *

+ * @since 2.32 + */ +// Must not be annotated with @Contract +@Beta +public interface ClientBuilderListener { + void onNewBuilder(ClientBuilder builder); +} diff --git a/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java b/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java new file mode 100644 index 0000000000..e2776fc79c --- /dev/null +++ b/core-client/src/test/java/org/glassfish/jersey/client/spi/ClientBuilderListenerTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.client.spi; + +import org.glassfish.jersey.client.ClientConfig; +import org.junit.Assert; +import org.junit.Test; + +import javax.annotation.Priority; +import javax.ws.rs.Priorities; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + +public class ClientBuilderListenerTest { + + public static final String PROPERTY_NAME = "ClientBuilderListenerProperty"; + + @Priority(Priorities.USER + 1000) + public static class FirstClientBuilderListener implements ClientBuilderListener { + @Override + public void onNewBuilder(ClientBuilder builder) { + builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 60)); + } + } + + public static class SecondClientBuilderListener implements ClientBuilderListener { + @Override + public void onNewBuilder(ClientBuilder builder) { + builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 50)); + } + } + + @Priority(Priorities.USER + 2000) + public static class ThirdClientBuilderListener implements ClientBuilderListener { + @Override + public void onNewBuilder(ClientBuilder builder) { + builder.withConfig(new ClientConfig().property(PROPERTY_NAME, 70)); + } + } + + @Test + public void testClientBuilderListener() { + Client client = ClientBuilder.newClient(); + Assert.assertEquals(70, client.getConfiguration().getProperty(PROPERTY_NAME)); + } + +} diff --git a/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener b/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener new file mode 100644 index 0000000000..4cfec496fa --- /dev/null +++ b/core-client/src/test/resources/META-INF/services/org.glassfish.jersey.client.spi.ClientBuilderListener @@ -0,0 +1,3 @@ +org.glassfish.jersey.client.spi.ClientBuilderListenerTest$ThirdClientBuilderListener +org.glassfish.jersey.client.spi.ClientBuilderListenerTest$FirstClientBuilderListener +org.glassfish.jersey.client.spi.ClientBuilderListenerTest$SecondClientBuilderListener \ No newline at end of file