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.mywildfly> 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:
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:
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.
openshift org.apache.maven.plugins maven-war-plugin 2.3 false deployments ROOT jenkins-openshift maven-surefire-plugin 2.14.1 jenkins-openshift org.jboss.arquillian.container arquillian-openshift 1.0.0.Final-SNAPSHOT test 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:
<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:
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:
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:
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:
------------------------------------------------------- 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:
Nov 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:
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. |