diff --git a/.gitignore b/.gitignore index f4739a6f..39d4567d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ nbactions.xml src/site/markdown/*.html target/ +.idea +*.iml \ No newline at end of file diff --git a/src/main/java/org/microbean/helm/DefaultManagedChannelFactory.java b/src/main/java/org/microbean/helm/DefaultManagedChannelFactory.java new file mode 100644 index 00000000..c97d3b3e --- /dev/null +++ b/src/main/java/org/microbean/helm/DefaultManagedChannelFactory.java @@ -0,0 +1,61 @@ +package org.microbean.helm; + +import io.fabric8.kubernetes.client.LocalPortForward; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.net.InetAddress; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import org.microbean.development.annotation.Issue; + +/** + * A default implementation of the {@link ManagedChannelFactory} that creates a {@link ManagedChannel} + * from a {@link LocalPortForward}. + * + * Allows additional customization of the {@link ManagedChannelBuilder} by supplying a + * {@link ManagedChannelConfigurer} to the constructor. + */ +public class DefaultManagedChannelFactory implements ManagedChannelFactory { + + private static final ManagedChannelConfigurer NOOP_CONFIGURER = (builder) -> {}; + private final ManagedChannelConfigurer configurer; + + public DefaultManagedChannelFactory() { + this.configurer = NOOP_CONFIGURER; + } + + /** + * @param configurer a {@link ManagedChannelConfigurer} to allow overriding of the default + * configuration of the {@link ManagedChannel} + * + * @throws NullPointerException if the configurer is null + */ + public DefaultManagedChannelFactory(final ManagedChannelConfigurer configurer) { + Objects.requireNonNull(configurer); + this.configurer = configurer; + } + + @Issue(id = "42", uri = "https://github.com/microbean/microbean-helm/issues/42") + @Override public ManagedChannel create(final LocalPortForward portForward) { + Objects.requireNonNull(portForward); + @Issue(id = "43", uri = "https://github.com/microbean/microbean-helm/issues/43") + final InetAddress localAddress = portForward.getLocalAddress(); + if (localAddress == null) { + throw new IllegalArgumentException("portForward", + new IllegalStateException("portForward.getLocalAddress() == null")); + } + final String hostAddress = localAddress.getHostAddress(); + if (hostAddress == null) { + throw new IllegalArgumentException("portForward", + new IllegalStateException("portForward.getLocalAddress().getHostAddress() == null")); + } + final ManagedChannelBuilder builder = + ManagedChannelBuilder.forAddress(hostAddress, portForward.getLocalPort()) + .idleTimeout(5L, TimeUnit.SECONDS) + .keepAliveTime(30L, TimeUnit.SECONDS) + .maxInboundMessageSize(Tiller.MAX_MESSAGE_SIZE) + .usePlaintext(true); + configurer.configure(builder); + return builder.build(); + } +} diff --git a/src/main/java/org/microbean/helm/ManagedChannelConfigurer.java b/src/main/java/org/microbean/helm/ManagedChannelConfigurer.java new file mode 100644 index 00000000..51c86d80 --- /dev/null +++ b/src/main/java/org/microbean/helm/ManagedChannelConfigurer.java @@ -0,0 +1,11 @@ +package org.microbean.helm; + +import io.grpc.ManagedChannelBuilder; + +/** + * An interface whose implementations configure options on the supplied + * {@link ManagedChannelBuilder} to override defaults. + */ +public interface ManagedChannelConfigurer { + void configure(final ManagedChannelBuilder> managedChannelBuilder); +} diff --git a/src/main/java/org/microbean/helm/ManagedChannelFactory.java b/src/main/java/org/microbean/helm/ManagedChannelFactory.java new file mode 100644 index 00000000..07c3dc21 --- /dev/null +++ b/src/main/java/org/microbean/helm/ManagedChannelFactory.java @@ -0,0 +1,32 @@ +package org.microbean.helm; + +import io.fabric8.kubernetes.client.LocalPortForward; +import io.grpc.ManagedChannel; + +/** + * An interface whose implementations create a {@link ManagedChannel} from a + * {@link LocalPortForward} to be used to communicate with Tiller. + */ +public interface ManagedChannelFactory { + + /** + * Creates a {@link ManagedChannel} for communication with Tiller + * from the information contained in the supplied {@link + * LocalPortForward}. + * + *
This method never returns {@code null}.
+ * + *Overrides of this method must not return {@code null}.
+ * + * @param portForward a {@link LocalPortForward}; must not be {@code + * null} + * @return a non-{@code null} {@link ManagedChannel} + * @throws NullPointerException if {@code portForward} is {@code + * null} + * @throws IllegalArgumentException if {@code portForward}'s + * {@link LocalPortForward#getLocalAddress()} method returns {@code + * null} + */ + ManagedChannel create(final LocalPortForward portForward); + +} diff --git a/src/main/java/org/microbean/helm/Tiller.java b/src/main/java/org/microbean/helm/Tiller.java index dd5ecca4..8b50ea5e 100644 --- a/src/main/java/org/microbean/helm/Tiller.java +++ b/src/main/java/org/microbean/helm/Tiller.java @@ -19,7 +19,6 @@ import java.io.Closeable; import java.io.IOException; -import java.net.InetAddress; import java.net.MalformedURLException; import java.util.Collections; @@ -27,8 +26,6 @@ import java.util.Map; import java.util.Objects; -import java.util.concurrent.TimeUnit; - import hapi.services.tiller.ReleaseServiceGrpc; import hapi.services.tiller.ReleaseServiceGrpc.ReleaseServiceBlockingStub; import hapi.services.tiller.ReleaseServiceGrpc.ReleaseServiceFutureStub; @@ -46,7 +43,6 @@ import io.fabric8.kubernetes.client.LocalPortForward; import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; import io.grpc.health.v1.HealthGrpc; @@ -58,8 +54,6 @@ import okhttp3.OkHttpClient; -import org.microbean.development.annotation.Issue; - import org.microbean.kubernetes.Pods; /** @@ -113,7 +107,7 @@ public class Tiller implements ConfigAwareThe {@linkplain Pods#getFirstReadyPod(Listable) first ready + * Pod} with a {@code name} label whose value is {@code tiller} and + * with an {@code app} label whose value is {@code helm} is deemed + * to be the pod housing the Tiller instance to connect to. (This + * duplicates the default logic of the {@code helm} command line + * executable.)
+ * + * @paramNote: This method is (deliberately) called - * from constructors so must have stateless semantics.
- * - *This method never returns {@code null}.
- * - *Overrides of this method must not return {@code null}.
- * - * @param portForward a {@link LocalPortForward}; must not be {@code - * null} - * - * @return a non-{@code null} {@link ManagedChannel} - * - * @exception NullPointerException if {@code portForward} is {@code - * null} - * - * @exception IllegalArgumentException if {@code portForward}'s - * {@link LocalPortForward#getLocalAddress()} method returns {@code - * null} - */ - @Issue(id = "42", uri = "https://github.com/microbean/microbean-helm/issues/42") - protected ManagedChannel buildChannel(final LocalPortForward portForward) { - Objects.requireNonNull(portForward); - @Issue(id = "43", uri = "https://github.com/microbean/microbean-helm/issues/43") - final InetAddress localAddress = portForward.getLocalAddress(); - if (localAddress == null) { - throw new IllegalArgumentException("portForward", new IllegalStateException("portForward.getLocalAddress() == null")); - } - final String hostAddress = localAddress.getHostAddress(); - if (hostAddress == null) { - throw new IllegalArgumentException("portForward", new IllegalStateException("portForward.getLocalAddress().getHostAddress() == null")); - } - return ManagedChannelBuilder.forAddress(hostAddress, portForward.getLocalPort()) - .idleTimeout(5L, TimeUnit.SECONDS) - .keepAliveTime(30L, TimeUnit.SECONDS) - .maxInboundMessageSize(MAX_MESSAGE_SIZE) - .usePlaintext(true) - .build(); - } /** * Closes this {@link Tiller} after use; any {@link @@ -498,7 +501,7 @@ public ReleaseServiceFutureStub getReleaseServiceFutureStub() { * @return a non-{@code null} {@link ReleaseServiceStub} * * @see ReleaseServiceStub - */ + */ public ReleaseServiceStub getReleaseServiceStub() { ReleaseServiceStub returnValue = null; if (this.channel != null) { @@ -522,7 +525,7 @@ public HealthFutureStub getHealthFutureStub() { } return returnValue; } - + public HealthStub getHealthStub() { HealthStub returnValue = null; if (this.channel != null) { @@ -538,5 +541,5 @@ public VersionOrBuilder getVersion() throws IOException { assert response != null; return response.getVersion(); } - + } diff --git a/src/main/java/org/microbean/helm/TillerInstaller.java b/src/main/java/org/microbean/helm/TillerInstaller.java index 767d3318..385a9686 100644 --- a/src/main/java/org/microbean/helm/TillerInstaller.java +++ b/src/main/java/org/microbean/helm/TillerInstaller.java @@ -999,7 +999,7 @@ protected final