Automating Integration Tests with WebSphere Liberty and Maven

I spent some hours to figure out how to deploy my webapp to the Liberty from my Maven project.

I looked into the feature restConnector-1.0 . restConnector provides a REST based JMX MBeans interface to WebSphere Liberty.  You add  <feature>restConnector-1.0</feature> to your server, and make sure you have a user set in the admin role.

<administrator-role>
 <user>admin</user>
</administrator-role>

You need to add write access for the administrator-role user.  You’ll need to specify a relative path (use the Liberty Directory Locations) or use the absolute path (it’s a bit more complicated).

 <remoteFileAccess>
   <writeDir>${server.output.dir}/dropins</writeDir>
 </remoteFileAccess>

You can login and see the various APIs [ https://localhost:9443/IBMJMXConnectorREST/api ] or check the documentation [API1][API2][MBean]  .  You’ll want to check any upload with https://localhost:9443/IBMJMXConnectorREST/file/status

I used it with maven-antrun-plugin to execute against curl.

<plugin>
 <artifactId>maven-antrun-plugin</artifactId>
 <version>1.8</version>
 <executions>
 <execution>
 <id>upload-pre-integration</id>
 <phase>pre-integration-test</phase>
 <goals>
 <goal>run</goal>
 </goals>
 <configuration>
 <target name="post-war-to-server" unless="maven.test.skip">
 <!-- Remove War File from the Server -->
 <exec executable="curl">
 <arg
 line="-u 'admin:dmin' -H 'Content-Type: application/war' -X DELETE 'https://localhost:9443/IBMJMXConnectorREST/file/%24%7Bserver.output.dir%7D%2Fdropins%2Ftransformation.war?recursiveDelete=true' 
 --insecure -v" />
 </exec>
 <!-- Should check that this is a 204 -->
 
 <!-- Post the War file to the Server -->
 <!-- Expand the War file on the Server -->
 <exec executable="curl">
 <arg
 line="-u 'admin:admin' -H 'Content-Type: application/war' -X POST 'https://localhost:9443/IBMJMXConnectorREST/file/%24%7Bserver.output.dir%7D%2Fdropins%2Ftransformation.war?expandOnCompletion=true' 
 --data-binary '@target/example.war' --insecure -v" />
 </exec>
 
 </target>

 </configuration>
 </execution>
 </executions>
 </plugin>

Execute maven with mvn clean integration-test package in order to trigger the deployment during the integration-test.

Hamcrest Matchers Issue

I’ve been using Rest-Assured as a simple Integration Test tool for the last few months, and suddenly I started seeing this issue.

java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(ClassLoader.java:895)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:665)
at java.lang.ClassLoader.defineClass(ClassLoader.java:758)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.test.restassured.TestCode.testaCreateTenant(TestCode.java:128)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

I wiped my .m2 repository of org.hamcrest.Matchers jar files, and rebuilt the maven repository (mvn clean package install -DskipTests).   The problem remained.

I ran across a simple for my code (on the rest-assured site thanks to johanhaleby)

I changed the code to

import static org.hamcrest.CoreMatchers.equalsTo;

Now the code passes the tests without a problem

CURL and LDAPS – How to Search and Debug

I hit an issue where I needed to Search LDAP from a machine I didn’t have access to install new RPMs on. I found this cool article on CURL and LDAP Search. I had to make some minor modifications to get it to work with a secure connection (–insecure ldaps:// and 636). I also added -v to diagnosis some connection problems.

curl "ldaps://127.0.0.1:636/DC=IBM.COM?cn,objectClass?sub?(objectClass=)" -u "cn=user1,ou=test_org3,o=dr,DC=IBM.COM" --insecure -v
Enter host password for user 'cn=user1,ou=test_org3,o=dr,DC=IBM.COM':
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 636 (#0)
* LDAP local: LDAP Vendor = OpenLDAP ; LDAP Version = 20428
* LDAP local: ldaps://127.0.0.1:636/DC=IBM.COM?cn,objectClass?sub?(objectClass=
)
* LDAP local: trying to establish encrypted connection
DN: dc=ibm.com
objectClass: domain
objectClass: top

DN: o=dr,dc=ibm.com
objectClass: organization
objectClass: top

DN: ou=test_org3,o=dr,dc=ibm.com
objectClass: organizationalunit
objectClass: top

You can then find the userids you need quickly. I left them off the output intentionally.

If you see connected, but no results, I suggest changing to the top level of the ldap, and using this string – ldaps://127.0.0.1:636/DC=IBM.COM?cn,objectClass?sub?(objectClass=*)

JAX-RS Mapping All ClientExceptions with ExceptionMappers

As many of you know, I have been working with JAX-RS and WebSphere Liberty for a few years now. Somehow, after this time has passed, I still seem to uncover new JAX-RS capabilities.

For those familiar with JAX-RS, you know it generates some funky errors. I wanted to control the data in the response. I started looking at Servlet Filters, however, by the time you get the response it’s fully committed. I started looking at JAX-RS filters and exception handlers. I found ExceptionMapper and ClientErrorException. The WebSphere Liberty documentation includes a good overview.

I implemented the ExceptionMapper and set a custom response. You could add any of these exceptions – BadRequestException, ForbiddenException, NotAcceptableException, NotAllowedException, NotAuthorizedException, NotFoundException, NotSupportedException. I also added the @Provider annotation to the top of the class, and added a reference in the Application declaration.

I hope you all find this useful. Thanks!

Automation of IIB Maven and Ant

I have been working on a project with IIB (IBM Integration Bus). If you are like me, you want to automate all those pesky build tasks. In IIB, I needed to package and build my project (BAR).

I investigated scripting the build using the mqsipackagebar command . I noticed at the bottom a description of using it with ANT.

I’ve used ANT in a few projects (in combination with Maven). I took the script as a starting point, added the jar files and property files (based on configuring environments without IIB). I configured the maven-antrun-plugin in order to integrate within my parent project’s maven build.

Here is some sample code for you, I hope it helps you all get started:

Mysterious Entry in my Swagger Doc

Recently, I’ve been working with Swagger to document my team’s APIs, and had a mysterious entry popup (default/entity). It looks something like this:

Swagger
Swagger

I threw some tracing into action:

(io.swagger.*=ALL:*=INFO)
[6/7/16 7:51:24:912 EDT] 00000039 id= io.swagger.jaxrs.utils.ReaderUtils < collectParameters Exit 
 []
[6/7/16 7:51:24:912 EDT] 00000039 id= io.swagger.jaxrs.utils.ReaderUtils < collectFieldParameters Exit 
 []
[6/7/16 7:51:24:912 EDT] 00000039 id= io.swagger.jaxrs.utils.ReflectionUtils > isOverriddenMethod Entry 
 public javax.ws.rs.core.Response org.eclipse.persistence.jpa.rs.resources.MetadataResource.getMetadataCatalog(java.lang.String,java.lang.String,javax.ws.rs.core.HttpHeaders,javax.ws.rs.core.UriInfo)
 class org.eclipse.persistence.jpa.rs.resources.MetadataResource
[6/7/16 7:51:24:912 EDT] 00000039 id= io.swagger.jaxrs.utils.ReflectionUtils > isOverriddenMethod Entry 
 public javax.ws.rs.core.Response org.eclipse.persistence.jpa.rs.resources.MetadataResource.getMetadataCatalog(java.lang.String,java.lang.String,javax.ws.rs.core.HttpHeaders,javax.ws.rs.core.UriInfo)
 class org.eclipse.persistence.jpa.rs.resources.common.AbstractResource
[6/7/16 7:51:24:912 EDT] 00000039 id= io.swagger.jaxrs.utils.ReflectionUtils > isOverriddenMethod Entry 
 public javax.ws.rs.core.Response org.eclipse.persistence.jpa.rs.resources.MetadataResource.getMetadataCatalog(java.lang.String,java.lang.String,javax.ws.rs.core.HttpHeaders,javax.ws.rs.core.UriInfo)

I had too broad a dependency in my Maven pom.xml. I switched from eclipselink to org.eclipse.persistence.jpa.

<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.3</version>
</dependency>

The swagger entries disappeared from my swagger.yaml and it’s subsequent view.   I hope this helps.

Localized Maven Repositories – A Hot Tip

I’ve been building a Maven Project that uses some jar files which are not in Maven Central (or any repository). I ran across this article – Local Maven Dependencies. I found it very helpful.

Simply, do the following:

create a directory (d:/folder/repo)

Run a maven deploy to url (it’ll create the repository details based on the flags)

mvn deploy:deploy-file -Durl=file://d:/folder/repo/ -Dfile=Common.jar -DgroupId=xyz -DartifactId=Common -Dpackaging=jar -Dversion=1.0

and add to your Maven Project’s POM
<repository>
<id>Local Repository</id>
<name>project</name>
<url>file:${project.basedir}/../mylibrary.project/src/repo</url>
</repository>

Then reference your jar file with a new dependency.

The code should almost write itself from there 🙂