Chapter 4. Creating the Environment
4.1. Prerequisites
Prerequisites for creating this reference architecture include a supported Operating System and JDK. Refer to Red Hat documentation for supported environments.
With minor changes, almost any RDBMS may be used in lieu of MySQL Database, but if MySQL is used, the details of the download and installation are also considered a prerequisite for this reference architecture. On RHEL 7, use MariaDB, the community fork of MySQL:
# yum install mariadb-server
This reference architecture also uses Apache HTTP Server to demonstrate load balancing. In a production environment, consider using Red Hat JBoss Core Services Apache HTTP Server, but the functionality and configuration described in this document is largely similar for other versions of httpd. On a RHEL machine with the required Red Hat subscription, Red Hat JBoss Core Services Apache HTTP Server 2.4 can be installed by using yum:
# yum groupinstall jbcs-httpd24For further information on installing and configuring JBoss EAP Apache HTTP Server, refer to the JBoss EAP 7 Clustering reference architecture. Clients with access to the Red Hat Customer Portal may download the reference architecture and attachments from https://access.redhat.com/site/articles/2359241.
4.2. Downloads
The attachments to this document provide the Apache HTTP Server configuration file, CLI configuration to configure the required datasource, and the source code for the reference application. These files may be downloaded from:
https://access.redhat.com/node/2386641/40/0
If you do not have access to the Red Hat customer portal, See the Comments and Feedback section to contact us for alternative methods of access to these files.
Download JBoss EAP 7 from Red Hat’s Customer Support Portal:
- Red Hat JBoss Enterprise Application Platform 7.0.0
An appropriate version of MySQL JDBC driver should also be separately downloaded.
4.3. Installation
Red Hat’s JBoss EAP 7 does not require any installation steps. The archive file simply needs to be extracted after the download:
# unzip jboss-eap-7.0.0.zipPlace the EAP files in an appropriate location, for example: /opt/jboss-eap-7.0
4.4. Configuration
This reference architecture uses firewalld, the default Red Hat Firewall, to block all network packets by default and only allow configured ports and addresses to communicate. Refer to the Red Hat documentation on firewalld for further details on this tool.
Check the status of firewalld on each machine and make sure it is running:
# systemctl status firewalldThis reference environment starts with the default and most restrictive firewall setting and only opens the required ports. In particular, the machine hosting the Apache HTTP Server load balancer needs to open port 80 to all incoming traffic:
# firewall-cmd --zone=public --add-service=http --permanentThe machine hosting the database must allow connections to the database port, in this case 3306, from the hosts where microservices are deployed. In this reference environment, these boxes use a sequence of IP addresses in the same subnet:
# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="10.19.137.1/24" port protocol="tcp" port="3306" accept"Using the permanent flag persists the firewall configuration but also requires a reload to have the changes take effect immediately:
# firewall-cmd --reload
On each of the hosts serving a microservice, open the JBoss EAP port for incoming traffic from the load balancer. In the reference environment, the Apache HTTP Server load balancer is hosted at 10.19.137.30. Follow that up by reloading firewall configuration to have the change take effect:
# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="10.19.137.30/32" port protocol="tcp" port="8080" accept" # firewall-cmd --reload
This reference environment has been set up and tested with Security-Enhanced Linux (SELinux) enabled in enforcing mode. Once again, refer to the Red Hat documentation on SELinux for further details on using and configuring this feature. For any other operating system, consult the respective documentation for security and firewall solutions to ensure that maximum security is maintained while the ports required by your application are opened.
When enabled in enforcing mode, by default, SELinux prevents Apache HTTP Server from establishing network connections. On the machine hosting Apache HTTP Server, configure SELinux it to allow httpd network connections:
# /usr/sbin/setsebool httpd_can_network_connect 1This reference application uses Apache HTTP Server to host static content, in this case the images used by the presentation layer. Create the images directory on the machine hosting httpd, copy the images in there, and set security privileges as appropriate to allow them to be served:
# mkdir -p /srv/msa/images # cp code/Presentation/images/* /srv/msa/images/ # chmod 644 /srv/msa/images/* Even with the correct security privileges, SELinux can stop the images from being served to web users unless their extended attributes are properly set:
# chcon -R -t httpd_sys_content_t /srv/msa/images
Various other types of configuration may be required for UDP and TCP communication. For example, Linux operating systems typically have a low maximum socket buffer size configured, which is lower than the default cluster JGroups buffer size. It may be important to correct any such warnings observed in the EAP logs. For example, in this case for a Linux operating system, the maximum socket buffer size may be configured as follows.
# sysctl -w net.core.rmem_max=26214400 # sysctl -w net.core.wmem_max=1048576The reference application uses a series of host names to make it more portable. These hostnames are as follows:
- product-service: Load balancer front-ending product microservice nodes
- billing-service: Load balancer front-ending billing microservice nodes
- sales-service: Load balancer front-ending sales microservice nodes
- product-db: The location of the product database server
- sales-db: The location of the sales database server
In the reference environment, the machine addressed 10.19.137.30 hosts the Apache HTTP Server, effectively acting as the load balancer for all three microservices. This machine also hosts the single database server with two separate schemas for sales and product, acting as two logical database servers.
For testing purposes, it is easy enough to edit the hosts file on each of the thirteen machines (three nodes for each of presentation, product, sales and billing applications, plus one for database and load balancer):
# vi /etc/hostsAdd the following lines to the hosts file:
10.19.137.30 product-service
10.19.137.30 billing-service
10.19.137.30 sales-service
10.19.137.30 product-db
10.19.137.30 sales-db
4.4.1. Red Hat JBoss Core Services Apache HTTP Server
The Apache HTTP Server used in this reference environment serves as the load balancer for the presentation application as well three different microservices. This web server also serves the static content (images) for the presentation layer.
Create a virtual host for the presentation layer. This environment uses msa-web as the host name for the entry point:
<VirtualHost msa-web:80>
ProxyPreserveHost On
ProxyRequests off
ServerName msa-web
Configure the location of static resources and allow access:
# static files:
DocumentRoot /srv/msa/
<Directory /srv/msa>
Options All
AllowOverride All
Require all granted
</Directory>
Finally, configure mod_proxy as a load balancer to distribute load between the nodes of the presentation application running on JBoss EAP.
<Proxy balancer://presCluster>
BalancerMember http://10.19.137.31:8080
BalancerMember http://10.19.137.32:8080
BalancerMember http://10.19.137.33:8080
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass /presentation balancer://presCluster/presentation stickysession=JSESSIONID|jsessionid scolonpathdelim=On
ProxyPassReverse /presentation balancer://presCluster/presentation
</VirtualHost>
The load balancing method is set to byrequests to perform a default simple round-robin, but sticky sessions are turned on using either the cookie name or URL rewriting with semicolon as a separator.
The load balancer configuration for the the product microservice is much simpler, since no static resources are being served and the application is completely stateless, so sticky sessions are not applicable:
<VirtualHost product-service:80>
ProxyPreserveHost On
ProxyRequests off
ServerName product-service
<Proxy balancer://productCluster>
BalancerMember http://10.19.137.34:8080
BalancerMember http://10.19.137.35:8080
BalancerMember http://10.19.137.36:8080
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass /product balancer://productCluster/product
ProxyPassReverse /product balancer://productCluster/product
</VirtualHost>
The load balancer configuration for the sales and billing microservices is similar:
<VirtualHost sales-service:80>
ProxyPreserveHost On
ProxyRequests off
ServerName sales-service
<Proxy balancer://salesCluster>
BalancerMember http://10.19.137.37:8080
BalancerMember http://10.19.137.38:8080
BalancerMember http://10.19.137.39:8080
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass /sales balancer://salesCluster/sales
ProxyPassReverse /sales balancer://salesCluster/sales
</VirtualHost>
<VirtualHost billing-service:80>
ProxyPreserveHost On
ProxyRequests off
ServerName billing-service
<Proxy balancer://billingCluster>
BalancerMember http://10.19.137.40:8080
BalancerMember http://10.19.137.41:8080
BalancerMember http://10.19.137.42:8080
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass /billing balancer://billingCluster/billing
ProxyPassReverse /billing balancer://billingCluster/billing
</VirtualHost>
Restart the web server after configuration is complete:
# systemctl stop jbcs-httpd24-httpd.service # systemctl start jbcs-httpd24-httpd.service4.4.2. MySQL / MariaDB Database
Start the database server:
# systemctl start mariadb.serviceEnable the database server at boot time:
# systemctl enable mariadb.serviceInitialize the database by running the included script:
# mysql_secure_installationThe database root password is initially blank. Set a new password and remove anonymous users and the test database, before reloading the privilege tables.
Once the database initialization is complete, run the database utility to set up the application databases:
# mysql -u root -pLog in using the newly configured password and use MySQL DDL syntax to create the database and the user that accesses it:
CREATE DATABASE product;
USE product;
CREATE USER 'product'@'%' IDENTIFIED BY 'password';
GRANT USAGE ON . TO 'product'@'%' IDENTIFIED BY 'password';
Create tables along with the sequence used by JPA, for example:
CREATE TABLE Product (SKU BIGINT NOT NULL AUTO_INCREMENT, DESCRIPTION VARCHAR(255), HEIGHT NUMERIC(8,2) NOT NULL, LENGTH NUMERIC(8,2) NOT NULL, NAME VARCHAR(255), WEIGHT NUMERIC(8,2) NOT NULL, WIDTH NUMERIC(8,2) NOT NULL, FEATURED BOOLEAN, AVAILABILITY INTEGER NOT NULL, IMAGE VARCHAR(255), PRICE NUMERIC(9,2) NOT NULL, PRIMARY KEY (SKU)) AUTO_INCREMENT = 10001;
Complete the setup of the databases by running the instructions in the provided SQL script file: setup.sql
4.4.3. JBoss Enterprise Application Platform
This reference architecture makes very few changes to the JBoss EAP configuration. The only required change is to configure a datasource and connect it to the appropriate database for the Product and Sales server instances. To do this, the MySQL JDBC driver is installed as a module and configured on the server. The appropriate datasource is then configured to leverage this driver and connect to the corresponding database.
This reference architecture provides a JBoss CLI script to automate the required configuration. Sample property files have been provided for each of the product and sales datasources. Modify the mysql.jar property to indicate the exact name and version of the MySQL JDBC driver you downloaded. Also configure the username and password appropritately for your database. The JNDI name of the datasource is used by the application code and expected to match the provided value for each of the product and sales datasources.
With the correct property file configured for an environment and the JDBC driver downloaded and placed next to it, use JBoss CLI to configure the standalone server:
# /opt/jboss-eap-7.0/bin/jboss-cli.sh --file=configure.cli --properties=product.propertiesOptionally, inspect the datasources subsystem of the server configuration for the applied changes in /opt/jboss-eap-7.0/standalone/configuration/standalone.xml.
The JBoss EAP server can be started after this step and bound to the correct IP address to be accessible by the load balancer.
4.5. Deployment
The application code for the presentation layer and all three microservice projects is included under the code directory of the attachment.
At the top level of this directory is an aggregation POM that builds all four projects. To build the projects, run maven from this directory:
# cd code/ # mvn installOnce the build completes successfully, the deployable web archive files are generated and placed in the target directory of each project. Deploy each web application by dropping it into the /opt/jboss-eap-7.0/standalone/deployments/ folder of its respective servers. The web application archives are as follows:
- The presentation layer: code/Presentation/target/presentation.war
- The product microservice: code/Product/target/product.war
- The sales microservice: code/Sales/target/sales.war
- The billing microservice: code/Billing/target/billing.war
While deploying the application, monitor the server log and make sure there are no errors. The server log is located at /opt/jboss-eap-7.0/standalone/log/server.log
4.6. Execution
Open a browser and point it to the load balancer to reach the application. Assuming that the hostname for the load balancer machine is msa-web, point the browser to: http://msa-web/presentation/
The first request to the server returns the featured products from the database:
Figure 4.1. Featured Products

The provided search bar allows the user to filter the products by keyword. Each product in the database may be associated with one or multiple keywords. The scope of this search is all products, whether they are featured or not. Search the product database for TV:
Figure 4.2. Search Products

Click the Register button on the top right of the screen to register a new customer user:
Figure 4.3. Customer Registration

Once registered, the user will be automatically and implicitly signed in. Alternatively, in a new browser session, the user can enter the same username and password to render the same page.
This page shows the same featured products but notice that there is now a purchase button underneath the product price and availability. Click on purchase button for a product to add it to your shopping cart:
Figure 4.4. User logged in

Notice that the shopping cart icon on the top right of the screen now includes the number of items in the shopping cart:
Figure 4.5. Shopping Cart Item Count

To view the content of your shopping cart, click on the cart icon:
Figure 4.6. Shopping Cart Content

Scroll down and click the checkout button to pay for the items in the cart:
Figure 4.7. Checkout

After entering valid data and an expiration data that is in the future, click the submit button to process the purchase.
Once the purchase is completed, the application returns to the featured products page. From this homepage, click the Order history link to view all the orders. The items in your shopping cart are stored as an order that is in progress and has a status of Initial:
Figure 4.8. Customer Order History


Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.