Deployment Pipeline for Java EE 7 with WildFly, Arquillian, Jenkins, and OpenShift
Tech Tip #54 showed how to Arquillianate (Arquillianize ?) an existing Java EE project and run those tests in remote mode where WildFly is running on a known host and port. Tech Tip #55 showed how to run those tests when WildFly is running in OpenShift. Both of these tips used Maven profiles to separate the appropriate Arquillian dependencies in “pom.xml” and <container> configuration in “arquillian.xml” to define where WildFy is running and how to connect to it.
This tip will show how to configure Jenkins in OpenShift and invoke these tests from Jenkins. Lets see it in action first!
Configuration required to connect from Jenkins on OpenShift to a WildFly instance on OpenShift is similar to that required for connecting from local machine to WildFly on OpenShift. This configuration is specified in “arquillian.xml” and we can specify some parameters which can then be defined in Jenkins.
On a high level, here is what we’ll do:
- Use the code created in Tech Tip #54 and #55 and add configuration for Arquillian/Jenkins/OpenShift
- Enable Jenkins
- Create a new WildFly Test instance
- Configure Jenkins to run tests on the Test instance
- Push the application to Production only if tests pass on Test instance
Lets get started!
- Remove the existing boilerplate source code, only the
src
directory, from the WildFly git repo created in Tech Tip #55.010203040506070809101112131415161718mywildfly> git
rm
-rf src/ pom.xml
rm
'pom.xml'
rm
'src/main/java/.gitkeep'
rm
'src/main/resources/.gitkeep'
rm
'src/main/webapp/WEB-INF/web.xml'
rm
'src/main/webapp/images/jbosscorp_logo.png'
rm
'src/main/webapp/index.html'
rm
'src/main/webapp/snoop.jsp'
mywildfly> git commit . -m
"removing source and pom"
[master 564b275] removing
source
and pom
7 files changed, 647 deletions(-)
delete mode 100644 pom.xml
delete mode 100644 src
/main/java/
.gitkeep
delete mode 100644 src
/main/resources/
.gitkeep
delete mode 100644 src
/main/webapp/WEB-INF/web
.xml
delete mode 100644 src
/main/webapp/images/jbosscorp_logo
.png
delete mode 100644 src
/main/webapp/index
.html
delete mode 100644 src
/main/webapp/snoop
.jsp
- Set a new remote to javaee7-continuous-delivery repository:123456
mywildfly> git remote add javaee7 https:
//github
.com
/arun-gupta/javaee7-continuous-delivery
.git
mywildfly> git remote -
v
javaee7 https:
//github
.com
/arun-gupta/javaee7-continuous-delivery
.git (fetch)
javaee7 https:
//github
.com
/arun-gupta/javaee7-continuous-delivery
.git (push)
origin
ssh
:
//54699516ecb8d41cb8000016
@mywildfly-milestogo.rhcloud.com/~
/git/mywildfly
.git/ (fetch)
origin
ssh
:
//54699516ecb8d41cb8000016
@mywildfly-milestogo.rhcloud.com/~
/git/mywildfly
.git/ (push)
- Pull the code from new remote:01020304050607080910111213141516171819202122232425262728293031
mywildfly> git pull javaee7 master
warning: no common commits
remote: Counting objects: 62,
done
.
remote: Compressing objects: 100% (45
/45
),
done
.
remote: Total 62 (delta 14), reused 53 (delta 5)
Unpacking objects: 100% (62
/62
),
done
.
From https:
//github
.com
/arun-gupta/javaee7-continuous-delivery
* branch master -> FETCH_HEAD
* [new branch] master -> javaee7
/master
Merge made by the
'recursive'
strategy.
.gitignore | 6 +++
README.asciidoc | 15 ++++++
pom.xml | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src
/main/java/org/javaee7/sample/MyApplication
.java | 9 ++++
src
/main/java/org/javaee7/sample/Person
.java | 31 ++++++++++++
src
/main/java/org/javaee7/sample/PersonDatabase
.java | 39 ++++++++++++++
src
/main/java/org/javaee7/sample/PersonResource
.java | 29 +++++++++++
src
/main/webapp/index
.jsp | 13 +++++
src
/test/java/org/javaee7/sample/PersonTest
.java | 77 ++++++++++++++++++++++++++++
src
/test/resources/arquillian
.xml | 26 ++++++++++
10 files changed, 442 insertions(+)
create mode 100644 .gitignore
create mode 100644 README.asciidoc
create mode 100644 pom.xml
create mode 100644 src
/main/java/org/javaee7/sample/MyApplication
.java
create mode 100644 src
/main/java/org/javaee7/sample/Person
.java
create mode 100644 src
/main/java/org/javaee7/sample/PersonDatabase
.java
create mode 100644 src
/main/java/org/javaee7/sample/PersonResource
.java
create mode 100644 src
/main/webapp/index
.jsp
create mode 100644 src
/test/java/org/javaee7/sample/PersonTest
.java
create mode 100644 src
/test/resources/arquillian
.xml
This will bring all the source code, include our REST endpoints, web pages, tests, updated “pom.xml” and “arquillian.xml”. The updated “pom.xml” has two new profiles.
0102030405060708091011121314151617181920212223242526272829303132333435363738394041<
profile
>
<
id
>openshift</
id
>
<
build
>
<
plugins
>
<
plugin
>
<
groupid
>org.apache.maven.plugins</
groupid
>
<
artifactid
>maven-war-plugin</
artifactid
>
<
version
>2.3</
version
>
<
configuration
>
<
failonmissingwebxml
>false</
failonmissingwebxml
>
<
outputdirectory
>deployments</
outputdirectory
>
<
warname
>ROOT</
warname
>
</
configuration
>
</
plugin
>
</
plugins
>
</
build
>
</
profile
>
<
profile
>
<
id
>jenkins-openshift</
id
>
<
build
>
<
plugins
>
<
plugin
>
<
artifactid
>maven-surefire-plugin</
artifactid
>
<
version
>2.14.1</
version
>
<
configuration
>
<
systempropertyvariables
>
<
arquillian.launch
>jenkins-openshift</
arquillian.launch
>
</
systempropertyvariables
>
</
configuration
>
</
plugin
>
</
plugins
>
</
build
>
<
dependencies
>
<
dependency
>
<
groupid
>org.jboss.arquillian.container</
groupid
>
<
artifactid
>arquillian-openshift</
artifactid
>
<
version
>1.0.0.Final-SNAPSHOT</
version
>
<
scope
>test</
scope
>
</
dependency
>
</
dependencies
>
</
profile
>
Few points to observe here:
- “openshift” profile is used when building an application on OpenShift. This is where the application’s WAR file is created and deployed to WildFly.
- A new profile “jenkins-openshift” is added that will be used by the Jenkins instance (to be enabled shortly) in OpenShift to run tests.
- “arquillian-openshift” dependency is the same as used in Tech Tip #55 and allows to run Arquillian tests on a WildFly instance on OpenShift.
- This profile refers to “jenkins-openshift” container configuration that will be defined in “arquillian.xml”.
Updated “src/test/resources/arquillian.xml” has the following container:
0102030405060708091011<
container
qualifier
=
"jenkins-openshift"
>
<
configuration
>
<
property
name
=
"namespace"
>${env.ARQ_DOMAIN}</
property
>
<
property
name
=
"application"
>${env.ARQ_APPLICATION}</
property
>
<
property
name
=
"libraDomain"
>rhcloud.com</
property
>
<
property
name
=
"sshUserName"
>${env.ARQ_SSH_USER_NAME}</
property
>
<
property
name
=
"login"
>arungupta@redhat.com</
property
>
<
property
name
=
"deploymentTimeoutInSeconds"
>300</
property
>
<
property
name
=
"disableStrictHostChecking"
>true</
property
>
</
configuration
>
</
container
>
This container configuration is similar to the one that was added in Tech Tip #55. The only difference here is that the domain name, application name, and the SSH user name are parametrized. The value of these properties is defined in the configuration of Jenkins instance and allows to run the test against a separate test node.
- Two more things need to be done before changes can be pushed to the remote repository. First is to create a WildFly Test instance which can be used to run the tests. This can be easily done as shown:01020304050607080910111213141516171819202122232425262728293031
workspaces> rhc app-create mywildflytest jboss-wildfly-8
Application Options
-------------------
Domain: milestogo
Cartridges: jboss-wildfly-8
Gear Size: default
Scaling: no
Creating application
'mywildflytest'
... Artifacts deployed: .
/ROOT
.war
done
WildFly 8 administrator added. Please
make
note of these credentials:
Username: adminITJt7Yh
Password: yXP2mUd1w4_8
run
'rhc port-forward mywildflytest'
to access the web admin area on port 9990.
Waiting
for
your DNS name to be available ...
done
Cloning into
'mywildflytest'
...
Warning: Permanently added the RSA host key
for
IP address
'54.205.69.88'
to the list of known hosts.
Your application
'mywildflytest'
is now available.
URL: http:
//mywildflytest-milestogo
.rhcloud.com/
SSH to: 546e3743ecb8d49ca9000014@mywildflytest-milestogo.rhcloud.com
Git remote:
ssh
:
//546e3743ecb8d49ca9000014
@mywildflytest-milestogo.rhcloud.com/~
/git/mywildflytest
.git/
Cloned to:
/Users/arungupta/workspaces/javaee7/mywildflytest
Run
'rhc show-app mywildflytest'
for
more
details about your app.
Note the domain here is
milestogo
, application name ismywildflytest
, and SSH user name is546e3743ecb8d49ca9000014
. These will be passed to Arquillian for running the tests. - Second is to enable and configure Jenkins.In your OpenShift Console, pick the “mywildfly” application and click on “Enable Jenkins” link as shown below:
Remember this is not your Test instance because all the source code lives on the instance created earlier.Provide the appropriate name, e.g. jenkins-milestogo.rhcloud.com in my case, and click on “Add Jenkins” button. This will provision a Jenkins instance, if not already there and also configure the project with a script to build and deploy the application. Note down the name and password credentials.
- Use the credentials to login to your Jenkins instance.Select the appropriate build, “mywildfly-build” in this case. Scroll down to the “Build” section and add the following script right after “# Run tests here” in the Execute Shell:1234
export
ARQ_DOMAIN=milestogo
export
ARQ_SSH_USER_NAME=546e3743ecb8d49ca9000014
export
ARQ_APPLICATION=mywildflytest
mvn
test
-Pjenkins-openshift
Click on “Save” to save the configuration. This will allow to run the Arquillian tests on the Test instance. If the tests pass then the app is deployed. If the tests fail, then none of the steps after that step are executed and so the app is not deployed.
- Lets push the changes to remote repo now:01020304050607080910111213141516171819
mywildfly> git push
Counting objects: 68,
done
.
Delta compression using up to 8 threads.
Compressing objects: 100% (49
/49
),
done
.
Writing objects: 100% (61
/61
), 8.85 KiB | 0 bytes
/s
,
done
.
Total 61 (delta 14), reused 0 (delta 0)
remote: Executing Jenkins build.
remote:
remote: You can track your build at https:
//jenkins-milestogo
.rhcloud.com
/job/mywildfly-build
remote:
remote: Waiting
for
build to schedule............................................................................................Done
remote: Waiting
for
job to complete................................................................................................................................................................................................................................................................................................................................................................................................Done
remote: SUCCESS
remote: New build has been deployed.
remote: -------------------------
remote: Git Post-Receive Result: success
remote: Deployment completed with status: success
To
ssh
:
//546cef93ecb8d4ff37000003
@mywildfly-milestogo.rhcloud.com/~
/git/mywildfly
.git/
e8f6c61..e9ad206 master -> master
The number of dots indicate the wait for a particular task and will most likely vary for different runs. And Jenkins console (jenkins-milestogo.rhcloud.com/job/mywildfly-build/1/console) shows the output as:
01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.javaee7.sample.PersonTest
Nov 20, 2014 2:54:56 PM org.jboss.arquillian.container.openshift.OpenShiftContainer start
INFO: Preparing Arquillian OpenShift container at http:
//mywildflytest-milestogo
.rhcloud.com
Nov 20, 2014 2:55:48 PM org.jboss.arquillian.container.openshift.OpenShiftRepository push
INFO: Pushed to the remote repository
ssh
:
//546e3743ecb8d49ca9000014
@mywildflytest-milestogo.rhcloud.com/~
/git/mywildflytest
.git/
Nov 20, 2014 2:56:37 PM org.jboss.arquillian.container.openshift.OpenShiftRepository push
INFO: Pushed to the remote repository
ssh
:
//546e3743ecb8d49ca9000014
@mywildflytest-milestogo.rhcloud.com/~
/git/mywildflytest
.git/
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 103.056 sec
Nov 20, 2014 2:56:37 PM org.jboss.arquillian.container.openshift.OpenShiftContainer stop
INFO: Shutting down Arquillian OpenShift container at http:
//mywildflytest-milestogo
.rhcloud.com
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total
time
: 3:13.069s
[INFO] Finished at: Thu Nov 20 14:57:34 EST 2014
[INFO] Final Memory: 10M
/101M
[INFO] ------------------------------------------------------------------------
+
/usr/libexec/openshift/cartridges/jenkins/bin/git_ssh_wrapper
.sh 546e36e5e0b8cd4e2a000007@mywildfly-milestogo.rhcloud.com
'gear stop --conditional'
Warning: Permanently added
'mywildfly-milestogo.rhcloud.com,10.5.171.43'
(RSA) to the list of known hosts.
Stopping gear...
Stopping wildfly cart
Sending SIGTERM to wildfly:418673 ...
+
rsync
--delete-after -azO -e
/usr/libexec/openshift/cartridges/jenkins/bin/git_ssh_wrapper
.sh
/var/lib/openshift/546e46304382ec3f29000012//
.m2/
'546e36e5e0b8cd4e2a000007@mywildfly-milestogo.rhcloud.com:~/.m2/'
Warning: Permanently added
'mywildfly-milestogo.rhcloud.com,10.5.171.43'
(RSA) to the list of known hosts.
+
rsync
--delete-after -azO -e
/usr/libexec/openshift/cartridges/jenkins/bin/git_ssh_wrapper
.sh
/var/lib/openshift/546e46304382ec3f29000012/app-root/runtime/repo/deployments/
'546e36e5e0b8cd4e2a000007@mywildfly-milestogo.rhcloud.com:${OPENSHIFT_REPO_DIR}deployments/'
Warning: Permanently added
'mywildfly-milestogo.rhcloud.com,10.5.171.43'
(RSA) to the list of known hosts.
+
rsync
--delete-after -azO -e
/usr/libexec/openshift/cartridges/jenkins/bin/git_ssh_wrapper
.sh
/var/lib/openshift/546e46304382ec3f29000012/app-root/runtime/repo/
.openshift/
'546e36e5e0b8cd4e2a000007@mywildfly-milestogo.rhcloud.com:${OPENSHIFT_REPO_DIR}.openshift/'
Warning: Permanently added
'mywildfly-milestogo.rhcloud.com,10.5.171.43'
(RSA) to the list of known hosts.
+
/usr/libexec/openshift/cartridges/jenkins/bin/git_ssh_wrapper
.sh 546e36e5e0b8cd4e2a000007@mywildfly-milestogo.rhcloud.com
'gear remotedeploy'
Warning: Permanently added
'mywildfly-milestogo.rhcloud.com,10.5.171.43'
(RSA) to the list of known hosts.
Preparing build
for
deployment
Deployment
id
is dff28e58
Activating deployment
Deploying WildFly
Starting wildfly cart
Found 127.12.255.129:8080 listening port
Found 127.12.255.129:9990 listening port
/var/lib/openshift/546e36e5e0b8cd4e2a000007/wildfly/standalone/deployments
/var/lib/openshift/546e36e5e0b8cd4e2a000007/wildfly
/var/lib/openshift/546e36e5e0b8cd4e2a000007/wildfly
CLIENT_MESSAGE: Artifacts deployed: .
/ROOT
.war
Archiving artifacts
Finished: SUCCESS
Log files for Jenkins can be viewed as shown:
0102030405060708091011121314151617181920212223242526272829Nov 20, 2014 2:51:11 PM hudson.plugins.openshift.OpenShiftCloud provision
INFO: Provisioning new node
for
workload = 2 and label = mywildfly-build
in
domain milestogo
Nov 20, 2014 2:51:11 PM hudson.plugins.openshift.OpenShiftCloud getOpenShiftConnection
INFO: Initiating Java Client Service - Configured
for
OpenShift Server https:
//openshift
.redhat.com
Nov 20, 2014 2:51:11 PM com.openshift.internal.client.RestService request
INFO: Requesting GET with protocol 1.2 on https:
//openshift
.redhat.com
/broker/rest/api
Nov 20, 2014 2:51:11 PM com.openshift.internal.client.RestService request
INFO: Requesting GET with protocol 1.2 on https:
//openshift
.redhat.com
/broker/rest/user
Nov 20, 2014 2:51:11 PM com.openshift.internal.client.RestService request
. . .
INFO: Checking availability of computer hudson.plugins.openshift.OpenShiftSlave@8ce21115
Nov 20, 2014 2:53:35 PM com.openshift.internal.client.RestService request
INFO: Requesting GET with protocol 1.2 on https:
//openshift
.redhat.com
/broker/rest/domain/milestogo/application/mywildflybldr/gear_groups
Nov 20, 2014 2:53:35 PM hudson.plugins.openshift.OpenShiftComputerLauncher launch
INFO: Checking SSH access to application mywildflybldr-milestogo.rhcloud.com
Nov 20, 2014 2:53:35 PM hudson.plugins.openshift.OpenShiftComputerLauncher launch
INFO: Connecting via SSH
'546e46304382ec3f29000012'
'mywildflybldr-milestogo.rhcloud.com'
'/var/lib/openshift/546e393e5973ca0492000070/app-root/data/.ssh/jenkins_id_rsa'
Nov 20, 2014 2:53:35 PM hudson.slaves.NodeProvisioner update
INFO: mywildfly-build provisioningE successfully completed. We have now 2 computer(s)
Nov 20, 2014 2:53:35 PM hudson.plugins.openshift.OpenShiftComputerLauncher launch
INFO: Connected via SSH.
Nov 20, 2014 2:53:35 PM hudson.plugins.openshift.OpenShiftComputerLauncher launch
INFO: Exec
mkdir
-p $OPENSHIFT_DATA_DIR
/jenkins
&&
cd
$OPENSHIFT_DATA_DIR
/jenkins
&&
rm
-f slave.jar && wget -q --no-check-certificate https:
//jenkins-milestogo
.rhcloud.com
/jnlpJars/slave
.jar
Nov 20, 2014 2:53:42 PM hudson.plugins.openshift.OpenShiftComputerLauncher launch
INFO: Slave connected.
Nov 20, 2014 2:58:24 PM hudson.model.Run execute
INFO: mywildfly-build
#1 main build action completed: SUCCESS
This shows the application was successfully deployed at mywildfly-milestogo.rhcloud.com/index.jsp and looks like as shown:
Now change “src/main/webapp/index.jsp” to show a different heading. And change “src/test/java/org/javaee7/sample/PersonTest.java” to make one of the tests fail. Doing “git commit” and “git push” shows the following results on command line:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | mywildfly> git commit . -m "breaking the test" [master ff2de09] breaking the test 2 files changed, 2 insertions(+), 2 deletions(-) mywildfly> git push Counting objects: 23, done . Delta compression using up to 8 threads. Compressing objects: 100% (8 /8 ), done . Writing objects: 100% (12 /12 ), 771 bytes | 0 bytes /s , done . Total 12 (delta 5), reused 0 (delta 0) remote: Executing Jenkins build. remote: remote: You can track your build at https: //jenkins-milestogo .rhcloud.com /job/mywildfly-build remote: remote: Waiting for build to schedule.......Done remote: Waiting for job to complete.....................................................................................................................................................................Done remote: FAILED remote: !!!!!!!! remote: Deployment Halted! remote: If the build failed before the deploy step, your previous remote: build is still running. Otherwise, your application may be remote: partially deployed or inaccessible. remote: Fix the build and try again. remote: !!!!!!!! remote: An error occurred executing 'gear postreceive' ( exit code: 1) remote: Error message: CLIENT_ERROR: Failed to execute: 'control post-receive' for /var/lib/openshift/546e36e5e0b8cd4e2a000007/jenkins-client remote: remote: For more details about the problem, try running the command again with the '--trace' option. To ssh : //546e36e5e0b8cd4e2a000007 @mywildfly-milestogo.rhcloud.com/~ /git/mywildfly .git/ d618fad..ff2de09 master -> master |
The key statement to note is that deployment is halted after the tests are failing. And you can verify this by revisiting mywildfly-milestogo.rhcloud.com/index.jsp and check that the updated “index.jsp” is not visible.
In short, tests pass, website is updated. And tests fail, the website is not updated. So you’ve built a simple deployment pipeline for Java EE 7 using WildFly, OpenShift, Arquillian, and Jenkins!
Reference: | Deployment Pipeline for Java EE 7 with WildFly, Arquillian, Jenkins, and OpenShift from our JCG partner Arun Gupta at the Miles to go 2.0 … blog. |