Practice key skills that were presented in this course.
| Resources | |
|---|---|
| Files |
/home/student/AD248/labs/compreview
|
| Application URL |
https://workstation:8443/kitchensink
|
Outcomes
You should be able to:
Install Red Hat JBoss Enterprise Application Platform (JBoss EAP) on the workstation, servera, and serverb machines.
Run a standalone server on the workstation machine, which acts as a load balancer.
Configure a managed domain that uses the three machines.
Configure the main subsystems to support a load balanced application, and other applications, running on the managed domain.
[student@workstation ~]$ lab start compreview
In this comprehensive review you install a high-available JBoss EAP environment on three different hosts: the workstation, the servera, and the serverb machines.
Then, you deploy the kitchensink.war application, which is a web application that connects to a MariaDB database.
The kitchensink.war application uses the following JakartaEE 8 technologies and APIs:
JSF
CDI
EJB
JPA
Bean Validation.
The following diagram shows the server architecture that you create during this lab.
![]() |
The environment is based on three virtual machines running Red Hat Enterprise Linux 9 (RHEL 9) with a minimal set of tools installed, including Java 11:
workstation machine (172.25.250.9)It is the only machine with a graphical interface.
It host the MariaDB database and JBoss EAP running a standalone server, and a domain controller.
The standalone server is responsible for load balancing requests for the kitchensink.war application.
servera machine (172.25.250.10)Machine for running multiple JBoss EAP managed instances.
serverb machine (172.25.250.11)Machine for running multiple JBoss EAP managed instances.
Instructions
Install JBoss EAP in the /opt/jboss-eap-7.4 directory.
The directory must be owned by the eap system user on each host.
In this step, you install JBoss EAP on each host from the classroom environment, and run JBoss EAP as a user with limited access to the OS environment.
The machines have the student user configured with sudo privileges.
The password for the student user is student.
You must install JBoss EAP with an answer file to automate the installation process on each host in a uniform way.
You can use the provided answer files available at /home/student/AD248/labs/compreview on each host.
Each host controller must use the same credentials: admin as the username, and redhat123 as the password.
Create an eap system user on the workstation machine to start and stop the JBoss EAP instances.
Create an eap system user on the servera machine to start and stop the JBoss EAP instances.
Create an eap system user on the serverb machine to start and stop the JBoss EAP instances.
Modify and customize the /home/student/AD248/labs/compreview/eap7-install.xml and /home/student/AD248/labs/compreview/eap7-install.xml.variables answer files.
The eap7-install.xml file configures the JBoss EAP location, and the login used to access the management console.
The eap7-install.xml.variables file is responsible for defining the password.
Use admin as the username, and redhat123 as the password.
Change the install path in the eap7-install.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<AutomatedInstallation langpack="eng">
<productName>EAP</productName>
<productVersion>7.4.0</productVersion>
<com.izforge.izpack.panels.HTMLLicencePanel id="HTMLLicencePanel"/>
<com.izforge.izpack.panels.TargetPanel id="DirectoryPanel">
<installpath>/opt/jboss-eap-7.4</installpath>
</com.izforge.izpack.panels.TargetPanel>
<com.izforge.izpack.panels.TreePacksPanel id="TreePacksPanel">
<pack index="0" name="Red Hat JBoss Enterprise Application Platform" selected="true"/>
...output omitted...Update the eap7-install.xml.variables file to:
adminPassword=redhat123Copy the answer files to the servera and serverb machines.
[student@workstation ~]$scp AD248/labs/compreview/eap7-install.xml* \ servera:/home/student/AD248/labs/compreview/...output omitted... eap7-install.xml ... eap7-install.xml.variables ... [student@workstation ~]$scp AD248/labs/compreview/eap7-install.xml* \ serverb:/home/student/AD248/labs/compreview/...output omitted... eap7-install.xml ... eap7-install.xml.variables ...
Run the JBoss EAP installer by using the answer files updated in the previous step.
You must install JBoss EAP as the root user to have permissions in the /opt directory.
The installer is in the /home/student/jboss-eap-7.4.0-installer.jar file.
Run the following command on the workstation machine:
[student@workstation ~]$sudo java -jar \/home/student/jboss-eap-7.4.0-installer.jar \/home/student/AD248/labs/compreview/eap7-install.xml \-variablefile /home/student/AD248/labs/compreview/eap7-install.xml.variables[ Starting automated installation ] ...output omitted... [ Automated installation done ]
Verify the JBoss EAP installation by running the following command:
[student@workstation ~]$ ls -la /opt/jboss-eap-7.4
total 532
drwxr-xr-x. 14 root root 4096 Nov 27 05:55 .
drwxr-xr-x. 3 root root 27 Nov 27 05:55 ..
drwxr-xr-x. 2 root root 6 Nov 27 05:55 .installation
drwxr-xr-x. 3 root root 28 Nov 27 05:55 .well-known
-rw-r--r--. 1 root root 419 Jun 23 2021 JBossEULA.txt
-rw-r--r--. 1 root root 26530 Jun 23 2021 LICENSE.txt
drwxr-xr-x. 3 root root 27 Nov 27 05:55 appclient
drwxr-xr-x. 4 root root 4096 Nov 27 05:55 bin
drwxr-xr-x. 5 root root 52 Nov 27 05:55 docs
drwxr-xr-x. 4 root root 38 Nov 27 05:55 domain
drwxr-xr-x. 2 root root 33 Nov 27 05:55 installation
-rw-r--r--. 1 root root 496975 Jun 23 2021 jboss-modules.jar
drwxr-xr-x. 3 root root 44 Nov 27 05:55 migration
drwxr-xr-x. 3 root root 20 Nov 27 05:55 modules
drwxr-xr-x. 6 root root 68 Nov 27 05:55 standalone
drwxr-xr-x. 2 root root 29 Nov 27 05:55 uninstaller
-rw-r--r--. 1 root root 65 Jun 23 2021 version.txt
drwxr-xr-x. 4 root root 158 Nov 27 05:55 welcome-contentInstall JBoss EAP on the servera machine.
Run the following command:
[student@workstation ~]$ssh root@servera java -jar \/home/student/jboss-eap-7.4.0-installer.jar \/home/student/AD248/labs/compreview/eap7-install.xml \-variablefile /home/student/AD248/labs/compreview/eap7-install.xml.variables[ Starting automated installation ] ...output omitted... [ Automated installation done ]
Verify the JBoss EAP installation in the servera machine.
Install JBoss EAP on the serverb machine.
[student@workstation ~]$ssh root@serverb java -jar \/home/student/jboss-eap-7.4.0-installer.jar \/home/student/AD248/labs/compreview/eap7-install.xml \-variablefile /home/student/AD248/labs/compreview/eap7-install.xml.variables[ Starting automated installation ] ...output omitted... [ Automated installation done ]
Verify the JBoss EAP installation on the serverb machine.
Apply the JBoss EAP 7.4.11 patch.
The jboss-eap-7.4.11-patch.zip file is present in the /home/student directory on each host.
Apply the patch on each host by running the following commands:
[student@workstation ~]$sudo /opt/jboss-eap-7.4/bin/jboss-cli.sh \--command="patch apply /home/student/jboss-eap-7.4.11-patch.zip"{ "outcome" : "success", "result" : {} } [student@workstation ~]$ssh root@servera "/opt/jboss-eap-7.4/bin/jboss-cli.sh \--command='patch apply /home/student/jboss-eap-7.4.11-patch.zip'"{ "outcome" : "success", "result" : {} } [student@workstation ~]$ssh root@serverb "/opt/jboss-eap-7.4/bin/jboss-cli.sh \--command='patch apply /home/student/jboss-eap-7.4.11-patch.zip'"{ "outcome" : "success", "result" : {} }
Update the owner of the JBoss EAP directory on each machine to the eap user.
[student@workstation ~]$sudo chown eap:eap -R /opt/jboss-eap-7.4[student@workstation ~]$ssh root@servera chown eap:eap -R /opt/jboss-eap-7.4[student@workstation ~]$ssh root@serverb chown eap:eap -R /opt/jboss-eap-7.4
Verify the owner by running the following command:
[student@workstation ~]$ls -ld /opt/jboss-eap-7.4drwxr-xr-x. 14eap eap4096 Nov 27 06:26 /opt/jboss-eap-7.4
Configure a standalone server in a different directory to act as a load balancer.
In this step you create and configure a JBoss EAP standalone instance to act as the load balancer.
The load balancer instance runs in the workstation machine.
Persist the changes to the configuration file by using the management CLI.
Use the following criteria to create the load balancer instance:
Table 13.1. Criteria for load balancer configuration
| Field | Value |
|---|---|
| Base directory |
/opt/standalone
|
| Directory owner |
eap
|
| Admin user |
admin
|
| Admin password |
redhat123
|
| JBoss EAP public interface |
172.25.250.9
|
| Port offset |
1000
|
| Configuration file |
standalone-load-balancer.xml
|
Copy the standalone directory from the JBoss EAP installation to /opt/standalone.
Change the owner to the eap user.
Start the JBoss EAP standalone server using the recently created directory.
Do not use the system variables to specify the port offset and the public interface, because you must persist their values to the standalone-load-balancer.xml configuration file by using the management CLI.
Update the port offset by using the management CLI.
In a new terminal on the workstation machine to start the management CLI as the eap user, and connect to the standalone server.
Update the port offset from the standalone server to 1000.
[standalone@localhost:9990 /]/socket-binding-group=standard-sockets:\write-attribute(name=port-offset,value=1000){ "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
Reload the server:
[standalone@localhost:9990 /] :reload
{
"outcome" => "success",
"result" => undefined
}After running the command, disconnect from the server because the administration port was changed.
Verify that the configuration was successfully set by accessing http://localhost:9080 from the web browser.
You get an HTTP 404 error because the standalone-load-balancer.xml configuration has no welcome page.
Update the public interface to make it available for external access.
The load balancer must be visible from an outside environment, via the eth0 interface.
However, the default configuration makes it visible only to the loopback interface.
Reload the server configuration to apply the changes.
Disconnect from the CLI to refresh the configuration.
To verify the previous step, navigate to http://172.25.250.9:9080 and verify that you get the 404 response.
Reopen the CLI session with the standalone server by running the following command from the same terminal window where CLI was exited.
Leave this terminal open.
From the CLI, run the following commands:
[standalone@localhost:10990 /]/interface=public:\write-attribute(name=inet-address,value=172.25.250.9){ "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
[standalone@localhost:10990 /] :reload
{
"outcome" => "success",
"result" => undefined
}[standalone@localhost:10990 /] exit[student@workstation bin]$sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \--connect --controller=localhost:10990[standalone@localhost:10990 /]
Configure the domain and host controllers in a custom directory location.
In this step, you configure and start the domain controller on the workstation machine.
Then, you install two host controllers on servera and serverb.
Configure the domain and the host controller on a different base directory from the initial installation process to keep the install directory clean.
Use /opt/domain as the base directory.
The eap user is the base directory owner.
Make all changes in the configuration file to minimize the need to change parameters during the start-up process.
Copy as root the base directory from the /opt/jboss-eap-7.4 install directory to the /opt/domain directory.
Then, change the owner of the directory to the eap user.
Copy the /opt/jboss-eap-7.4/domain base directory on the workstation machine to the /opt/domain directory.
This destination directory represents the domain controller configuration.
Change the owner of the /opt/domain directory to the eap user on the workstation machine.
Copy the /opt/jboss-eap-7.4/domain base directory on the servera machine to the /opt/domain directory.
Change the owner of the /opt/domain directory to the eap user on the servera machine.
Copy the /opt/jboss-eap-7.4/domain base directory on the serverb machine to the /opt/domain directory.
Change the owner of the /opt/domain directory to the eap user on the serverb machine.
Verify the controller on the workstation machine.
In this step, you verify that the domain controller starts on workstation.
To start a domain controller, run the domain.sh script from the JBOSS_HOME/bin directory, and point to the /opt/domain directory as the base directory.
The owner of the base directory is the eap user: start the controller by using the sudo -u command.
Use the host-master.xml configuration file to start this controller as a domain controller.
Run the following command to start a domain controller on the workstation machine:
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/domain.sh \-Djboss.domain.base.dir=/opt/domain --host-config=host-master.xml...output omitted... [Host Controller] 03:34:27,823 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0062: Http management interface listening on http://127.0.0.1:9990/management and https://127.0.0.1:-1/management [Host Controller] 03:34:27,824 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0053: Admin console listening on http://127.0.0.1:9990 and https://127.0.0.1:-1 [Host Controller] 03:34:27,859 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.4.11.GA (WildFly Core 15.0.26.Final-redhat-00001) (Host Controller) started in 3920ms - Started 80 of 81 services (22 services are lazy, passive or on-demand)
Configure network permissions for the domain and host controller from the managed domain.
The ports related to JBoss EAP management interfaces are already opened in the classroom environment, but you need to perform other low level configuration on the domain controller to support external connections from the host controllers.
The management interface from the domain controller only listens on the 127.0.0.1 loopback interface.
The secondary host controllers need to connect to the server using a public interface.
In this step you update the domain controller network configuration by using the management CLI.
Start the management CLI installed in the workstation machine at JBOSS_HOME/bin and connect to the local domain controller.
Start the CLI process as the eap user.
In a new terminal on the workstation machine, start the CLI as the eap user.
Connect to the domain controller started at localhost.
Run the following command from the workstation machine:
[student@workstation ~]$ sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /][disconnected /] connect localhost:9990
[domain@localhost:9990 /]Update the domain controller management interface IP address by using the CLI.
Recall that the domain controller name is master and the IP address from workstation is 172.25.250.9.
Reload the host controller to activate the IP address changes.
The management CLI cannot reach the management interface after changing its IP address.
Connect the servera host controller to use the domain controller.
Configure the JBoss EAP installation on the servera machine to be a host controller in a managed domain.
The host controller must point to the domain controller on the workstation machine.
All the servers managed by the host controller must be accessible externally.
Therefore, the public interface must point to the external interface, not the loopback interface.
The host controller from servera machine has the following characteristics:
| Field | Value |
|---|---|
| Host controller name |
servera
|
Host controller IP address (public interface)
|
172.25.250.10
|
Domain controller IP address
|
172.25.250.9
|
| Configuration file |
host-slave.xml
|
To prevent unknown hosts from connecting to the domain controller, you must create a management user by using the add-user.sh script.
Use the following parameters when creating a the management user:
| Field | Value |
|---|---|
Domain configuration (-dc) |
/opt/domain/configuration
|
login
|
jbossmgmt
|
password
|
redhat123
|
What type of user do you wish to add?
|
a) Management User (mgmt-users.properties)
|
Is this new user going to be used for one AS process to connect to another AS process?
|
yes
|
You must add these credentials to the /opt/domain/configuration directory, and you must execute the add-user.sh as the eap user.
Finally, remove the default servers associated with this host controller, because you create new ones later.
Create the management user with the add-user.sh script from the workstation machine as the eap user to update the mgmt-users.properties file.
Take note of the resulting XML content.
From the workstation machine, open a new terminal window, and run the following command:
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/add-user.sh \-dc /opt/domain/configurationWhat type of user do you wish to add? a) Management User (mgmt-users.properties) b) Application User (application-users.properties)(a):Enter the details of the new user to add. Using realm 'ManagementRealm' as discovered from the existing property files. Username :jbossmgmtPassword recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file. - The password should be different from the username - The password should not be one of the following restricted values {root, admin, administrator} - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s) Password : WFLYDM0102: Password should have at least 1 non-alphanumeric symbol. Are you sure you want to use the password entered yes/no?yesRe-enter Password : What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[ ]: About to add user 'jbossmgmt' for realm 'ManagementRealm' Is this correct yes/no?yesAdded user 'jbossmgmt' to file '/opt/domain/configuration/mgmt-users.properties' Added user 'jbossmgmt' with groups to file '/opt/domain/configuration/mgmt-groups.properties' Is this new user going to be used for one AS process to connect to another AS process? e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server Jakarta Enterprise Beans calls. yes/no?yesTo represent the user add the following to the server-identities definition<secret value="cmVkaGF0MTIz" />
As the eap user, edit the /opt/domain/configuration/host-slave.xml file on the servera machine and add the host name, the authentication data, the primary controller IP address, and the host controller IP address.
...output omitted... <hostname="servera"xmlns="urn:jboss:domain:16.0"> <management> <security-realms> <security-realm name="ManagementRealm"> <server-identities> <secret value=""/> </server-identities> ...output omitted... <domain-controller> <remotecmVkaGF0MTIzusername="jbossmgmt"security-realm="ManagementRealm"> <discovery-options> <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote+http}" host="${jboss.domain.master.address:172.25.250.9}" port="${jboss.domain.master.port:9990}"/> ...output omitted... <interface name="public"> <inet-address value="${jboss.bind.address:172.25.250.10}"/> </interface>
Start the JBoss EAP host controller from the servera machine using /opt/domain as the base directory.
Verify that the servera host controller connects to the domain controller by checking the logs from the domain controller terminal window.
Verify that the servers are available via the public interface. Using a web browser, open the following URLs and verify that the JBoss EAP welcome pages show:
http://172.25.250.10:8080
http://172.25.250.10:8230
Connect to the management CLI.
In the CLI terminal window, stop the servers running on the host controller servera to remove them.
Remove the server-one instance from the servera host controller.
Remove the server-two instance from the servera host controller.
Connect the host controller running on the serverb machine to the domain controller.
The JBoss EAP installation on the serverb machine is the second host controller of a managed domain.
The host controller must point to the domain controller on the workstation machine.
All the servers managed by the host controller must be accessible externally.
Therefore, the public interface must point to the external interface, not the loopback interface.
The host controller from serverb machine has the following characteristics:
| Field | Value |
|---|---|
Domain configuration (-dc) |
/opt/domain/configuration
|
| Host controller name |
serverb
|
| Management user |
jbossmgmt
|
| Management user password |
redhat123
|
Host controller IP address (public interface)
|
172.25.250.11
|
Domain controller IP address
|
172.25.250.9
|
| Configuration file |
host-slave.xml
|
To prevent unknown hosts from connecting to the domain controller, use the management user created in the previous step.
Finally, remove the instance servers associated with this server.
As the eap user, edit the host-slave.xml file on the serverb machine and add the host name, the authentication data, the primary controller IP address, and the host controller IP address.
...output omitted... <hostname="serverb"xmlns="urn:jboss:domain:16.0"> <management> <security-realms> <security-realm name="ManagementRealm"> <server-identities> <secret value=""/> </server-identities> ...output omitted... <domain-controller> <remotecmVkaGF0MTIzusername="jbossmgmt"security-realm="ManagementRealm"> <discovery-options> <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote+http}" host="${jboss.domain.master.address:172.25.250.9}" port="${jboss.domain.master.port:9990}"/> ...output omitted... <interface name="public"> <inet-address value="${jboss.bind.address:172.25.250.11}"/> </interface>
Start the JBoss EAP host controller from the serverb machine using /opt/domain as the base directory.
Verify that the serverb host controller connects to the domain controller by checking the logs from the domain controller terminal window.
Verify that the servers are available via the public interface. Using a web browser, open the following URLs and verify that the JBoss EAP welcome pages show:
http://172.25.250.11:8080
http://172.25.250.11:8230
In the CLI terminal window, stop the servers running on the host controller serverb to remove them.
Remove the server-one instance from the serverb host controller.
Remove the server-two instance from the serverb host controller.
Customize the server groups to support a high availability environment.
The default server groups provided by JBoss EAP are focused on testing.
In an actual production environment you must address high availability concerns, and avoid downtime of a critical application.
In this step, you remove the main-server-group and other-server-group, and create two server groups with the same profile.
Use the following configuration for the server groups:
First server group characteristics:
| Field | Value |
|---|---|
| Server group name |
Group1
|
| Profile |
full-ha
|
| Socket binding configuration |
full-ha-sockets
|
Second server group characteristics:
| Field | Value |
|---|---|
| Server group name |
Group2
|
| Profile |
full-ha
|
| Socket binding configuration |
full-ha-sockets
|
Remove the server group named main-server-group from the domain controller.
Remove the server group named other-server-group from the domain controller.
Create a Group1 server group on the domain controller.
Create a Group2 server group on the domain controller.
Reload the configuration from the servera host controller to update the servers.
Reload the configuration from the serverb host controller to update the servers.
Reload the configuration from the domain controller to update the servers.
Create servers on the servera host controller.
In this step, you create two servers on the servera host controller.
Associate the two servers with the server groups created in the previous step.
Recall that all new servers are not started automatically by default.
The servers run on the servera machine with the following characteristics:
First server:
| Field | Value |
|---|---|
| Name |
servera.1
|
| Server group |
Group1
|
| Socket binding port offset | None (Leave at default value of 0) |
| Auto start |
true
|
Second server:
| Field | Value |
|---|---|
| Name |
servera.2
|
| Server group |
Group2
|
| Socket binding port offset |
150
|
| Auto start |
true
|
Configure the servera.1 on servera.
Configure the servera.2 on servera.
Start servera.1.
Start servera.2.
Verify that the servers are running and accessible with a web browser from the workstation machine.
Use the following addresses:
http://172.25.250.10:8080
http://172.25.250.10:8230
Create servers on the serverb host controller.
In this step, you create two servers on the serverb host controller.
Create the two servers associated with the server groups that you created in the previous step.
Recall that all new servers are not started automatically by default.
The servers must use the following characteristics:
First server:
| Field | Value |
|---|---|
| Name |
serverb.1
|
| Server group |
Group1
|
| Socket binding port offset | None (Leave at default value of 0) |
| Auto start |
true
|
Second server:
| Field | Value |
|---|---|
| Name |
serverb.2
|
| Server group |
Group2
|
| Socket binding port offset |
150
|
| Auto start |
true
|
Configure the serverb.1 on serverb.
Configure the serverb.2 on serverb.
Start serverb.1 and serverb.2.
Verify that the servers are running and accessible with a web browser from the workstation machine.
Use the following addresses:
http://172.25.250.11:8080
http://172.25.250.11:8230
Install the MariaDB JDBC driver as a JBoss EAP module, configure the driver in the subsystem, and create two data sources.
The following applications require that you create a data source:
The kitchensink.war application stores a list of members in a database by using common JakartaEE APIs.
The database name is kitchensink.
The example.war application checks user names and passwords stored at the bksecurity MariaDB database.
In this step, you install the JDBC driver as a JBoss EAP module.
The database vendor is responsible for providing the JDBC drivers to the database system.
The MariaDB data source JDBC driver file is present on all machines at the /tmp directory.
The following is the list of the MariaDB JDBC driver dependencies:
javaee.api
sun.jdk
ibm
jdk
javax.api
javax.transaction.api
The driver must have a unique name.
Usually, the driver vendor ID is used, and for MariaDB it is the reverse address name com.mariadb.
Install the module by using a disconnected CLI session on each host in the managed domain.
Recall that the module is installed in the same directory where JBoss EAP is installed, and the command must be run as the eap user.
Start a disconnected CLI session on the workstation machine.
Add the module to the domain controller.
Exit the CLI window.
Repeat the command on servera to create a module for the MariaDB JDBC driver.
Note that you must use single quotes to quote the complete command you are sending to servera over ssh.
You can ignore the warning about the home directory, because we created the user without any home directory.
[student@workstation ~]$ ssh eap@servera \
'/opt/jboss-eap-7.4/bin/jboss-cli.sh \
--command="module add --name=com.mariadb \
--resources=/tmp/mariadb-java-client-3.2.0.jar \
--dependencies=javaee.api,sun.jdk,ibm.jdk,javax.api,javax.transaction.api"'
Could not chdir to home directory /home/eap: No such file or directoryRepeat the command on serverb to create a module for the MariaDB JDBC driver.
[student@workstation ~]$ ssh eap@serverb \
'/opt/jboss-eap-7.4/bin/jboss-cli.sh \
--command="module add --name=com.mariadb \
--resources=/tmp/mariadb-java-client-3.2.0.jar \
--dependencies=javaee.api,sun.jdk,ibm.jdk,javax.api,javax.transaction.api"'
Could not chdir to home directory /home/eap: No such file or directoryCreate a reference in the domain controller to the module recently installed.
Add the driver to the data source subsystem of the full-ha profile.
Use mariadb as the driver name.
Recall that the module name is com.mariadb.
Use the CLI open and connected to the domain controller to configure the module.
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=datasources/\jdbc-driver=mariadb:add(driver-name=mariadb,driver-module-name=com.mariadb){ "outcome" => "success", "result" => undefined, "server-groups" => { "Group1" => {"host" => { ...output omitted...
Make sure the driver was installed by running the following command:
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=datasources/\jdbc-driver=mariadb:read-resource{ "outcome" => "success", "result" => { "deployment-name" => undefined, "driver-class-name" => undefined, "driver-datasource-class-name" => undefined, "driver-major-version" => undefined, "driver-minor-version" => undefined, "driver-module-name" =>"com.mariadb", "driver-name" =>"mariadb", "driver-xa-datasource-class-name" => undefined, "jdbc-compliant" => undefined, "module-slot" => undefined, "profile" => undefined, "xa-datasource-class" => undefined } }
Configure the data source to access the kitchensink.war application database.
The following are the parameters for the kitchensink data source:
| Field | Value |
|---|---|
| Profile |
full-ha
|
Name
|
kitchensink
|
Datasouce type
|
Non-XA
|
JNDI Name
|
java:jboss/datasources/KitchensinkQuickstartDS
|
Driver Name
|
mariadb
|
Connection URL
|
jdbc:mariadb://172.25.250.9:3306/kitchensink
|
Username
|
dbadmin
|
Password
|
redhat123
|
The /tmp/kitchensink-ds.cli file contains the full command to minimize typing.
To create the data source, run the following command:
The resulting content for the file should be:
data-source add --profile=full-ha --name=KitchensinkQuickstartDS \ --driver-name=mariadb --jndi-name=java:jboss/datasources/KitchensinkQuickstartDS \ --connection-url=jdbc:MariaDB://172.25.250.9:3306/kitchensink \ --user-name=dbadmin --password=redhat123
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \--connect --controller=172.25.250.9:9990 \--file="/tmp/kitchensink-ds.cli"[student@workstation ~]$
Verify that the data source works.
Configure the data source to access the example application database.
The following are the parameters for the bksecurity data source:
| Field | Value |
|---|---|
| Profile |
full-ha
|
Name
|
bksecurity
|
Datasouce type
|
Non-XA
|
JNDI Name
|
java:jboss/datasources/bksecurity-ds
|
Driver Name
|
mariadb
|
Connection URL
|
jdbc:mariadb://172.25.250.9:3306/bksecurity
|
Username
|
dbadmin
|
Password
|
redhat123
|
The /tmp/bksecurity-ds.cli file contains the full command to minimize typing.
The resulting content is:
data-source add --profile=full-ha --name=bksecurity --driver-name=mariadb \ --jndi-name=java:jboss/datasources/bksecurity-ds \ --connection-url=jdbc:mariadb://172.25.250.9:3306/bksecurity \ --user-name=dbadmin --password=redhat123
To create the data source, run the following command from a workstation terminal window:
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \--connect --controller=172.25.250.9:9990 \--file="/tmp/bksecurity-ds.cli"
Verify that the data source works.
Configure the logging subsystem to store the logs in a customized directory.
Each server must store the log files at /var/log/jboss.
Create the /var/log/jboss directory on each host machine, change the owner to the eap user.
Recall that in order to point to a directory different from the base directory, you must create a path element in the configuration files.
To minimize the amount of data generated by logging, you must use a size rotating file handler.
The file handler must have a maximum 1 MB size, and a maximum of five files.
You must name the handler as KITCHENSINK_LOG_HANDLER, and set its level to DEBUG.
Create a category to capture logs from the org.jboss.as.quickstarts.kitchensink Java package by using the previous KITCHENSINK_LOG_HANDLER.
Create the /var/log/jboss directories on each host machine.
Change the ownership to the eap user:
Create a new path called custom.log.dir pointing to /var/log/jboss.
Configure a KITCHENSINK_LOG_HANDLER handler, which uses the custom.log.dir path created in the previous step.
Use the following specifications:
Log file name: kitchensink.log
It should be enabled.
All the logs should be appended to kitchensink.log, and not deleted.
All the contents stored in the file buffer should be auto-flushed.
Each log file should have a maximum size of 1 MB.
The maximum number of files for the log should be five. Any extra files needed should overwrite the oldest file created.
All logs less critical than DEBUG should be written to the file.
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=logging/\size-rotating-file-handler=KITCHENSINK_LOG_HANDLER:add\(file={"relative-to"=>"custom.log.dir",\"path"=>"${jboss.server.name}/kitchensink.log"}, \enabled=true, append=true, autoflush=true, rotate-size=1m, \max-backup-index=5,level=DEBUG){ "outcome" => "success", "result" => undefined, "server-groups" => { "Group1" => {"host" => { "servera" => {"servera.1" => {"response" => { ...output omitted...
Create a category to capture only log messages from the kitchensink.war application.
Determine if the /var/log/jboss directory on servera and serverb have directories representing each server instance with a kitchensink.log file.
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=logging/\logger=com.redhat.training:add\(category=org.jboss.as.quickstarts.kitchensink,level=DEBUG,\handlers=["KITCHENSINK_LOG_HANDLER"]){ "outcome" => "success", "result" => undefined, "server-groups" => { "Group1" => {"host" => { "servera" => {"servera.1" => {"response" => { ...output omitted...
[student@workstation ~]$ ssh root@servera tree /var/log/jboss/
/var/log/jboss/
├── servera.1
│ └── kitchensink.log
└── servera.2
└── kitchensink.log
2 directories, 2 filesCustomize the messaging subsystem to create queues and customize an in-vm connection factory.
You must update the messaging subsystem to support a message queue with a dead letter queue for failed messages.
Also, you must associate an expiry queue with the same queue in the case that the message is not consumed after a certain amount of time.
The queue receives messages from a mdb-client.war application.
You must deploy this application.
Finally, you deploy a message-driven bean (MDB) running on a helloworld-mdb.jar application, which consumes the messages.
Use the following characteristics to create the described messaging elements in the full-ha profile:
A new connection factory published at java:/jms/CustomCF, which uses an in-vm connector.
A TestQueue message queue bound to the java:/jms/queue/AD248TestQueue JNDI name.
A TestDLQ message queue, which you must bind to the java:/jms/AD248TestDLQ JNDI name.
This queue is the dead letter queue (DLQ) that stores the failed messages at TestQueue.
A TestExpiry message queue, which you must bind to the java:/jms/AD248TestExpiry JNDI name.
This queue is the expiry queue that stores all the messages stored at TestQueue that are not consumed in five minutes.
Remember that the queue address used to bind a queue is different from the queue address used to create a queue.
Deploy the message queues.
[domain@172.25.250.9:9990 /]cd /profile=full-ha/\ subsystem=messaging-activemq/server=default[domain@172.25.250.9:9990 server=default]./jms-queue=TestQueue:add(\ entries=[java:/jms/queue/AD248TestQueue])...output omitted... "outcome" => "success", ...output omitted... [domain@172.25.250.9:9990 server=default]./jms-queue=TestExpiry:add(\ entries=[java:/jms/AD248TestExpiry])...output omitted... "outcome" => "success", ...output omitted... [domain@172.25.250.9:9990 server=default]./jms-queue=TestDLQ:add(\ entries=[java:/jms/AD248TestDLQ])...output omitted... "outcome" => "success", ...output omitted...
Identify the TestQueue address in the servera.1 instance.
By default, the queue address is the same among servers running on the same server group.
This queue address is used to configure the default dead letter and the default expiry queues.
Identify the TestDLQ address in the servera.1 instance.
By default, the queue address is the same among servers running on the same server group.
This queue address is used to bind the TestDLQ with TestQueue as a dead letter queue.
Identify the TestExpiry address in the servera.1 instance.
By default, the queue address is the same among servers running on the same server group.
This queue address is used to bind the TestExpiry with TestQueue as an expiry queue.
Bind the dead letter queue and the expiry queue to TestQueue to capture messages with the following parameters:
expiry-delay=300000 to wait for five minutes before expiring messages.
max-delivery-attempts=1 to send messages to the dead-letter queue after one delivery attempt.
[domain@172.25.250.9:9990 server=default] ./address-setting=\
jms.queue.TestQueue:add(expiry-address=jms.queue.TestExpiry,\
dead-letter-address=jms.queue.TestDLQ,\
expiry-delay=300000,max-delivery-attempts=1)
{
"outcome" => "success",
"result" => undefined,
"server-groups" => {
"Group1" => {"host" => {
"servera" => {"servera.1" => {"response" => {
"outcome" => "success",
...output omitted...Create a ConnectionFactory that uses an in-vm connector under the full-ha profile.
Use java:/jms/CustomCF as JNDI name.
[domain@172.25.250.9:9990 server=default] ./pooled-connection-factory=custom:add\
(connectors=[in-vm], entries=[java:/jms/CustomCF])
{
"outcome" => "success",
"result" => undefined,
"server-groups" => {
"Group1" => {"host" => {
"servera" => {"servera.1" => {"response" => {
"outcome" => "success",
...output omitted...Deploy the mdb-client.war application on the Group1 server group to verify that the messaging subsystem is correct.
Send a message to the queue by using curl, and the http://172.25.250.10:8080/mdb-client/queue endpoint with the following parameters:
count=1
label=first
message=test message body
Verify that the message is in the queue, but it is not consumed.
Deploy the helloworld-mdb.jar, which consumes the messages from TestQueue.
Verify that the message is not in the queue.
Enforce the managed domain security by encrypting passwords, disabling local automatic authentication, and creating a security domain connected to a database.
Any attempt to connect to the domain controller or to the standalone server using a management CLI does not request a password if the session is opened locally on the workstation machine.
However, this is not a secure behavior and you must change it to avoid malicious access.
In this step, you change the security configuration to require the admin user and the redhat123 password to access the domain controller or the standalone server .
Then, you create a vault to store the password for the bksecurity-ds data source.
Finally, you create a legacy security domain connected to the bksecurity database.
The example.war application uses this legacy security domain to authenticate its users.
Recall that the standalone server management interface is available via loopback interface only, and the administration port is 10990 to avoid port collision with the domain controller.
Remove the local authentication from the management realm.
The management realm is under the core-services node level, under the security realm service.
Reload the server and connect again to the management CLI.
Now the standalone server asks for authentication.
Use admin/redhat123 as the credentials.
Connect to the standalone server by using the following command line from the workstation machine:
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \--connect \--controller=localhost:10990
Run the following command to disable the standalone server local authentication:
[standalone@localhost:10990 /]/core-service=management/\security-realm=ManagementRealm/authentication=local:remove(){ "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
[standalone@localhost:10990 /] reload
Authenticating against security realm: ManagementRealm
Username: admin
Password:
[standalone@localhost:10990 /]Use the opened CLI session to remove the local authentication from the domain controller.
Remove the local authentication from the management realm.
The management realm is under the core-services node level, under the security realm service.
Reload the master host, and connect the CLI again to the domain controller.
Now the domain controller asks for credentials.
Run the following command to disable the domain controller local authentication:
[domain@172.25.250.9:9990 /]/host=master/core-service=management\ /security-realm=ManagementRealm/authentication=local:remove(){ "outcome" => "success", "result" => undefined, "server-groups" => undefined, "response-headers" => {"process-state" => "reload-required"} } [domain@172.25.250.9:9990 /]reload --host=masterAuthenticating against security realm: ManagementRealm Username: admin Password: [domain@172.25.250.9:9990 /]
Create a vault to store encrypted passwords.
The vault is a keystore generated by the keytool utility from the Java Development Kit (JDK).
You can manage the vault by using the JBOSS_HOME/bin/vault.sh utility.
Save the vault files in the /opt/domain directory with key.store as the name of the main file.
You can use the /tmp/keystore-vault.sh to create the keystore vault:
[student@workstation ~]$ sudo /tmp/keystore-vault.sh
Warning:
The JCEKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore /opt/domain/key.store -destkeystore /opt/domain/key.store -deststoretype pkcs12".You can safely ignore the warning.
Create a parameter to hold the password for the kitchensink.war data source.
The following parameters should be used to run the vault.sh script, which must run as the eap user.
Table 13.2. Criteria for Vault configuration in JBoss EAP
| Field | Value |
|---|---|
Keystore file name
|
/opt/domain/key.store
|
Keystore password
|
redhat123
|
alias
|
Vault
|
vault block
|
bk-vb
|
Attribute
|
kitchensink-password
|
Value
|
redhat123
|
Encrypt directory
|
/opt/domain/vault
|
iteration
|
95
|
salt
|
ABCD1234
|
Copy the resulting management CLI command for domain mode.
You use this command to update the host-slave.xml files on each host controller in next steps.
Additionally, take note of the content right below the Configuration should be done as follows:.
This string refers to the password for the KitchensinkQuickstartDS data source.
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/vault.sh \--keystore /opt/domain/key.store \--keystore-password redhat123 --alias Vault \--vault-block bk-vb --attribute kitchensink-password \--sec-attr redhat123 --enc-dir /opt/domain/vault --iteration 95 --salt ABCD1234...output omitted... Dec 12, 2023 7:15:41 AM org.picketbox.plugins.vault.PicketBoxSecurityVault init INFO: PBOX00361: Default Security Vault Implementation Initialized and Ready WFLYSEC0047: Secured attribute value has been stored in Vault. Please make note of the following: ******************************************** Vault Block:bk-vb Attribute Name:kitchensink-passwordConfiguration should be done as follows:VAULT::bk-vb::kitchensink-password::1 ******************************************** WFLYSEC0048: Vault Configuration commands in WildFly for CLI: ******************************************** For standalone mode: /core-service=vault:add(vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")]) ******************************************** For domain mode: /host=the_host/core-service=vault:add(vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")]) ********************************************
Create one parameter to hold the password from the bksecurity-ds data source.
The following parameters should be used to run the vault.sh script.
| Field | Value |
|---|---|
Keystore file name
|
/opt/domain/key.store
|
Keystore password
|
redhat123
|
alias
|
Vault
|
Vault block
|
realm-vb
|
Attribute
|
bksecurity-password
|
value
|
redhat123
|
Encrypt directory
|
/opt/domain/vault
|
iteration
|
95
|
salt
|
ABCD1234
|
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/vault.sh \--keystore /opt/domain/key.store \--keystore-password redhat123 --alias Vault --vault-block realm-vb \--attribute bksecurity-password \--sec-attr redhat123 --enc-dir /opt/domain/vault --iteration 95 --salt ABCD1234...output omitted... Dec 12, 2023 7:21:39 AM org.picketbox.plugins.vault.PicketBoxSecurityVault init INFO: PBOX00361: Default Security Vault Implementation Initialized and Ready WFLYSEC0047: Secured attribute value has been stored in Vault. Please make note of the following: ******************************************** Vault Block:realm-vb Attribute Name:bksecurity-password Configuration should be done as follows: VAULT::realm-vb::bksecurity-password::1 ******************************************** WFLYSEC0048: Vault Configuration commands in WildFly for CLI: ******************************************** For standalone mode: /core-service=vault:add(vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")]) ******************************************** For domain mode: /host=the_host/core-service=vault:add(vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")])
Notice that most of the parameters from the previous command are the same, except for the vault block, attribute, and value.
Take note of the content right below the Configuration should be done as follows:.
This string will be used to refer to the password from the example app.
Transfer the key.store and the vault file to other servers by using scp.
Transfer the files as root.
Change the owner of these files to eap.
[student@workstation ~]$scp /opt/domain/key.store root@servera:/opt/domain/[student@workstation ~]$scp -r /opt/domain/vault root@servera:/opt/domain/
[student@workstation ~]$scp /opt/domain/key.store root@serverb:/opt/domain/[student@workstation ~]$scp -r /opt/domain/vault root@serverb:/opt/domain/
[student@workstation ~]$ssh root@servera chown eap:eap /opt/domain/*[student@workstation ~]$ssh root@serverb chown eap:eap /opt/domain/*
Configure the vault in each host controller by using the management CLI.
Add the vault by using the following commands returned in the previous step, and adapted for each host controller:
[domain@172.25.250.9:9990 /]/host=master/core-service=vault:add(\ vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),\ ("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),\ ("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),\ ("ITERATION_COUNT" => "95"),\ ("ENC_FILE_DIR" => "/opt/domain/vault/")]){ "outcome" => "success", "result" => undefined, "server-groups" => undefined } [domain@172.25.250.9:9990 /]/host=servera/core-service=vault:add(\ vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),\ ("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),\ ("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),\ ("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")]){ "outcome" => "success", "result" => undefined, "server-groups" => undefined } [domain@172.25.250.9:9990 /]/host=serverb/core-service=vault:add(\ vault-options=[("KEYSTORE_URL" => "/opt/domain/key.store"),\ ("KEYSTORE_PASSWORD" => "MASK-3jXLkNAhMsV0gujJ5u0WCx"),\ ("KEYSTORE_ALIAS" => "Vault"),("SALT" => "ABCD1234"),\ ("ITERATION_COUNT" => "95"),("ENC_FILE_DIR" => "/opt/domain/vault/")]){ "outcome" => "success", "result" => undefined, "server-groups" => undefined }
Restart the servers.
Update the password from the data sources in the full-ha profile by substituting the plain text password with the vault reference mentioned in the vault.sh output.
From the CLI window accessing the domain controller:
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=datasources/\data-source=KitchensinkQuickstartDS:\write-attribute(name=password,\value=${VAULT::realm-vb::bksecurity-password::1}){ "outcome" => "success", "result" => undefined, "server-groups" => { "Group1" => {"host" => { "servera" => {"servera.1" => {"response" => { "outcome" => "success", "result" => undefined }}}, "serverb" => {"serverb.1" => {"response" => { "outcome" => "success", "result" => undefined }}} }}, "Group2" => {"host" => { "servera" => {"servera.2" => {"response" => { "outcome" => "success", "result" => undefined }}}, "serverb" => {"serverb.2" => {"response" => { "outcome" => "success", "result" => undefined }}} }} } }
Restart the host controllers and the domain controller.
Prepare the servers to run by using the -Djboss.bind.address.private IP addresses for the servera and serverb host controllers and servers.
Stop the three host controllers by pressing Ctrl+C in each terminal. Start the domain again:
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/domain.sh \-Djboss.domain.base.dir=/opt/domain \--host-config=host-master.xml
[student@workstation ~]$ssh -t eap@servera /opt/jboss-eap-7.4/bin/domain.sh \-Djboss.domain.base.dir=/opt/domain \-Djboss.bind.address.private=172.25.250.10 \--host-config=host-slave.xml
[student@workstation ~]$ssh -t eap@serverb /opt/jboss-eap-7.4/bin/domain.sh \-Djboss.domain.base.dir=/opt/domain \-Djboss.bind.address.private=172.25.250.11 \--host-config=host-slave.xml
Verify that the modified data source connection works.
Create a security realm that uses the bksecurity data source.
The example.war application requires authentication, and it is bound to a bksecurity security domain in its jboss-web.xml and web.xml configuration files.
The username is admin, and the password is admin.
This password is encrypted in the users table from the bksecurity database, and it must use the SHA-256 hash algorithm and a base64 hash encoding.
The roles can be obtained from the roles table.
This table has a username column to identify the roles of a username.
Use the provided /tmp/bksecurity-domain.cli file to provide the parameters, and avoid typing errors.
Use the following parameters and create the security domain on the full-ha profile:
| Field | Value |
|---|---|
| Security domain name |
bksecurity
|
| Login module configuration flag |
required
|
| Login module configuration code |
Database
|
Configuration option dsJndiName
|
java:jboss/datasources/bksecurity-ds
|
Configuration option principalsQuery
|
SELECT password FROM users WHERE username = ?
|
Configuration option rolesQuery
|
SELECT role, "ROLES" FROM roles WHERE username = ?
|
Configuration option hashAlgorithm
|
sha-256
|
Configuration option hashEncoding
|
base64
|
/profile=full-ha/subsystem=security/security-domain=bksecurity:add()
/profile=full-ha/subsystem=security/security-domain=bksecurity/authentication=classic:add(login-modules=[{"code"=>"Database", "flag"=>"required", "module-options"=>[("dsJndiName"=>"java:jboss/datasources/bksecurity-ds"),("principalsQuery"=>"SELECT password FROM users WHERE username = ?"), ("rolesQuery"=>"SELECT role, 'ROLES' FROM roles WHERE username = ?"),("hashAlgorithm"=>"SHA-256"),("hashEncoding"=>"base64")]}])To start the CLI, use the following command from a terminal window in the workstation machine.
[student@workstation ~]$ sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \
--connect --user=admin --password=redhat123 --controller=172.25.250.9:9990 \
--file="/tmp/bksecurity-domain.cli"
{
"outcome" => "success",
"result" => undefined,
"server-groups" => {
"Group1" => {"host" => {
"servera" => {"servera.1" => {"response" => {
"outcome" => "success",
"result" => undefined,
"response-headers" => {
"operation-requires-reload" => true,
"process-state" => "reload-required"
}
}}},
...output omitted...
}}}
}},
"Group2" => {"host" => {
...output omitted...
}}}
}}
}
}Reload the servers to allow the changes to take place:
[domain@172.25.250.9:9990 /] :reload-servers
{
"outcome" => "success",
"result" => undefined,
"server-groups" => undefined
}Deploy the /tmp/example.war application to the Group1 server group.
Use admin/admin as the credentials to access the application page at http://172.25.250.10:8080/example.
Update the amount of memory allocated for all the server groups.
Change the amount of memory allocated to the heap for each server to 256 MB minimum and 512 MB maximum. To change memory settings, update the memory configuration for each server group, instead of changing individually. Additionally, create a default JVM configuration for the server group.
Reload the servers to activate the changes.
[domain@172.25.250.9:9990 /]/server-group=Group1/\jvm=default:add(heap-size=256m,max-heap-size=512m){ "outcome" => "success", "result" => undefined, "server-groups" => {"Group1" => {"host" => { "servera" => {"servera.1" => {"response" => { "outcome" => "success", "result" => undefined, "response-headers" => { "operation-requires-restart" => true, "process-state" => "restart-required" } }}}, "serverb" => {"serverb.1" => {"response" => { "outcome" => "success", "result" => undefined, "response-headers" => { "operation-requires-restart" => true, "process-state" => "restart-required" } }}} }}} } [domain@172.25.250.9:9990 /]/server-group=Group2/\jvm=default:add(heap-size=256m,max-heap-size=512m){ "outcome" => "success", "result" => undefined, "server-groups" => {"Group2" => {"host" => { "servera" => {"servera.2" => {"response" => { "outcome" => "success", "result" => undefined, "response-headers" => { "operation-requires-restart" => true, "process-state" => "restart-required" } }}}, "serverb" => {"serverb.2" => {"response" => { "outcome" => "success", "result" => undefined, "response-headers" => { "operation-requires-restart" => true, "process-state" => "restart-required" } }}} }}} }
[domain@172.25.250.9:9990 /]reload --restart-servers=true --host=servera[domain@172.25.250.9:9990 /]reload --restart-servers=true --host=serverb
Customize the root application on the servers.
Change the default welcome page in all server groups.
Use the /tmp/welcome.war file.
Remove the default web module.
Update the welcome web module to access the recently updated version of the welcome.war.
Reload the servers to activate the changes.
Navigate to the following addresses to verify that the welcome page was updated:
http://172.25.250.10:8080
http://172.25.250.10:8230
http://172.25.250.11:8080
http://172.25.250.11:8230
A welcome page with a Red Hat logo displays.
From the CLI, run the following command to deploy the application:
[domain@172.25.250.9:9990 /]deploy \/tmp/welcome.war --all-server-groups[domain@172.25.250.9:9990 /]
Run the following command in the CLI:
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=undertow\/server=default-server/host=default-host/location=\/:remove{ "outcome" => "success", "result" => undefined, "server-groups" => { "Group1" => {"host" => { "servera" => {"servera.1" => {"response" => { "outcome" => "success", ...output omitted...
[domain@172.25.250.9:9990 /]/profile=full-ha/subsystem=undertow/\server=default-server/host=default-host:write-attribute\(name=default-web-module,value=welcome.war)
[domain@172.25.250.9:9990 /]reload --restart-servers=true --host=servera[domain@172.25.250.9:9990 /]reload --restart-servers=true --host=serverb
Enable encrypted communication with the load balancer standalone server.
All the requests in this architecture go to the standalone server, which acts as a load balancer.
To guarantee those requests with sensitive information are not being transmitted in plain text, you must use a certificate to identify the load balancer.
In this step you import the /tmp/workstation.p12 provided certificate into a Java Key Store (JKS).
Then, you use this JKS to provide HTTPS connections from the load balancer.
You can safely ignore the warning about the JKS format.
Configure the realm to reference to the keystore where the certificate is stored.
Add a realm named HTTPSRealm to the security realm from the standalone server.
Link the HTTPSRealm to the keystore file with the certificate. It should provide the keystore password (password) and the alias where the certificate is bound to (1).
Add a new HTTPS listener using the configured HTTPSRealm realm.
Verify that you access to the server by using HTTPS. Open a browser and access the standalone server with a port offset of 1000.
Import the certificate into a JKS.
Use password as the destination and source keystore passwords.
[student@workstation ~]$sudo -u eap keytool -v -importkeystore \-srckeystore /tmp/workstation.p12 -srcstoretype PKCS12 \-destkeystore /opt/standalone/identity.jks -deststoretype JKSImporting keystore workstation.p12 to identity.jks... Enter destination keystore password: Re-enter new password: Enter source keystore password: Entry for alias 1 successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelled [Storing identity.jks] Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore identity.jks -destkeystore identity.jks -deststoretype pkcs12".
In the CLI opened to access the standalone server, run the following command:
[standalone@localhost:10990 /]/core-service=management/\security-realm=HTTPSRealm:add(){"outcome" => "success"}
[standalone@localhost:10990 /]/core-service=management/security-realm=HTTPSRealm/\server-identity=ssl:add(keystore-path=/opt/standalone/identity.jks,\keystore-password=password, alias=1){ "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
To make the change persistent, reload the standalone server.
[standalone@localhost:10990 /] reload[standalone@localhost:10990 /]/subsystem=undertow/server=\default-server/https-listener=https:\add(socket-binding=https, security-realm=HTTPSRealm){"outcome" => "success"}
Open a browser and navigate to the https://workstation.lab.example.com:9443 address to verify that the connection is secured.
You get an HTTP 404 error because the standalone-load-balancer.xml configuration has no welcome page.
Configure the cluster to use the TCP stack instead of the default UDP stack.
JBoss EAP is configured by default to use a UDP stack to discover cluster members. UDP supports multicast. Thus, new servers can be easily identified and added to a cluster. Unfortunately, the network does not support UDP and JBoss EAP must use a TCP stack, identifying which servers should be connected by a unicast connection.
To achieve this goal, customize the JGroups subsystem to use the TCPPING protocol.
A TCP stack cannot multicast messages.
Therefore, you must configure the TCPPING protocol to look for each cluster member.
The following list shows all IP and ports of each cluster member:
172.25.250.10 port 7600
172.25.250.10 port 7750
172.25.250.11 port 7600
172.25.250.11 port 7750
To minimize the risks from updating an existing stack, create a new stack called tcpping and make it the default stack.
You can use the /tmp/tcp-stack.cli existing prepopulated configuration file.
Reload the domain controller and all host controllers to make the TCPPING stack valid. From the CLI on the domain controller, run:
Update the /tmp/tcp-stack.cli file to use the TCPPING protocol, and customize the host list to include all the servers running on the managed domain.
Finally, change the stack used by JGroups to use the tcpping stack instead of the UDP stack.
batch /profile="full-ha"/subsystem="jgroups"/stack="tcpping":add() /profile="full-ha"/subsystem="jgroups"/stack="tcpping":add-protocol(type="TCPPING") /profile="full-ha"/subsystem="jgroups"/stack="tcpping"/\ transport="TRANSPORT":add(socket-binding="jgroups-tcp",type="TCP") run-batch batch /profile="full-ha"/subsystem="jgroups"/stack="tcpping"/protocol="TCPPING"/\ property="initial_hosts":add\ (value="") /profile="full-ha"/subsystem="jgroups"/stack="tcpping"/protocol="TCPPING"/\ property="port_range":add(value="10") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="MERGE2") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(socket-binding="jgroups-tcp-fd",type="FD_SOCK") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="FD") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="VERIFY_SUSPECT") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="BARRIER") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="pbcast.NAKACK") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="UNICAST2") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="pbcast.STABLE") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="pbcast.GMS") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="UFC") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="MFC") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="FRAG2") /profile="full-ha"/subsystem="jgroups"/stack="tcpping":\ add-protocol(type="RSVP") /profile=full-ha/subsystem=jgroups/channel=ee:\ write-attribute(name=172.25.250.10[7600],172.25.250.10[7750],172.25.250.11[7600],172.25.250.11[7750]stack,value=tcpping) run-batch
Run the modified CLI script.
[student@workstation ~]$sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \--connect --user=admin --password=redhat123 \--controller=172.25.250.9:9990 \--file="/tmp/tcp-stack.cli"The batch executed successfully The batch executed successfully
[domain@172.25.250.9:9990 /]/host=servera:reload{ "outcome" => "success", "result" => undefined } [domain@172.25.250.9:9990 /]/host=serverb:reload{ "outcome" => "success", "result" => undefined } [domain@172.25.250.9:9990 /]/host=master:reload{ "outcome" => "success", "result" => undefined }
Create a static load balancer by using the standalone server.
From the original architecture, the standalone server load balances all the requests from external environments.
You must customize the undertow subsystem to act as a reverse proxy.
Create a reverse proxy called kitchensink-handler in the standalone server.
Configure an outbound socket binding to connect to servera.1 (172.25.250.10).
The socket binding uses the AJP protocol running on the 8009 TCP port.
Name it remote-servera.1.
Reference the socket binding in the undertow subsystem:
Use a reference to the socket binding created previously for the servera.1
Bind it to the AJP scheme
Configure Undertow to access the /kitchensink application path from servera.1:
Configure an outbound socket binding to connect to servera.2 (172.25.250.10).
The socket binding uses the AJP protocol running on the 8159 TCP port.
Name it remote-servera.2.
Reference the socket binding in the undertow subsystem:
Use a reference to the socket binding created previously for the servera.2.
Bind it to the AJP scheme.
Configure Undertow to access the /kitchensink application path from servera.2
Configure an outbound socket binding to connect to serverb.1 (172.25.250.11).
The socket binding uses the AJP protocol running on the 8009 TCP port.
Name it remote-serverb.1.
Reference the socket binding in the undertow subsystem:
Use a reference to the socket binding created previously for the serverb.1.
Bind it to the AJP scheme.
Configure Undertow to access the /kitchensink application path from serverb.1:
Configure an outbound socket binding to connect to serverb.2 (172.25.250.11).
The socket binding uses the AJP protocol running on the 8159 TCP port.
Name it remote-serverb.2.
Reference the socket binding in the undertow subsystem:
Use a reference to the socket binding created previously for the serverb.2.
Bind it to the AJP scheme.
Configure Undertow to access the kitchensink.war application path from serverb.2
Create a reverse proxy location called /kitchensink, and refer it to the handler called kitchensink-handler:
Deploy the kitchensink.war application on all group servers and test it.
Navigate to https://workstation:9443/kitchensink.
The application user interfaces shows.
[standalone@localhost:10990 /]/subsystem=undertow/configuration=handler\/reverse-proxy=kitchensink-handler:add(){"outcome" => "success"}
[standalone@localhost:10990 /]/socket-binding-group=standard-sockets\/remote-destination-outbound-socket-binding=remote-servera.1/:\add(host=172.25.250.10, port=8009){"outcome" => "success"}
[standalone@localhost:10990 /]/subsystem=undertow/configuration=handler\/reverse-proxy=kitchensink-handler/host=servera.1:\add(outbound-socket-binding=remote-servera.1, \scheme=ajp, instance-id=myroute, path=/kitchensink)
[standalone@localhost:10990 /]/socket-binding-group=standard-sockets\/remote-destination-outbound-socket-binding=remote-servera.2/:\add(host=172.25.250.10, port=8159)
[standalone@localhost:10990 /]/subsystem=undertow/configuration=handler\/reverse-proxy=kitchensink-handler/host=servera.2:add\(outbound-socket-binding=remote-servera.2, \scheme=ajp, instance-id=myroute, path=/kitchensink)
[standalone@localhost:10990 /]/socket-binding-group=standard-sockets\/remote-destination-outbound-socket-binding=remote-serverb.1/:\add(host=172.25.250.11, port=8009)
[standalone@localhost:10990 /]/subsystem=undertow/configuration=handler\/reverse-proxy=kitchensink-handler/host=serverb.1:\add(outbound-socket-binding=remote-serverb.1, \scheme=ajp, instance-id=myroute, path=/kitchensink)
[standalone@localhost:10990 /]/socket-binding-group=standard-sockets\/remote-destination-outbound-socket-binding=remote-serverb.2/:\add(host=172.25.250.11, port=8159)
[standalone@localhost:10990 /]/subsystem=undertow/configuration=handler\/reverse-proxy=kitchensink-handler/host=serverb.2:\add(outbound-socket-binding=remote-serverb.2, \scheme=ajp, instance-id=myroute, path=/kitchensink)
[standalone@127.0.0.1:9990 /]/subsystem=undertow/server=default-server/\host=default-host\/location=\/kitchensink:add(handler=kitchensink-handler){"outcome" => "success"}
[domain@172.25.250.9:9990 /]deploy \/tmp/kitchensink.war --all-server-groups