From b698988512e015e8e659f2fb92e54e039a9dcbf6 Mon Sep 17 00:00:00 2001 From: Bryce Anderson Date: Fri, 23 Feb 2024 17:26:24 -0700 Subject: [PATCH 1/2] examples: add an example of using DefaultLoadBalancer Motivation: We want an example to show how to test drive DefaultLoadBalancer. Modifications: - Add an example. --- .../http/defaultloadbalancer/build.gradle | 25 +++++++++ .../DefaultLoadBalancerClient.java | 56 +++++++++++++++++++ .../defaultloadbalancer/HelloWorldServer.java | 30 ++++++++++ .../defaultloadbalancer/package-info.java | 19 +++++++ .../src/main/resources/log4j2.xml | 35 ++++++++++++ settings.gradle | 1 + 6 files changed, 166 insertions(+) create mode 100644 servicetalk-examples/http/defaultloadbalancer/build.gradle create mode 100644 servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/DefaultLoadBalancerClient.java create mode 100644 servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/HelloWorldServer.java create mode 100644 servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/package-info.java create mode 100644 servicetalk-examples/http/defaultloadbalancer/src/main/resources/log4j2.xml diff --git a/servicetalk-examples/http/defaultloadbalancer/build.gradle b/servicetalk-examples/http/defaultloadbalancer/build.gradle new file mode 100644 index 0000000000..c1d4d565d8 --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/build.gradle @@ -0,0 +1,25 @@ +/* + * Copyright © 2019 Apple Inc. and the ServiceTalk project authors + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +apply plugin: "java" +apply from: "../../gradle/idea.gradle" + +dependencies { + implementation project(":servicetalk-annotations") + implementation project(":servicetalk-http-netty") + implementation project(":servicetalk-loadbalancer-experimental") + + runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion" +} diff --git a/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/DefaultLoadBalancerClient.java b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/DefaultLoadBalancerClient.java new file mode 100644 index 0000000000..3da0848301 --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/DefaultLoadBalancerClient.java @@ -0,0 +1,56 @@ +/* + * Copyright © 2024 Apple Inc. and the ServiceTalk project authors + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.servicetalk.examples.http.defaultloadbalancer; + +import io.servicetalk.client.api.LoadBalancerFactory; +import io.servicetalk.http.api.BlockingHttpClient; +import io.servicetalk.http.api.FilterableStreamingHttpLoadBalancedConnection; +import io.servicetalk.http.api.HttpResponse; +import io.servicetalk.http.api.SingleAddressHttpClientBuilder; +import io.servicetalk.http.netty.DefaultHttpLoadBalancerFactory; +import io.servicetalk.http.netty.HttpClients; +import io.servicetalk.loadbalancer.LoadBalancers; +import io.servicetalk.loadbalancer.OutlierDetectorConfig; +import io.servicetalk.loadbalancer.XdsHealthCheckerFactory; +import io.servicetalk.transport.api.HostAndPort; + +import java.net.InetSocketAddress; + +import static io.servicetalk.http.api.HttpSerializers.textSerializerUtf8; + +public final class DefaultLoadBalancerClient { + + public static void main(String[] args) throws Exception { + SingleAddressHttpClientBuilder builder = + HttpClients.forSingleAddress("localhost", 8080) + .loadBalancerFactory(DefaultHttpLoadBalancerFactory.Builder.from( + loadBalancer("localhost-defaultloadbalancer")).build()); + try (BlockingHttpClient client = builder.buildBlocking()) { + HttpResponse response = client.request(client.get("/sayHello")); + System.out.println(response.toString((name, value) -> value)); + System.out.println(response.payloadBody(textSerializerUtf8())); + } + } + + private static LoadBalancerFactory loadBalancer( + String id) { + return LoadBalancers. + builder(id) + .healthCheckerFactory(new XdsHealthCheckerFactory<>( + new OutlierDetectorConfig.Builder().build() + )).build(); + } +} diff --git a/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/HelloWorldServer.java b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/HelloWorldServer.java new file mode 100644 index 0000000000..eef709aeae --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/HelloWorldServer.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2024 Apple Inc. and the ServiceTalk project authors + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.servicetalk.examples.http.defaultloadbalancer; + +import io.servicetalk.http.netty.HttpServers; + +import static io.servicetalk.http.api.HttpSerializers.textSerializerUtf8; + +public final class HelloWorldServer { + + public static void main(String[] args) throws Exception { + HttpServers.forPort(8080) + .listenBlockingAndAwait((ctx, request, responseFactory) -> + responseFactory.ok().payloadBody("Hello World!", textSerializerUtf8())) + .awaitShutdown(); + } +} diff --git a/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/package-info.java b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/package-info.java new file mode 100644 index 0000000000..9ccc222a70 --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright © 2024 Apple Inc. and the ServiceTalk project authors + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@ElementsAreNonnullByDefault +package io.servicetalk.examples.http.defaultloadbalancer; + +import io.servicetalk.annotations.ElementsAreNonnullByDefault; diff --git a/servicetalk-examples/http/defaultloadbalancer/src/main/resources/log4j2.xml b/servicetalk-examples/http/defaultloadbalancer/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..3e1a0311eb --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/src/main/resources/log4j2.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/settings.gradle b/settings.gradle index dc3fa8dd6f..9a6d88cf04 100755 --- a/settings.gradle +++ b/settings.gradle @@ -70,6 +70,7 @@ include "servicetalk-annotations", "servicetalk-examples:http:compression", "servicetalk-examples:http:debugging", "servicetalk-examples:http:timeout", + "servicetalk-examples:http:defaultloadbalancer", "servicetalk-gradle-plugin-internal", "servicetalk-grpc-api", "servicetalk-grpc-health", From 536d4b347cdc8bdfdab850b8e21db0fbb68e8565 Mon Sep 17 00:00:00 2001 From: Bryce Anderson Date: Tue, 27 Feb 2024 14:32:53 -0700 Subject: [PATCH 2/2] Link example into documentation --- .../ROOT/pages/_partials/nav-versioned.adoc | 1 + .../docs/modules/ROOT/pages/http/index.adoc | 14 ++++++++++++++ .../http/defaultloadbalancer/README.adoc | 4 ++++ 3 files changed, 19 insertions(+) create mode 100644 servicetalk-examples/http/defaultloadbalancer/README.adoc diff --git a/servicetalk-examples/docs/modules/ROOT/pages/_partials/nav-versioned.adoc b/servicetalk-examples/docs/modules/ROOT/pages/_partials/nav-versioned.adoc index 8231c6338a..40943c2a24 100644 --- a/servicetalk-examples/docs/modules/ROOT/pages/_partials/nav-versioned.adoc +++ b/servicetalk-examples/docs/modules/ROOT/pages/_partials/nav-versioned.adoc @@ -12,6 +12,7 @@ ** xref:{page-version}@servicetalk-examples::http/index.adoc#HTTP2[HTTP/2] ** xref:{page-version}@servicetalk-examples::http/index.adoc#Mutual-TLS[Mutual TLS] ** xref:{page-version}@servicetalk-examples::http/index.adoc#Observer[Observer] +** xref:{page-version}@servicetalk-examples::http/index.adoc#DefaultLoadBalancer[DefaultLoadBalancer] ** xref:{page-version}@servicetalk-examples::http/index.adoc#OpenTracing[OpenTracing] ** xref:{page-version}@servicetalk-examples::http/index.adoc#Redirects[Redirects] ** xref:{page-version}@servicetalk-examples::http/index.adoc#Retries[Retries] diff --git a/servicetalk-examples/docs/modules/ROOT/pages/http/index.adoc b/servicetalk-examples/docs/modules/ROOT/pages/http/index.adoc index 81ee71b7ba..00de31b88a 100644 --- a/servicetalk-examples/docs/modules/ROOT/pages/http/index.adoc +++ b/servicetalk-examples/docs/modules/ROOT/pages/http/index.adoc @@ -226,6 +226,20 @@ on via a client filter on the client builder. link:{source-root}/servicetalk-http-api/src/main/java/io/servicetalk/http/api/HttpLifecycleObserver.java[HttpLifecycleObserver] on via a client filter on the client builder. +[#DefaultLoadBalancer] +== DefaultLoadBalancer +This example demonstrates how to use the experimental link:{source-root}/servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java[DefaultLoadBalancer]: + +- by setting the load balancer to DefaultLoadBalancer for a HTTP client +- configuring xDS failure detection for that client using default settings + +Using the following classes: + +- link:{source-root}/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/DefaultLoadBalancerClient.java[DefaultLoadBalancerClient] - A client that uses the DefaultLoadBalancer. +- link:{source-root}/servicetalk-examples/http/defaultloadbalancer/src/main/java/io/servicetalk/examples/http/defaultloadbalancer/HelloWorldServer.java[HelloWorldServer] - A simple server implementation. + +NOTE: DefaultLoadBalancer is currently considered experimental and therefore the API is subject to change. + [#OpenTracing] == OpenTracing diff --git a/servicetalk-examples/http/defaultloadbalancer/README.adoc b/servicetalk-examples/http/defaultloadbalancer/README.adoc new file mode 100644 index 0000000000..84546f79b4 --- /dev/null +++ b/servicetalk-examples/http/defaultloadbalancer/README.adoc @@ -0,0 +1,4 @@ +== ServiceTalk DefaultLoadBalancer Example + +A simple hello-world style application that uses a client configured with the DefaultLoadBalancer and xDS style outlier +detection. \ No newline at end of file