Monday, September 26, 2016

Integrate Wiremock into Spring Boot Java Web Application for Mocking External Dependencies


Introduction

WireMock is a mock server for HTTP-based APIs. Some might consider it a service virtualization tool or a mock server. It enables you to stub out an API or other external dependency you depend on to expedite local development. It supports testing of edge cases and failure modes that the real API won't reliably produce. It also is useful in mocking out external dependencies in unit and integration tests. It has excellent integration with jUnit.

Add Wiremock Dependency

First you will want to add the Wiremock dependency. You can download the regular dependency or the fat JAR stand-alone version that contains all it's dependencies. We will be using the standard dependency here. Add the following dependency to your build.gradle

build.gradle


dependencies {
    testCompile('com.github.tomakehurst:wiremock:2.1.12')
}



Add Wiremock Unit test

Here is the complete unit test that you can use for testing your integration with Wiremock. This unit test uses a jUnit4 rule to spin up a Wiremock server on port 8089 and shut it down after each test. We use the stubFor method to define a mocked end point and the response. We use a Spring RestTemplate to create a HTTP request to our mock server and capture the result.

WiremockTests.java

public class WiremockTests {

    RestTemplate restTemplate;
    ResponseEntity response;

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(8089).httpsPort(8443));

    @Before
    public void setup() throws Exception {
        restTemplate = new RestTemplate();
        response = null;
    }

    @Test
    public void givenWireMockAdminEndpoint_whenGetWithoutParams_thenVerifyRequest() {

        RestTemplate restTemplate = new RestTemplate();

        response = restTemplate.getForEntity("http://localhost:8089/__admin", String.class);

        assertThat("Verify Response Body", response.getBody().contains("mappings"));
        assertThat("Verify Status Code", response.getStatusCode().equals(HttpStatus.OK));
    }

    @Test
    public void givenWireMockEndpoint_whenGetWithoutParams_thenVerifyRequest() {
        stubFor(get(urlEqualTo("/api/resource/"))
                .willReturn(aResponse()
                        .withStatus(HttpStatus.OK.value())
                        .withHeader("Content-Type", TEXT_PLAIN_VALUE)
                        .withBody("test")));

        response = restTemplate.getForEntity("http://localhost:8089/api/resource/", String.class);

        assertThat("Verify Response Body", response.getBody().contains("test"));
        assertThat("Verify Status Code", response.getStatusCode().equals(HttpStatus.OK));

        verify(getRequestedFor(urlMatching("/api/resource/.*")));
    }
}



Drill down into Unit Test

Here are some static imports you can use for readability and conciseness in your test.

WiremockTests.java

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;



jUnit4 Rule

This jUnit4 @rule will automatically manage the Wiremock server lifecycle and startup and shutdown Wiremock for each test case. You would also be able to implement this using a setup() and teardown() method but the jUnit4 rule is cleaner and more concise.

WiremockTests.java

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(8089).httpsPort(8443));



Stubbed Endpoint and Response

This code uses the stubFor() method which has been statically imported to define an endpoint, /api/resource/ and the plain text response body "test" You could return a JSON or XML response using this method as well by changing the Content-Type and response body

WiremockTests.java

        stubFor(get(urlEqualTo("/api/resource/"))
                .willReturn(aResponse()
                        .withStatus(HttpStatus.OK.value())
                        .withHeader("Content-Type", TEXT_PLAIN_VALUE)
                        .withBody("test")));



Spring RestTemplate

We use a Spring RestTemplate class to execute a GET HTTP request to http://localhost:8089/api/resource/ hitting the stubbed endpoint of the wiremock server. We are expecting a String.class entity response in this case because that is what we defined in the stubFor() method. You would need to define a POJO object to capture a JSON response from your stubbed out method if that is what you configured. We capture the response in a ResponseEntity object which captures the response body, headers and status code as well as other information about the request.

WiremockTests.java

response = restTemplate.getForEntity("http://localhost:8089/api/resource/", String.class);



Starting and Stopping the Wiremock Server Manually

You can start and stop a Wiremock server manually without using a jUnit4 rule to manage the lifecycle. You may want to do this is a bootstrap method when your application starts up.

ServiceClass.java

WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089)); //No-args constructor will start on port 8080, no HTTPS
wireMockServer.start();

WireMock.reset();

wireMockServer.stop();



Conclusion

You now have Wiremock setup in your project. You can use Wiremock in unit and integration tests to stub externally dependencies and also to speed up development in your local environment. You can read more about setting up Wiremock here: http://wiremock.org/docs/getting-started/

Monday, August 29, 2016

Error with Gradle Build SonarQube Plugin Registering Findbugs Plugin

How to Fix the Error: Unable to register extension org.sonar.plugins.findbugs.FindbugsConfiguration when Running Gradle sonarqube task



Using Gradle, Sonarqube and Findbugs you may get the following error when you try to execute the command:

./gradlew clean build sonarqube


Here is the error:

FAILURE: Build failed with an exception.
* What went wrong:Execution failed for task ':sonarqube'.> Unable to register extension org.sonar.plugins.findbugs.FindbugsConfiguration
* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED


Root Cause


This bug seems to occur when there is a mismatch of versions that don't play nice together.

For instance here are the versions of our stack:

  • Sonar Version: 5.3
  • SonarQube Gradle Plugin:  2.0.1

Update Findbugs plugin on Sonar:


First, we had to update our Sonar server:


Navigate to the Update Center
Navigate to the Sonar Update Center to update the findbugs plugin
Navigate to the Sonar Update Center



Update the findbugs plugin and restart the sonar instance
Update findbugs plugin and restart sonar
Update findbugs plugin

Update your Gradle Dependencies:



Update the sonarqube Gradle Plugin

Update sonarqube dependency

 
dependencies {
     classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.1-rc1"
}


Update sonar version
 
sonarqube {
     version='2.1-rc1'
}

Update sonar-findbugs-plugin

dependencies {
     compile: 'org.codehaus.sonar-plugins.java', name: 'sonar-findbugs-plugin', version: '3.2'
}



Update Findbugs

Update findbugs dependency
dependencies {
     compile: 'com.google.code.findbugs', name: 'findbugs', version: '3.0.1'
}

Update Findbugs version
findbugs {
     toolVersion = "3.0.1"
     ignoreFailures = true
     sourceSets = [ project.sourceSets.main ]
}

Monday, August 22, 2016

Install a Local Instance of AWS DynamoDB



STEP 1:  Press Command+Space and type Terminal and press enter/return key.
STEP 2:  Install Brew(If you don't already have it installed.)  Run this command in the Terminal app.

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
and press enter/return key.
Wait for the command to finish.
STEP 3:  Use Brew to install and download dynamoDB so that you can run it locally.
brew install dynamodb-local

Launch your DynamoDB local instance like this:
To have start dynamodb-local now and restart at login as a background service using brew services:
  brew services start dynamodb-local
Or, if you don't want/need a background service you can just run:
  /usr/local/bin/dynamodb-local

You can then access a JS Shell in a browser such as Chrome:
URL to hit the Javascript shell for your locally running DynamoDB instance:
http://localhost:8000/shell/

This is what you will see what you load up your DynamoDB Shell.  If you see this, then you are successfully running a local instance of DynamoDB!

AWS Local DynamoDB Javascript Shell in Browser
AWS Local DynamoDB Javascript Shell in Browser


Common DynamoDB Concepts
  • Table:  A collection of data
  • Items: An item is a group of attributes that is uniquely identifiable among all of the other items.
  • Attributes: An attribute is a fundamental data element, something that does not need to be broken down any further.
  • Primary Key
    • Partition Key:  Composed of one attribute known as the partition key
    • Partition Key and Sort Key: Composite primary key, composed of two attributes.

Datatypes
Scalar
  • Number:  String
    • Example:  "N": "123.45"
  • String:  String
    • Example:  "S": "Hello"
  • Binary:  Base64-encoded binary data
    • Example:  "B": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk"
  • Boolean:  Boolean
    • Example:  "BOOL": true
  • Null:  Boolean
    • Example:  "NULL": true
Multi-value
  • String Set:  Array of Strings
    • Example:  "SS": ["Giraffe", "Hippo" ,"Zebra"]
  • Number Set:  Array of Strings
    • Example:  "NS": ["42.2", "-19", "7.5", "3.14"]
  • Binary Set:  Array of Base64-encoded binary data
    • Example:  "BS": ["U3Vubnk=", "UmFpbnk=", "U25vd3k="]

Document
  • List: array of AttributeValue objects
    • Example:  "L": ["Cookies", "Coffee", 3.14159]
  • Map:  String to AttributeValue object map
    • Example:  "M": {"Name": {"S": "Joe"}, "Age": {"N": "35"}}

Tuesday, August 2, 2016

Suppress FindBugs Warnings in a Java and Spring Boot Web Application using Gradle

How to Suppress FindBugs Warnings using Annotations in a +Spring Boot and +Java Application



If your build is breaking because of a FindBugs issue and it is a false-positive or you are unable to resolve the issue because of other considerations, you can add an Annotation to ignore the Findbugs warning.


Update your Gradle Dependencies


You will want to add the following compile time dependency to your build.gradle file.

compile group: 'findbugs', name: 'findbugs', version: '1.0.0'

dependencies {

    compile group: 'findbugs', name: 'findbugs', version: '1.0.0'
}


Get the Findbugs Issue ID

You will need a specific ALL_CAPS identifier so that FindBugs knows what bug to ignore.


Locate the FindBugs Report


In your build message, you will see a link to the findbugs report:



You can also find the report in your build artifact.  Right-click and open in your preferred browser to view file.
find bugs html report in build artifact
Open the findbugs html report from the build directory


Open the FindBugs Report


Once you have it, open the Findbugs HTML report in a browser.  It should look like the following.

findbugs html report for java issues
Find Bugs HTML Report

Get the FindBugs identifier


Copy and paste the FindBugs identifier.  It should be in ALL_CAPS.

You will use the annotation like this:
@SuppressWarnings("OUT_OF_RANGE_ARRAY_INDEX")

Add the Annotation to Your Code


Be sure that the correct findbugs SuppressWarnings annotation is being used.

import edu.umd.cs.findbugs.annotations.SuppressWarnings;


Add Suppress warnings annotation


Add this Suppress warnings annotation above the offending line of code.  There are multiple versions of this annotation.

Be sure to use the specific FindBugs issue ID as a parameter in the annotation.


Be sure to use the annotation specific to findbugs in the package edu.umd.cs.findbugs.annotations.

Suppress warnings annotation
Use the edu.umd.cs.findbugs.annotation version of @SuppressWarnings


This is the annotation you will want to add above the offending line of code.

@SuppressWarnings("OUT_OF_RANGE_ARRAY_INDEX")



Re-run the Build to Verify that the Warning is being Suppressed


You want to ensure that the warning is being ignored correctly.  You may want to add a TODO as well if you intend to fix the issue at a later point as well or at least track the issues you are suppressing in some way.

Your build should run successfully without issuesmoving forward now.



Further info:




Saturday, December 5, 2015

Whirlwind Tour of JavaOne and Oracle Openworld 2015

JavaOne 2015 Roundups and Summary Articles



I recently had the wonderful opportunity of attending JavaOne and Oracle Openworld 2015 and have extensively blogged about the social and technical aspects of the conference!

Get a taste of the many events and exhibits on display and an insider's view on the conference.  I will also be presenting the most important takeaways regarding the future direction of Java including an in-depth discussion of changes coming in Java 9 and how to best prepare for those upcoming changes.

If you are local to the Richmond,VA then check out our meetup on the topic!




JavaOne 2015 Day 1 Roundup




JavaOne 2015 Day 2 Roundup




JavaOne 2015 Day 3/4 Roundup





More Pictures of JavaOne 2015



You can find more pictures of the event in our JavaOne 2015 Album here: JavaOne 2015

We had a great time celebrating 20 years of #java at the JavaOne Conference and Oracle OpenWorldBig thanks to Atlassian for providing refreshments at Duke's Cafe and Buzzhouse#JavaOne #JavaOne2015 #oow15

Posted by Ippon Technologies USA on Tuesday, November 3, 2015

Whirlwind tour of Javaone Meetup





Slides





Link to slides: Slides for RJUG JavaOne meetup

Friday, September 11, 2015

Running a new jHipster Application using Compass and the main CSS file is not loading

How to fix a Newly Created jHipster Application not Loading the Main CSS File 


If you see an error similar to the following upon first startup of a jHipster application you have just created:

Failed to load resource: the server responded with a status of 404 (Not Found) http://127.0.0.1:8080/assets/styles/main.css


Issue loading main.css on jHipster application
jHipster with CSS not loaded


Then you will need to run the grunt task, grunt compass.


Install Compass

You will need to first install Compass, an open-source CSS Authoring Framework before you can run the Grunt task to create the main.css file which is missing.

Using node:

npm install compass

Reference the following link for more info about installing compass using npm


Run Grunt Task


After you install Compass, you will then need to run the grunt task.  In in IntelliJ you can click the grunt task runner at the bottom of your screen or go to Tools -> Open Grunt Console.

Use grunt task runner console to create Main CSS file
Run grunt compass task to create main.css file

Restart your Application


Try refreshing and restarting your application and the styling should now display correctly.

mvn spring-boot:run

Saturday, August 15, 2015

Spring Scheduler to Create Background Process to make Async Calls to Update Cache in Spring Boot


Using Spring Scheduler to Create a Scheduled Task that hits your Endpoints to Update a Spring Cache for a Spring Boot Application



I used Spring Scheduler to execute a process on a regular basis to make separate async calls to several endpoints to keep the Spring cache updated and also as a health monitor.

This serves two purposes for us, we monitor all the endpoints to ensure correct data is coming back and it keeps the caches fresh and up to date even when there hasn't been traffic on that endpoint recently.

Guides on how to setup Spring caching:


Guide on Spring Scheduler:  http://spring.io/guides/gs/scheduling-tasks/


View all the code used in this article on Github here:


Spring Scheduler



You will want to add 3 annotations to your Application.java class.  You will need to add annotations for caching, async method calls and scheduling.

Add annotations to your Application.Java class for caching, async and scheduling
Add annotations to your Application.Java class

Create Scheduled Task



I created a scheduled task here and set the interval that it runs on using Spring Scheduler and the @Scheduled annotation.

The task calls a method which is async and cached which allowed me to call multiple endpoints concurrently.  The results of the method call were cached and the success was logged.

I also injected the service to call the async method we are using to get the status of various endpoints.



Create Service for Scheduled Task to use



Get endpoint status is the method called directly from the scheduled task.  You can pass in a constant or enum to indicate which endpoint you want to check.  Each endpoint will be cached separately because the parameters in the method call are different.

You will need to setup caching in a separate config file.  You can view this article on how to setup Spring caching:  http://codedevstuff.blogspot.com/2015/07/add-guava-cache-to-spring-boot-to-cache.html

Get endpoint status will then call the correct getStatus() method to check the results of the endpoint.  These results will be cached.



This scheduled task can be used with an API or service to regularly check the status and response of various endpoints for health checking or as a regular running integration test of sorts.

View full code below



View the code on Github here:

Code snippets below: