From c8df871258989336c2cc30e2d2005f5e354bb9f0 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Tue, 4 Jan 2022 14:35:33 +0100 Subject: Provide feed client reference --- .../hosted/cd/cloud/impl/VespaTestRuntime.java | 2 +- .../services/ai.vespa.hosted.cd.TestRuntime | 2 - .../ai/vespa/feed/client/FeedClientBuilder.java | 32 ++-------------- .../src/main/java/ai/vespa/feed/client/Helper.java | 44 ++++++++++++++++++++++ 4 files changed, 49 insertions(+), 31 deletions(-) delete mode 100644 cloud-tenant-cd/src/main/resources/META-INF/services/ai.vespa.hosted.cd.TestRuntime diff --git a/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/cloud/impl/VespaTestRuntime.java b/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/cloud/impl/VespaTestRuntime.java index 201ddcb3908..1e6065c63b9 100644 --- a/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/cloud/impl/VespaTestRuntime.java +++ b/cloud-tenant-cd/src/main/java/ai/vespa/hosted/cd/cloud/impl/VespaTestRuntime.java @@ -43,7 +43,7 @@ public class VespaTestRuntime implements TestRuntime { DefaultEndpointAuthenticator authenticator = new DefaultEndpointAuthenticator(config.system()); this.deploymentToTest = new HttpDeployment(config.deployments().get(config.zone()), authenticator); FeedClientBuilder.setEndpointAuthenticator(authenticator); - System.setProperty(ai.vespa.feed.client.FeedClientBuilder.PREFERRED_IMPLEMENTATION_PROPERTY, FeedClientBuilder.class.getName()); + ai.vespa.feed.client.FeedClientBuilder.setFeedClientBuilderSupplier(FeedClientBuilder::new); } @Override diff --git a/cloud-tenant-cd/src/main/resources/META-INF/services/ai.vespa.hosted.cd.TestRuntime b/cloud-tenant-cd/src/main/resources/META-INF/services/ai.vespa.hosted.cd.TestRuntime deleted file mode 100644 index 9d318b87fca..00000000000 --- a/cloud-tenant-cd/src/main/resources/META-INF/services/ai.vespa.hosted.cd.TestRuntime +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -ai.vespa.hosted.cd.cloud.impl.VespaTestRuntime \ No newline at end of file diff --git a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java index 05bc608df27..94d5a0ba2d1 100644 --- a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java +++ b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java @@ -3,18 +3,13 @@ package ai.vespa.feed.client; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.nio.file.Path; import java.security.PrivateKey; import java.security.cert.X509Certificate; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; -import java.util.ServiceLoader; import java.util.function.Supplier; /** @@ -32,31 +27,12 @@ public interface FeedClientBuilder { /** Creates a builder for multiple container endpoints **/ static FeedClientBuilder create(List endpoints) { - String defaultImplementation = "ai.vespa.feed.client.impl.FeedClientBuilderImpl"; - String preferredImplementation = System.getProperty(PREFERRED_IMPLEMENTATION_PROPERTY, defaultImplementation); - Iterator iterator = ServiceLoader.load(FeedClientBuilder.class).iterator(); - if (iterator.hasNext()) { - List builders = new ArrayList<>(); - iterator.forEachRemaining(builders::add); - return builders.stream() - .filter(builder -> preferredImplementation.equals(builder.getClass().getName())) - .findFirst() - .orElse(builders.get(0)); - } else { - try { - Class aClass = Class.forName(preferredImplementation); - for (Constructor constructor : aClass.getConstructors()) { - if (constructor.getParameterTypes().length==0) { - return ((FeedClientBuilder)constructor.newInstance()).setEndpointUris(endpoints); - } - } - throw new RuntimeException("Could not find Feed client builder implementation"); - } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } + return Helper.getFeedClientBuilder().setEndpointUris(endpoints); } + static void setFeedClientBuilderSupplier(Supplier supplier) { + Helper.setFeedClientBuilderReference(supplier); + } /** * Sets the number of connections this client will use per endpoint. * diff --git a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java index 59c12077bef..edf9457aaa1 100644 --- a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java +++ b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java @@ -1,18 +1,62 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package ai.vespa.feed.client; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.ServiceLoader; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; import java.util.stream.Collectors; +import static ai.vespa.feed.client.FeedClientBuilder.PREFERRED_IMPLEMENTATION_PROPERTY; + /** * @author bjorncs */ class Helper { + static final AtomicReference> feedClientBuilderSupplier = new AtomicReference<>(); + + static final void setFeedClientBuilderReference(Supplier supplier) { + feedClientBuilderSupplier.set(supplier); + } + + static FeedClientBuilder getFeedClientBuilder() { + if (Helper.feedClientBuilderSupplier.get()!=null) { + return Helper.feedClientBuilderSupplier.get().get(); + } else { + String defaultImplementation = "ai.vespa.feed.client.impl.FeedClientBuilderImpl"; + String preferredImplementation = System.getProperty(PREFERRED_IMPLEMENTATION_PROPERTY, defaultImplementation); + Iterator iterator = ServiceLoader.load(FeedClientBuilder.class).iterator(); + if (iterator.hasNext()) { + List builders = new ArrayList<>(); + iterator.forEachRemaining(builders::add); + return builders.stream() + .filter(builder -> preferredImplementation.equals(builder.getClass().getName())) + .findFirst() + .orElse(builders.get(0)); + } else { + try { + Class aClass = Class.forName(preferredImplementation); + for (Constructor constructor : aClass.getConstructors()) { + if (constructor.getParameterTypes().length == 0) { + return ((FeedClientBuilder) constructor.newInstance()); + } + } + throw new RuntimeException("Could not find Feed client builder implementation"); + } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + } + private Helper() {} @SafeVarargs -- cgit v1.2.3 From 95494e40aaf1bfbccca89c0b45b7dfbc7f1b8387 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Tue, 4 Jan 2022 14:45:59 +0100 Subject: Update abi-spec --- vespa-feed-client-api/abi-spec.json | 1 + 1 file changed, 1 insertion(+) diff --git a/vespa-feed-client-api/abi-spec.json b/vespa-feed-client-api/abi-spec.json index 8af7798984f..16e532a2c9a 100644 --- a/vespa-feed-client-api/abi-spec.json +++ b/vespa-feed-client-api/abi-spec.json @@ -123,6 +123,7 @@ "methods": [ "public static ai.vespa.feed.client.FeedClientBuilder create(java.net.URI)", "public static ai.vespa.feed.client.FeedClientBuilder create(java.util.List)", + "public static void setFeedClientBuilderSupplier(java.util.function.Supplier)", "public abstract ai.vespa.feed.client.FeedClientBuilder setConnectionsPerEndpoint(int)", "public abstract ai.vespa.feed.client.FeedClientBuilder setMaxStreamPerConnection(int)", "public abstract ai.vespa.feed.client.FeedClientBuilder setSslContext(javax.net.ssl.SSLContext)", -- cgit v1.2.3 From 0b0233583f656e2e5b02bc7fd0fbf69a7b2a2e3c Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Tue, 4 Jan 2022 15:23:46 +0100 Subject: Supply default implementation --- .../ai/vespa/feed/client/FeedClientBuilder.java | 5 ++- .../src/main/java/ai/vespa/feed/client/Helper.java | 48 +++++++++++----------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java index 94d5a0ba2d1..95c9b2c95fe 100644 --- a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java +++ b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/FeedClientBuilder.java @@ -27,11 +27,12 @@ public interface FeedClientBuilder { /** Creates a builder for multiple container endpoints **/ static FeedClientBuilder create(List endpoints) { - return Helper.getFeedClientBuilder().setEndpointUris(endpoints); + return Helper.getFeedClientBuilderSupplier().get().setEndpointUris(endpoints); } + /** Override FeedClientBuilder. This will be preferred in {@link #create} */ static void setFeedClientBuilderSupplier(Supplier supplier) { - Helper.setFeedClientBuilderReference(supplier); + Helper.setFeedClientBuilderSupplier(supplier); } /** * Sets the number of connections this client will use per endpoint. diff --git a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java index edf9457aaa1..6971b2ea8f5 100644 --- a/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java +++ b/vespa-feed-client-api/src/main/java/ai/vespa/feed/client/Helper.java @@ -21,38 +21,38 @@ import static ai.vespa.feed.client.FeedClientBuilder.PREFERRED_IMPLEMENTATION_PR */ class Helper { - static final AtomicReference> feedClientBuilderSupplier = new AtomicReference<>(); + private static final AtomicReference> feedClientBuilderSupplier = new AtomicReference<>(Helper::getFeedClientBuilder); - static final void setFeedClientBuilderReference(Supplier supplier) { + static final void setFeedClientBuilderSupplier(Supplier supplier) { feedClientBuilderSupplier.set(supplier); } + static Supplier getFeedClientBuilderSupplier() { + return feedClientBuilderSupplier.get(); + } + static FeedClientBuilder getFeedClientBuilder() { - if (Helper.feedClientBuilderSupplier.get()!=null) { - return Helper.feedClientBuilderSupplier.get().get(); + String defaultImplementation = "ai.vespa.feed.client.impl.FeedClientBuilderImpl"; + String preferredImplementation = System.getProperty(PREFERRED_IMPLEMENTATION_PROPERTY, defaultImplementation); + Iterator iterator = ServiceLoader.load(FeedClientBuilder.class).iterator(); + if (iterator.hasNext()) { + List builders = new ArrayList<>(); + iterator.forEachRemaining(builders::add); + return builders.stream() + .filter(builder -> preferredImplementation.equals(builder.getClass().getName())) + .findFirst() + .orElse(builders.get(0)); } else { - String defaultImplementation = "ai.vespa.feed.client.impl.FeedClientBuilderImpl"; - String preferredImplementation = System.getProperty(PREFERRED_IMPLEMENTATION_PROPERTY, defaultImplementation); - Iterator iterator = ServiceLoader.load(FeedClientBuilder.class).iterator(); - if (iterator.hasNext()) { - List builders = new ArrayList<>(); - iterator.forEachRemaining(builders::add); - return builders.stream() - .filter(builder -> preferredImplementation.equals(builder.getClass().getName())) - .findFirst() - .orElse(builders.get(0)); - } else { - try { - Class aClass = Class.forName(preferredImplementation); - for (Constructor constructor : aClass.getConstructors()) { - if (constructor.getParameterTypes().length == 0) { - return ((FeedClientBuilder) constructor.newInstance()); - } + try { + Class aClass = Class.forName(preferredImplementation); + for (Constructor constructor : aClass.getConstructors()) { + if (constructor.getParameterTypes().length == 0) { + return ((FeedClientBuilder) constructor.newInstance()); } - throw new RuntimeException("Could not find Feed client builder implementation"); - } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - throw new RuntimeException(e); } + throw new RuntimeException("Could not find Feed client builder implementation"); + } catch (ClassNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); } } } -- cgit v1.2.3