Enterprise Java

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!

  1. 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
  2. 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)
  3. 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:

    1. “openshift” profile is used when building an application on OpenShift. This is where the application’s WAR file is created and deployed to WildFly.
    2. A new profile “jenkins-openshift” is added that will be used by the Jenkins instance (to be enabled shortly) in OpenShift to run tests.
    3. “arquillian-openshift” dependency is the same as used in Tech Tip #55 and allows to run Arquillian tests on a WildFly instance on OpenShift.
    4. 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.

  4. 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 is mywildflytest, and SSH user name is 546e3743ecb8d49ca9000014. These will be passed to Arquillian for running the tests.

  5. Second is to enable and configure Jenkins.In your OpenShift Console, pick the “mywildfly” application and click on “Enable Jenkins” link as shown below:
     
    techtip56-enable-jenkinsRemember 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.
  6. 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.

  7. 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:
     
    techtip56-mywildfly-output-tests-passing

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!

Arun Gupta

Arun is a technology enthusiast, avid runner, author of a best-selling book, globe trotter, a community guy, Java Champion, JavaOne Rockstar, JUG Leader, Minecraft Modder, Devoxx4Kids-er, and a Red Hatter.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button