diff --git a/.github/workflows/quickstart_ha-singleton-deployment_ci.yml b/.github/workflows/quickstart_ha-singleton-deployment_ci.yml new file mode 100644 index 0000000000..0657c09a44 --- /dev/null +++ b/.github/workflows/quickstart_ha-singleton-deployment_ci.yml @@ -0,0 +1,15 @@ +name: WildFly ha-singleton-deployment Quickstart CI + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - 'ha-singleton-deployment/**' + - '.github/workflows/quickstart_ci.yml' + +jobs: + call-quickstart_ci: + uses: ./.github/workflows/quickstart_ci.yml + with: + QUICKSTART_PATH: ha-singleton-deployment + TEST_OPENSHIFT: false diff --git a/ha-singleton-deployment/README-source.adoc b/ha-singleton-deployment/README-source.adoc index 2457d0a022..b8c8c69f13 100644 --- a/ha-singleton-deployment/README-source.adoc +++ b/ha-singleton-deployment/README-source.adoc @@ -9,15 +9,15 @@ include::../shared-doc/attributes.adoc[] The `ha-singleton-deployment` quickstart demonstrates the recommended way to deploy any service packaged in an application archive as a cluster-wide singleton. :standalone-server-type: ha -:archiveType: jar +:archiveType: war :requires-multiple-servers: :jbds-not-supported: == What is it? The `ha-singleton-deployment` quickstart demonstrates the deployment of a service packaged in an application as a cluster-wide singleton using singleton deployments. -In this example, the service is a timer that is initialized by a `@Startup @Singleton` bean. -The example is built and packaged as a single EJB archive. +In this example, the service is a timer that is initialized by a `@Startup @Singleton` Jakarta Enterprise Beans bean. +The example is built and packaged as a single web archive. For more information about singleton deployments, see _HA Singleton Deployments_ in the {LinkDevelopmentGuide}[__{DevelopmentBookName}__] for {DocInfoProductName} located on the Red Hat Customer Portal. @@ -58,15 +58,15 @@ This example is not limited to two servers. Additional servers can be started by $ mvn clean install wildfly:deploy ---- -. Ensure the `target/{artifactId}.jar` archive is deployed to `node1` (the one without port offset) by observing the log. +. Ensure the `target/{artifactId}.war` archive is deployed to `node1` (the one without port offset) by observing the log. + [source,options="nowrap"] ---- -INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of "ha-singleton-deployment.jar" (runtime-name: "ha-singleton-deployment.jar") +INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of "ha-singleton-deployment.war" (runtime-name: "ha-singleton-deployment.war") ... -INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: node1 elected as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.jar".FIRST_MODULE_USE service -INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0001: This node will now operate as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.jar".FIRST_MODULE_USE service -INFO [org.jboss.as.server] (management-handler-thread - 4) WFLYSRV0010: Deployed "ha-singleton-deployment.jar" (runtime-name : "ha-singleton-deployment.jar") +INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: node1 elected as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.war".FIRST_MODULE_USE service +INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0001: This node will now operate as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.war".FIRST_MODULE_USE service +INFO [org.jboss.as.server] (management-handler-thread - 4) WFLYSRV0010: Deployed "ha-singleton-deployment.war" (runtime-name : "ha-singleton-deployment.war") ... WARNING [class org.jboss.as.quickstarts.ha.singleton.SingletonTimer] (ServerService Thread Pool -- 68) SingletonTimer is initializing. INFO [class org.jboss.as.quickstarts.ha.singleton.SingletonTimer] (EJB default - 1) SingletonTimer: Hello World! @@ -87,11 +87,11 @@ WARN [org.jboss.as.clustering.jgroups.protocol.UDP] (ServerService Thread Pool mvn wildfly:deploy -Dwildfly.port=10090 ---- -. Ensure the `service/target/{artifactId}.jar` archive is deployed to `node2` by observing the log. Note that even though the logs indicate "Deployed", the deployment does not actually deploy completely and the timer is not operating on this node. +. Ensure the `service/target/{artifactId}.war` archive is deployed to `node2` by observing the log. Note that even though the logs indicate "Deployed", the deployment does not actually deploy completely and the timer is not operating on this node. + [source,options="nowrap"] ---- -INFO [org.jboss.as.server.deployment] (MSC service thread 1-6) WFLYSRV0027: Starting deployment of "ha-singleton-deployment.jar" (runtime-name: "ha-singleton-deployment.jar") +INFO [org.jboss.as.server.deployment] (MSC service thread 1-6) WFLYSRV0027: Starting deployment of "ha-singleton-deployment.war" (runtime-name: "ha-singleton-deployment.war") INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (MSC service thread 1-3) ISPN000078: Starting JGroups channel server ... INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (MSC service thread 1-3) ISPN000094: Received new cluster view for channel server: [node1|1] (2) [node1, node2] @@ -99,7 +99,7 @@ INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (MSC service INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (MSC service thread 1-3) ISPN000079: Channel server local address is node2, physical addresses are [127.0.0.1:55300] INFO [org.infinispan.factories.GlobalComponentRegistry] (MSC service thread 1-6) ISPN000128: Infinispan version: Infinispan 'Chakra' 8.2.7.Final INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 68) WFLYCLINF0002: Started default cache from server container -INFO [org.jboss.as.server] (management-handler-thread - 2) WFLYSRV0010: Deployed "ha-singleton-deployment.jar" (runtime-name : "ha-singleton-deployment.jar") +INFO [org.jboss.as.server] (management-handler-thread - 2) WFLYSRV0010: Deployed "ha-singleton-deployment.war" (runtime-name : "ha-singleton-deployment.war") ---- . Verify the timer is running only on one instance by observing the logs. The node running the timer will output the following every 5 seconds: @@ -113,7 +113,7 @@ While the instance not running, the timer will display the following as the last + [source,options="nowrap"] ---- -INFO [org.jboss.as.server] (management-handler-thread - 2) WFLYSRV0010: Deployed "ha-singleton-deployment.jar" (runtime-name : "ha-singleton-deployment.jar") +INFO [org.jboss.as.server] (management-handler-thread - 2) WFLYSRV0010: Deployed "ha-singleton-deployment.war" (runtime-name : "ha-singleton-deployment.war") ---- . Verify failover of the singleton deployment. Shutdown the server operating as the primary provider of the singleton, for instance by using the `Ctrl` + `C` key combination in the terminal. Observe the following messages on the node being shutdown: @@ -132,8 +132,8 @@ Now observe the log messages on the second server. The node will now be elected + [source,options="nowrap"] ---- -INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: node2 elected as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.jar".FIRST_MODULE_USE service -INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0001: This node will now operate as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.jar".FIRST_MODULE_USE service +INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: node2 elected as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.war".FIRST_MODULE_USE service +INFO [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0001: This node will now operate as the singleton provider of the jboss.deployment.unit."ha-singleton-deployment.war".FIRST_MODULE_USE service INFO [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (thread-4) ISPN000094: Received new cluster view for channel server: [node2|2] (1) [node2] ... WARNING [class org.jboss.as.quickstarts.ha.singleton.SingletonTimer] (ServerService Thread Pool -- 68) SingletonTimer is initializing. @@ -151,7 +151,7 @@ Note the `include-runtime` flag on the `read-resource` operation. [source,options="nowrap"] ---- -[standalone@localhost:9990 /] /subsystem=singleton/singleton-policy=default/deployment=ha-singleton-deployment.jar:read-resource(include-runtime=true) +[standalone@localhost:9990 /] /subsystem=singleton/singleton-policy=default/deployment=ha-singleton-deployment.war:read-resource(include-runtime=true) { "outcome" => "success", "result" => { @@ -169,7 +169,7 @@ The typical use case for scripting to determine the primary provider of a servic [source,options="nowrap"] ---- -[rhusar@ribera bin]$ ./jboss-cli.sh --output-json --connect "/subsystem=singleton/singleton-policy=default/deployment=ha-singleton-deployment.jar:read-attribute(name=primary-provider)" +[rhusar@ribera bin]$ ./jboss-cli.sh --output-json --connect "/subsystem=singleton/singleton-policy=default/deployment=ha-singleton-deployment.war:read-attribute(name=primary-provider)" { "outcome" : "success", "result" : "node1" @@ -213,9 +213,9 @@ $ mvn wildfly:deploy -Dwildfly.port=10090 [source,subs="+quotes,attributes+",options="nowrap"] ---- $ __{jbossHomeName}_1__/bin/jboss-cli.sh --connect -deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.jar --content=META-INF/singleton-deployment.xml=singleton-deployment.xml +deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.war --content=META-INF/singleton-deployment.xml=singleton-deployment.xml deployment-overlay redeploy-affected --name=singleton-deployment -$ __{jbossHomeName}_2__/bin/jboss-cli.sh --connect --controller=localhost:10090 deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.jar --content=META-INF/singleton-deployment.xml=singleton-deployment.xml deployment-overlay redeploy-affected --name=singleton-deployment +$ __{jbossHomeName}_2__/bin/jboss-cli.sh --connect --controller=localhost:10090 deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.war --content=META-INF/singleton-deployment.xml=singleton-deployment.xml deployment-overlay redeploy-affected --name=singleton-deployment ---- + NOTE: For Windows, use the ` __{jbossHomeName}_1__\bin\jboss-cli.bat` and ` __{jbossHomeName}_2__\bin\jboss-cli.bat` scripts. @@ -227,7 +227,7 @@ NOTE: For Windows, use the ` __{jbossHomeName}_1__\bin\jboss-cli.bat` and ` __{j - + ---- @@ -256,17 +256,8 @@ $ mvn wildfly:undeploy $ mvn wildfly:undeploy -Dwildfly.port=10090 ---- -// Run the Quickstart in Red Hat CodeReady Studio or Eclipse -include::../shared-doc/run-the-quickstart-in-jboss-developer-studio.adoc[leveloffset=+1] // Debug the Application include::../shared-doc/debug-the-application.adoc[leveloffset=+1] -//************************************************* -// Product Release content only -//************************************************* -ifdef::ProductRelease[] - // Quickstart not compatible with OpenShift include::../shared-doc/openshift-incompatibility.adoc[leveloffset=+1] - -endif::[] \ No newline at end of file diff --git a/ha-singleton-deployment/pom.xml b/ha-singleton-deployment/pom.xml index 3c76a9cdb4..0e74d6794b 100644 --- a/ha-singleton-deployment/pom.xml +++ b/ha-singleton-deployment/pom.xml @@ -37,7 +37,7 @@ ha-singleton-deployment 33.0.0.Beta1-SNAPSHOT - ejb + war Quickstart: HA Singleton Deployment This quickstart demonstrates the recommended way to deploy any service as a cluster-wide singleton. @@ -50,8 +50,13 @@ - - 32.0.0.Final + + 32.0.0.Final + + ${version.server} + 7.0.0.Final + 5.0.0.Final + 5.10.0 @@ -115,10 +120,15 @@ org.wildfly.bom wildfly-ee-with-tools - ${version.server.bom} + ${version.bom.ee} pom import + + org.junit.jupiter + junit-jupiter-engine + ${version.junit-jupiter} + @@ -126,12 +136,55 @@ jakarta.ejb jakarta.ejb-api + provided jakarta.annotation jakarta.annotation-api provided + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.wildfly.plugins + wildfly-maven-plugin + ${version.plugin.wildfly} + + + + + + + + integration-testing + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.2.1 + + + + integration-test + verify + + + + + + + + + diff --git a/ha-singleton-deployment/singleton-deployment-overlay-add.cli b/ha-singleton-deployment/singleton-deployment-overlay-add.cli index cc56b5f3e7..530836e69e 100644 --- a/ha-singleton-deployment/singleton-deployment-overlay-add.cli +++ b/ha-singleton-deployment/singleton-deployment-overlay-add.cli @@ -1,5 +1,5 @@ # Adds a deployment overlay for the quickstart deployment -deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.jar --content=META-INF/singleton-deployment.xml=singleton-deployment.xml +deployment-overlay add --name=singleton-deployment --deployments=ha-singleton-deployment.war --content=META-INF/singleton-deployment.xml=singleton-deployment.xml # Redeploys all deployments affected by the above change deployment-overlay redeploy-affected --name=singleton-deployment diff --git a/ha-singleton-deployment/src/main/webapp/index.html b/ha-singleton-deployment/src/main/webapp/index.html new file mode 100644 index 0000000000..2f46086485 --- /dev/null +++ b/ha-singleton-deployment/src/main/webapp/index.html @@ -0,0 +1,24 @@ + + + + ha-singleton-deployment Quickstart + + +

The ha-singleton-deployment quickstart deployed successfully. You can find the available operations in the included README file.

+ + \ No newline at end of file diff --git a/ha-singleton-deployment/src/test/java/org/wildfly/quickstarts/ha/singleton/BasicRuntimeIT.java b/ha-singleton-deployment/src/test/java/org/wildfly/quickstarts/ha/singleton/BasicRuntimeIT.java new file mode 100644 index 0000000000..6f85854dbb --- /dev/null +++ b/ha-singleton-deployment/src/test/java/org/wildfly/quickstarts/ha/singleton/BasicRuntimeIT.java @@ -0,0 +1,59 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2024, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * 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 org.wildfly.quickstarts.ha.singleton; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +/** + * The very basic runtime integration testing. + * + * @author Radoslav Husar + */ +public class BasicRuntimeIT { + + private static final String DEFAULT_SERVER_HOST = "http://localhost:8080/ha-singleton-deployment"; + + @Test + public void testHTTPEndpointIsAvailable() throws IOException, InterruptedException, URISyntaxException { + String serverHost = System.getenv("SERVER_HOST"); + if (serverHost == null) { + serverHost = System.getProperty("server.host"); + } + if (serverHost == null) { + serverHost = DEFAULT_SERVER_HOST; + } + final HttpRequest request = HttpRequest.newBuilder() + .uri(new URI(serverHost)) + .GET() + .build(); + final HttpClient client = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMinutes(1)) + .build(); + final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + Assertions.assertEquals(200, response.statusCode()); + } +}