Skip to content

Commit

Permalink
WFLY-18471 ha-singleton-deployment Quickstart Common Enhancements CY2…
Browse files Browse the repository at this point in the history
…023Q3

Synchronize properties definitions.
Convert the deployment to war from jar and introduce a welcome page via static index.html.
Introduce a simple integration test and -Pintegration-tests Maven profile.
Cleanup README file.
Introduce automatic CI for the quickstart.
  • Loading branch information
rhusar committed May 20, 2024
1 parent 3312dd7 commit a64b031
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 33 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/quickstart_ha-singleton-deployment_ci.yml
Original file line number Diff line number Diff line change
@@ -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
47 changes: 19 additions & 28 deletions ha-singleton-deployment/README-source.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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!
Expand All @@ -87,19 +87,19 @@ 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]
...
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:
Expand All @@ -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:
Expand All @@ -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.
Expand All @@ -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" => {
Expand All @@ -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"
Expand Down Expand Up @@ -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.
Expand All @@ -227,7 +227,7 @@ NOTE: For Windows, use the ` __{jbossHomeName}_1__\bin\jboss-cli.bat` and ` __{j
<deployment-overlays>
<deployment-overlay name="singleton-deployment">
<content path="META-INF/singleton-deployment.xml" content="60a35e2bb6a1886f0a4abe499c7af16833d2a533"/>
<deployment name="ha-singleton-deployment.jar"/>
<deployment name="ha-singleton-deployment.war"/>
</deployment-overlay>
</deployment-overlays>
----
Expand Down Expand Up @@ -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::[]
61 changes: 57 additions & 4 deletions ha-singleton-deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<artifactId>ha-singleton-deployment</artifactId>
<version>33.0.0.Beta1-SNAPSHOT</version>
<packaging>ejb</packaging>
<packaging>war</packaging>
<name>Quickstart: HA Singleton Deployment</name>
<description>This quickstart demonstrates the recommended way to deploy any service as a cluster-wide singleton.</description>

Expand All @@ -50,8 +50,13 @@
</licenses>

<properties>
<!-- The versions for BOMs, Dependencies and Plugins -->
<version.server.bom>32.0.0.Final</version.server.bom>
<!-- the version for the Server -->
<version.server>32.0.0.Final</version.server>
<!-- The versions for BOMs, Packs and Plugins -->
<version.bom.ee>${version.server}</version.bom.ee>
<version.pack.cloud>7.0.0.Final</version.pack.cloud>
<version.plugin.wildfly>5.0.0.Final</version.plugin.wildfly>
<version.junit-jupiter>5.10.0</version.junit-jupiter>
</properties>

<repositories>
Expand Down Expand Up @@ -115,23 +120,71 @@
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-ee-with-tools</artifactId>
<version>${version.server.bom}</version>
<version>${version.bom.ee}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${version.junit-jupiter}</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>jakarta.ejb</groupId>
<artifactId>jakarta.ejb-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<scope>provided</scope>
</dependency>

<!-- Tests -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.plugin.wildfly}</version>
</plugin>
</plugins>
</pluginManagement>
</build>

<profiles>
<profile>
<id>integration-testing</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions ha-singleton-deployment/src/main/webapp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
~ 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.
-->
<html>
<head>
<title>ha-singleton-deployment Quickstart</title>
</head>
<body>
<h1>The <code>ha-singleton-deployment</code> quickstart deployed successfully. You can find the available operations in the included README file.</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -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<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
Assertions.assertEquals(200, response.statusCode());
}
}

0 comments on commit a64b031

Please sign in to comment.