Bookmark this page

Lab: Comprehensive Review of Red Hat JBoss Application Administration I

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

  1. 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.

    1. Create an eap system user on the workstation machine to start and stop the JBoss EAP instances.

      On the workstation machine, open a terminal window and run the following command to create the user:

      [student@workstation ~]$ sudo useradd -r eap
    2. Create an eap system user on the servera machine to start and stop the JBoss EAP instances.

      Run the following command to create the eap user in the servera machine:

      [student@workstation ~]$ ssh root@servera useradd -r eap
    3. Create an eap system user on the serverb machine to start and stop the JBoss EAP instances.

      Run the following command to create the eap user in the serverb machine:

      [student@workstation ~]$ ssh root@serverb useradd -r eap
    4. 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=redhat123
    5. Copy 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 ...
    6. 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-content
    7. Install 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 ]
    8. Verify the JBoss EAP installation in the servera machine.

      [student@workstation ~]$ ssh root@servera ls -la /opt/jboss-eap-7.4
      total 532
      ...output omitted...
    9. 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 ]
    10. Verify the JBoss EAP installation on the serverb machine.

      [student@workstation ~]$ ssh root@serverb ls -la /opt/jboss-eap-7.4
      total 532
      ...output omitted...
    11. 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" : {}
      }
    12. 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.4
      drwxr-xr-x. 14 eap eap 4096 Nov 27 06:26 /opt/jboss-eap-7.4
  2. 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

    FieldValue
    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

    1. Copy the standalone directory from the JBoss EAP installation to /opt/standalone.

      [student@workstation ~]$ sudo cp -R /opt/jboss-eap-7.4/standalone /opt
    2. Change the owner to the eap user.

      [student@workstation ~]$ sudo chown -R eap:eap /opt/standalone
    3. 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.

      [student@workstation ~]$ sudo -u eap /opt/jboss-eap-7.4/bin/standalone.sh \
      -Djboss.server.base.dir=/opt/standalone/ \
      -c standalone-load-balancer.xml
    4. 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.

      [student@workstation ~]$ sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \
      --connect --controller=localhost:9990
      [standalone@localhost:9990 /]
    5. 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
      }
    6. 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.

      [standalone@localhost:9990 /] exit

      Connect the CLI again to JBoss EAP by using the port offset:

      [student@workstation bin]$ sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \
      --connect --controller=localhost:10990
      [standalone@localhost:10990 /]
    7. 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 /]
  3. 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.

    1. 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.

      In a new terminal on the workstation machine, run the following commands as the student user.

      [student@workstation ~]$ sudo cp -R /opt/jboss-eap-7.4/domain /opt/

      On the workstation machine, run the following commands as the student user.

      [student@workstation ~]$ sudo chown -R eap:eap /opt/domain
    2. 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.

      [student@workstation ~]$ ssh root@servera cp -R /opt/jboss-eap-7.4/domain/ /opt/
      [student@workstation ~]$ ssh root@servera chown -R eap:eap /opt/domain
    3. 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.

      [student@workstation ~]$ ssh root@serverb cp -R /opt/jboss-eap-7.4/domain/ /opt/
      [student@workstation ~]$ ssh root@serverb chown -R eap:eap /opt/domain
    4. 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)
  4. 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.

    1. 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 /]
    2. 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.

      [domain@localhost:9990 /] /host=master/interface=management:\
      write-attribute(name=inet-address,value=172.25.250.9)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined,
          "response-headers" => {"process-state" => "reload-required"}
      }
    3. Reload the host controller to activate the IP address changes.

      The management CLI cannot reach the management interface after changing its IP address.

      [domain@localhost:9990 /] reload --host=master
      [disconnected /] Failed to establish connection in 6047ms

      Exit the management CLI to continue with the exercise.

      [disconnected /] exit
  5. 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:

    FieldValue
    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:

    FieldValue
    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.

    1. 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/configuration
      What 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 : jbossmgmt
      Password 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? yes
      Re-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? yes
      Added 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? yes
      To represent the user add the following to the server-identities definition <secret value="cmVkaGF0MTIz" />
    2. 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...
      <host name="servera" xmlns="urn:jboss:domain:16.0">
        <management>
              <security-realms>
                  <security-realm name="ManagementRealm">
                      <server-identities>
                          <secret value="cmVkaGF0MTIz"/>
                      </server-identities>
      
      ...output omitted...
        <domain-controller>
              <remote username="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>
    3. Start the JBoss EAP host controller from the servera machine using /opt/domain as the base directory.

      [student@workstation ~]$ ssh -t eap@servera /opt/jboss-eap-7.4/bin/domain.sh \
      -Djboss.domain.base.dir=/opt/domain --host-config=host-slave.xml
    4. Verify that the servera host controller connects to the domain controller by checking the logs from the domain controller terminal window.

      ...output omitted...
      [Host Controller] 04:38:46,352 INFO  [org.jboss.as.domain.controller] (Host Controller Service Threads - 53) WFLYHC0019: Registered remote slave host "servera", JBoss JBoss EAP 7.4.11.GA (WildFly 15.0.26.Final-redhat-00001)
    5. 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

    6. Connect to the management CLI.

      [student@workstation ~]$ sudo -u eap /opt/jboss-eap-7.4/bin/jboss-cli.sh \
      --connect --controller=172.25.250.9:9990
      [domain@172.25.250.9:9990 /]
    7. In the CLI terminal window, stop the servers running on the host controller servera to remove them.

      [domain@172.25.250.9:9990] :stop-servers
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    8. Remove the server-one instance from the servera host controller.

      [domain@172.25.250.9:9990] /host=servera/server-config=server-one:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    9. Remove the server-two instance from the servera host controller.

      [domain@172.25.250.9:9990] /host=servera/server-config=server-two:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
  6. 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:

    FieldValue
    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.

    1. 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...
      <host name="serverb" xmlns="urn:jboss:domain:16.0">
        <management>
              <security-realms>
                  <security-realm name="ManagementRealm">
                      <server-identities>
                          <secret value="cmVkaGF0MTIz"/>
                      </server-identities>
      
      ...output omitted...
        <domain-controller>
              <remote username="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>
    2. Start the JBoss EAP host controller from the serverb machine using /opt/domain as the base directory.

      [student@workstation ~]$ ssh -t eap@serverb /opt/jboss-eap-7.4/bin/domain.sh \
      -Djboss.domain.base.dir=/opt/domain --host-config=host-slave.xml
    3. Verify that the serverb host controller connects to the domain controller by checking the logs from the domain controller terminal window.

      ...output omitted...
      [Host Controller] 04:38:46,352 INFO  [org.jboss.as.domain.controller] (Host Controller Service Threads - 53) WFLYHC0019: Registered remote slave host "serverb", JBoss JBoss EAP 7.4.11.GA (WildFly 15.0.26.Final-redhat-00001)
    4. 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

    5. In the CLI terminal window, stop the servers running on the host controller serverb to remove them.

      [domain@172.25.250.9:9990] :stop-servers
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    6. Remove the server-one instance from the serverb host controller.

      [domain@172.25.250.9:9990] /host=serverb/server-config=server-one:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    7. Remove the server-two instance from the serverb host controller.

      [domain@172.25.250.9:9990] /host=serverb/server-config=server-two:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
  7. 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:

    FieldValue
    Server group name Group1
    Profile full-ha
    Socket binding configuration full-ha-sockets

    Second server group characteristics:

    FieldValue
    Server group name Group2
    Profile full-ha
    Socket binding configuration full-ha-sockets
    1. Remove the server group named main-server-group from the domain controller.

      [domain@172.25.250.9:9990] /server-group=main-server-group:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    2. Remove the server group named other-server-group from the domain controller.

      [domain@172.25.250.9:9990] /server-group=other-server-group:remove
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    3. Create a Group1 server group on the domain controller.

      [domain@172.25.250.9:9990] /server-group=Group1:add\
      (profile=full-ha,socket-binding-group=full-ha-sockets)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    4. Create a Group2 server group on the domain controller.

      [domain@172.25.250.9:9990] /server-group=Group2:add\
      (profile=full-ha,socket-binding-group=full-ha-sockets)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    5. Reload the configuration from the servera host controller to update the servers.

      [domain@172.25.250.9:9990] reload --host=servera
    6. Reload the configuration from the serverb host controller to update the servers.

      [domain@172.25.250.9:9990] reload --host=serverb
    7. Reload the configuration from the domain controller to update the servers.

      [domain@172.25.250.9:9990] reload --host=master
  8. 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:

    FieldValue
    Name servera.1
    Server group Group1
    Socket binding port offsetNone (Leave at default value of 0)
    Auto start true

    Second server:

    FieldValue
    Name servera.2
    Server group Group2
    Socket binding port offset 150
    Auto start true
    1. Configure the servera.1 on servera.

      [domain@172.25.250.9:9990 /] /host=servera/server-config=servera.1:add\
      (auto-start=true,group=Group1,socket-binding-port-offset=0)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    2. Configure the servera.2 on servera.

      [domain@172.25.250.9:9990 /] /host=servera/server-config=servera.2:add\
      (auto-start=true,group=Group2,socket-binding-port-offset=150)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    3. Start servera.1.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1:start
      {
          "outcome" => "success",
          "result" => "STARTING"
      }
    4. Start servera.2.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.2:start
      {
          "outcome" => "success",
          "result" => "STARTING"
      }
    5. 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

  9. 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:

    FieldValue
    Name serverb.1
    Server group Group1
    Socket binding port offsetNone (Leave at default value of 0)
    Auto start true

    Second server:

    FieldValue
    Name serverb.2
    Server group Group2
    Socket binding port offset 150
    Auto start true
    1. Configure the serverb.1 on serverb.

      [domain@172.25.250.9:9990 /] /host=serverb/server-config=serverb.1:add\
      (auto-start=true,group=Group1,socket-binding-port-offset=0)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    2. Configure the serverb.2 on serverb.

      [domain@172.25.250.9:9990 /] /host=serverb/server-config=serverb.2:add\
      (auto-start=true,group=Group2,socket-binding-port-offset=150)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    3. Start serverb.1 and serverb.2.

      [domain@172.25.250.9:9990 /] /host=serverb/server=serverb.1:start
      {
          "outcome" => "success",
          "result" => "STARTING"
      }
      [domain@172.25.250.9:9990 /] /host=serverb/server=serverb.2:start
      {
          "outcome" => "success",
          "result" => "STARTING"
      }
    4. 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

  10. 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:

    Kitchensink

    The kitchensink.war application stores a list of members in a database by using common JakartaEE APIs. The database name is kitchensink.

    Example

    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.

    1. Start a disconnected CLI session on 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 /]
    2. Add the module to the domain controller.

      [disconnected /] 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
      [disconnected /]
    3. Exit the CLI window.

      [disconnected /] exit
    4. 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 directory
    5. Repeat 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 directory
    6. Create 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
          }
      }
    7. Configure the data source to access the kitchensink.war application database. The following are the parameters for the kitchensink data source:

      FieldValue
      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 ~]$
    8. Verify that the data source works.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1/\
      subsystem=datasources/\
      data-source=KitchensinkQuickstartDS:test-connection-in-pool
      {
          "outcome" => "success",
          "result" => [true]
      }
    9. Configure the data source to access the example application database. The following are the parameters for the bksecurity data source:

      FieldValue
      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"
    10. Verify that the data source works.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1/\
      subsystem=datasources/\
      data-source=bksecurity:test-connection-in-pool
      {
          "outcome" => "success",
          "result" => [true]
      }
  11. 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.

    1. Create the /var/log/jboss directories on each host machine.

      [student@workstation ~]$ sudo mkdir /var/log/jboss ; \
      ssh root@servera mkdir /var/log/jboss ; \
      ssh root@serverb mkdir /var/log/jboss
      [student@workstation ~]$
    2. Change the ownership to the eap user:

      [student@workstation ~]$ sudo chown eap:eap /var/log/jboss ; \
      ssh root@servera chown eap:eap /var/log/jboss ; \
      ssh root@serverb chown eap:eap /var/log/jboss
      [student@workstation ~]$
    3. Create a new path called custom.log.dir pointing to /var/log/jboss.

      [domain@172.25.250.9:9990 /] /path=custom.log.dir:\
      add(path=/var/log/jboss/)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => {
              "Group1" => {"host" => {
      ...output omitted...
    4. 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...
    5. 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 files
  12. Customize 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.

    1. 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...
    2. 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.

      [domain@172.25.250.9:9990 server=default] /host=servera/server=servera.1/\
      subsystem=messaging-activemq\
      /server=default/jms-queue=TestQueue:read-attribute(name=queue-address)
      {
          "outcome" => "success",
          "result" => "jms.queue.TestQueue"
      }
    3. 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.

      [domain@172.25.250.9:9990 server=default] /host=servera/server=servera.1/\
      subsystem=messaging-activemq\
      /server=default/jms-queue=TestDLQ:read-attribute(name=queue-address)
      {
          "outcome" => "success",
          "result" => "jms.queue.TestDLQ"
      }
    4. 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.

      [domain@172.25.250.9:9990 server=default] /host=servera/server=servera.1/\
      subsystem=messaging-activemq\
      /server=default/jms-queue=TestExpiry:read-attribute(name=queue-address)
      {
          "outcome" => "success",
          "result" => "jms.queue.TestExpiry"
      }
    5. 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...
    6. 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...
    7. Deploy the mdb-client.war application on the Group1 server group to verify that the messaging subsystem is correct.

      [domain@172.25.250.9:9990 server=default] cd /
      [domain@172.25.250.9:9990 /] deploy \
      /tmp/mdb-client.war --server-groups=Group1
      [domain@172.25.250.9:9990 /]
    8. 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

      [student@workstation ~]$ curl --data "count=1" --data "label=first" \
      --data "message=test message body" \
      http://172.25.250.10:8080/mdb-client/queue; echo
      ...output omitted...
    9. Verify that the message is in the queue, but it is not consumed.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1\
      /subsystem=messaging-activemq/server=default\
      /jms-queue=TestQueue:read-resource(include-runtime=true)
      {
          "outcome" => "success",
          "result" => {
      ...output omitted...
              "message-count" => 1L,
              "messages-added" => 1L,
      ...output omitted...
          }
      }
    10. Deploy the helloworld-mdb.jar, which consumes the messages from TestQueue.

      [domain@172.25.250.9:9990 /] deploy \
      /tmp/helloworld-mdb.jar --server-groups=Group1
      [domain@172.25.250.9:9990 /]
    11. Verify that the message is not in the queue.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1\
      /subsystem=messaging-activemq/server=default\
      /jms-queue=TestQueue:read-resource(include-runtime=true)
      {
          "outcome" => "success",
          "result" => {
      ...output omitted...
              "message-count" => 0L,
              "messages-added" => 1L,
      ...output omitted...
          }
      }
  13. 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.

    1. 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 /]
    2. 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=master
      Authenticating against security realm: ManagementRealm
      
      Username: admin
      Password:
      [domain@172.25.250.9:9990 /]
    3. 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.

    4. 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

      FieldValue
      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-password
      Configuration 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/")])
      ********************************************
    5. 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.

      FieldValue
      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.

    6. 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/*
    7. 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
      }
    8. Restart the servers.

      [domain@172.25.250.9:9990 /] :reload-servers(blocking=true)
      {
          "outcome" => "success",
          "result" => undefined,
          "server-groups" => undefined
      }
    9. 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
                  }}}
              }}
          }
      }
    10. 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
    11. Verify that the modified data source connection works.

      [domain@172.25.250.9:9990 /] /host=servera/server=servera.1\
      /subsystem=datasources/data-source=bksecurity:test-connection-in-pool
      {
          "outcome" => "success",
          "result" => [true]
      }
    12. 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:

      FieldValue
      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
      }
    13. 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.

      [domain@172.25.250.9:9990 /] deploy \
      /tmp/example.war --server-groups=Group1
  14. 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
  15. 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
  16. 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.

    Note

    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 JKS
    Importing 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.

  17. 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="172.25.250.10[7600],172.25.250.10[7750],172.25.250.11[7600],​172.25.250.11[7750]")
    /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=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
    }
  18. 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

Evaluation

As the student user on the workstation machine, use the lab command to grade your work. Correct any reported failures and rerun the command until successful.

[student@workstation ~]$ lab grade compreview

Finish

As the student user on the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish compreview
Revision: ad248-7.4-18a9db2