DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Integrating AWS With Salesforce Using Terraform
  • Structured Logging
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early

Trending

  • Integrating AWS With Salesforce Using Terraform
  • Structured Logging
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early
  1. DZone
  2. Coding
  3. Java
  4. Your Tests Assume That JBoss is Up and Running

Your Tests Assume That JBoss is Up and Running

Antonio Goncalves user avatar by
Antonio Goncalves
·
Jul. 24, 14 · Interview
Like (0)
Save
Tweet
Share
12.22K Views

Join the DZone community and get the full member experience.

Join For Free

as a java ee developer i tend to mix unit tests with integrations tests, usually using arquillian . but sometimes, for obscure reasons, arquillian cannot do the job (let’s say the packaging of the application to test is too obscur). so i want to deploy my application, and then, execute some tests. but what i really want is my tests to be executed if and only if the web application is deployed, if not, the tests are skipped. in other words, i want my jenkins to automatically fail if there is no jboss . for that i can use the jboss http management api and the junit assumptions .

use case

testing a web application on jboss let’s say i have a java ee application with a simple html page (index.html), a servlet (myservlet.java) and a rest endpoint (myrestendpoint.java). once packaged in a war (samplejavaeejbossutil.war) and deployed on jboss, i want to check all the different urls and http response code (i.e. is the servlet deployed and running, is the rest endpoint up and running…).

so this is the code of this very simple servlet

@webservlet(urlpatterns = "/myservlet")
public class myservlet extends httpservlet {
 
    public void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
        try {
            response.getwriter().println("hello from the rest endpoint");
        } catch (exception e) {
            e.printstacktrace();
        }
    }
}

and this is the code that uses jax-rs 2.0 client api to test the servlet just by pinging the url (i could have done something more clever, but that’s not the point of this post.

public class urltest {
 
    @test
    public void checkstheservletisdeployed() throws exception {
 
        client client = clientbuilder.newclient();
        webtarget target = client.target("http://localhost:8080/samplejavaeejbossutil").path("myservlet");
        assertequals(response.status.ok.getstatuscode(), target.request(mediatype.text_plain).get().getstatus());
    }
}

i execute the test while the application is deployed and jboss is up and running, and the test is green. as you can imagine, if i shutdown jboss or undeploy the application, the test fail. in this case, what i really want, is to ignore the test.

jboss admin cli

so let’s say the web application is deployed, jboss is up and running, everything is fine… let’s check all that with the jboss cli . you will find this command line interface under $jboss_home/bin/jboss-cli.sh. when you execute it, you connect to jboss and enter a few commands to get the status of the server and other components (i.e. datasource, jms factories…). the following commands check that jboss is up and running and also that oursamplejavaeejbossutil.war is deployed:

$ ./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 /] connect
[standalone@localhost:9990 /] :read-attribute(name=server-state)
{
    "outcome" => "success",
    "result" => "running"
}
[standalone@localhost:9990 /] /deployment=samplejavaeejbossutil.war:read-attribute(name=status)
{
    "outcome" => "success",
    "result" => "ok"
}

jboss admin rest api

on top of the command line interface, jboss also has a rest interface for administration. so all the commands you type on cli have an http equivalent. so to know if jboss is up and running and if the samplejavaeejbossutil.war is deployed we can just go to a browser and type the following urls:

http://localhost:9990/management?operation=attribute&name=server-state
 
 
http://localhost:9990/management/deployment/samplejavaeejbossutil.war?operation=attribute&name=status

notice that the jboss administration apis are under http://localhost:9990/management . then, it’s just a matter of passing certain paths (e.g. deployment) or query parameters (e.g. operation=attribute)). if you type these urls in a browser, you will also notice that you need to login as an administrator (first you need to create a user/password with the $jboss_home/bin/add-user.sh utility).

jboss administration apis need digest authentication

so what if you don’t want to use a browser but instead use the jax-rs 2.0 client api to connect to it? let’s first use curl to see what it tells us.

~$ curl http://localhost:9990/management -v
* about to connect() to localhost port 9990 (#0)
* connected to localhost (127.0.0.1) port 9990 (#0)
> get /management http/1.1
> user-agent: curl/7.30.0
> host: localhost:9990
> accept: */*
>
< http/1.1 401 unauthorized
< connection: keep-alive
< www-authenticate: digest realm="managementrealm",domain="/management",algorithm=md5
< content-length: 77

as you can see on the output on line number 11, the jboss administration apis need digest authentication. so, supposing that the user and password are admin/admin, you need to enter the following:

~$ curl --digest 'http://admin:admin@localhost:9990/management' -v
* about to connect() to localhost port 9990 (#0)
* connected to localhost (127.0.0.1) port 9990 (#0)
* server auth using digest with user 'admin'
> get /management http/1.1
> user-agent: curl/7.30.0
> host: localhost:9990
> accept: */*
>
< http/1.1 401 unauthorized
< connection: keep-alive</pre>
< www-authenticate: digest realm="managementrealm",domain="/management",algorithm=md5
< content-length: 77
<
* ignoring the response-body
* issue another request to this url: 'http://admin:admin@localhost:9990/management'
* connected to localhost (127.0.0.1) port 9990 (#0)
* server auth using digest with user 'admin'
> get /management http/1.1
> authorization: digest username="admin", realm="managementrealm", uri="/management", algorithm="md5"
> user-agent: curl/7.30.0
> host: localhost:9990
> accept: */*
>
< http/1.1 200 ok
< connection: keep-alive
< authentication-info: nextnonce="mjnypxk1uwinmtqwntgwnda2mtmzmhie0+sv9v15urc9i8n075w="
< content-type: application/json; charset=utf-8
< content-length: 2189
<
* connection #0 to host localhost left intact

as you can see, when using digest authentication, the output is much more verbose and the outcome is a return code 200 (instead of just 401). so now we have the two important ingredients to access the api with rest : we know how the urls look like, and we know we need to use digest authentication. so let’s see how to do it.

jax-rs client api to access the jboss management api

jax-rs 2.0 has a very nice client api. if we want to check if jboss is up and running, what we need to do is access the url http://localhost:9990/management?operation=attribute&name=server-state and check that it returns"running". with jax-rs this is as simple as writing :

public static boolean isjbossupandrunning() {
 
    client client = clientbuilder.newclient();
    webtarget target = client.target("http://localhost:9990/management").queryparam("operation", "attribute").queryparam("name", "server-state");
    response response = target.request(mediatype.application_json).get();
    return response.getstatus() == response.status.ok.getstatuscode() && response.readentity(string.class).contains("running");
}

but unfortunately, this won’t work because it will return a 401 (unauthorized). we need to authenticate using the digest scheme. how do we do that in jax-rs 2.0? well, we can’t :o( the only trick i found (thanks to bill burke and arun gupta ) is using the apache http client and an extension of resteasy . so in the code below, the getclientmethod returns an authenticated httpclient which is then used to access the jboss administration rest apis.

public class jbossutil {
 
  private static resteasyclient getclient() {
    // setting digest credentials
    credentialsprovider credentialsprovider = new basiccredentialsprovider();
    usernamepasswordcredentials credentials = new usernamepasswordcredentials("admin", "admin");
    credentialsprovider.setcredentials(authscope.any, credentials);
    httpclient httpclient = httpclientbuilder.create().setdefaultcredentialsprovider(credentialsprovider).build();
    apachehttpclient4engine engine = new apachehttpclient4engine(httpclient, true);
 
    // creating http client
    return new resteasyclientbuilder().httpengine(engine).build();
  }
 
  public static boolean isjbossupandrunning() {
 
    webtarget target = getclient().target("http://localhost:9990/management").queryparam("operation", "attribute").queryparam("name", "server-state");
    response response = target.request(mediatype.application_json).get();
    return response.getstatus() == response.status.ok.getstatuscode() && response.readentity(string.class).contains("running");
  }
}

here, i’ve simplified the code (no exception handling) and i’m only showing the method isjbossupandrunning. but you can check the full jbossutil class on github , i’ve created other methods.

the test class

coming back to our use case, we now have all the pieces of the puzzle. we know how to check that jboss is up and running (we could even check that the web application is actually deployed ) and we can use the junit assumptions . the following test will only be executed if and only if jboss is up and running. if not, the test will automatically be ignored, thanks to the assume api.

public class urltest {
 
    @test
    public void checkstheservletisdeployed() throws exception {
        assume.assumetrue(jbossutil.isjbossupandrunning());
 
        client client = clientbuilder.newclient();
        webtarget target = client.target("http://localhost:8080/samplejavaeejbossutil").path("myservlet");
        assertequals(response.status.ok.getstatuscode(), target.request(mediatype.text_plain).get().getstatus());
     }
}

conclusion

unit testing is important, but when you execute your code within a container, integration tests are also very useful. arquillian solves most of the problems and simplifies integration testing, but other technics can also be used. the main ambition of our build system is to pass all the tests… or ignore some. with junit assumptions and some rest apis, our tests can be knowledgeable and executed only if the container is up and running, if the web application is deployed, or if the datasource is actually enabled. download the code , give it a try, and let me know what you think.

and thanks to bill burke , arun gupta , alexis hassler and christos vasilakis for their help and tips.

references

  • jboss forum
  • jboss http management api
  • jboss management model
  • using digest authentication
  • jboss command line interface
  • cli recipes
JBoss unit test

Published at DZone with permission of Antonio Goncalves, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Integrating AWS With Salesforce Using Terraform
  • Structured Logging
  • Introduction To Git
  • Authorization: Get It Done Right, Get It Done Early

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: