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/


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:


Wednesday, July 29, 2015

Add Guava Cache to Spring Boot to Cache Method Calls


Add Google Guava Cache to Spring Boot to Cache the Results of Method Calls using Java Config and Spring Annotations



If you have a time-intensive method that is slowing down your application and the results of that method don't change very often, it is a good candidate for caching.  This guide will show you how to implement caching in your Spring Boot application using Google Guava cache.  

Guava cache is a simple, lightweight in-memory cache that has more configuration options then the default In-Memory Spring Cache.  Guava cache is not for clustered systems, for that you will want to use Hazelcast http://hazelcast.com/

So if you just need a simple cache but you want more config options such as cache expiration time, then this approach may fit your use case.  Alternatively, you could use EhCache.

Full source code references can be found at the bottom of the article.

More info on Guava Cache:
https://code.google.com/p/guava-libraries/wiki/CachesExplained

More info on Spring Cache:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html



Add dependencies to your Maven pom.xml file



Add the two following dependencies to your maven pom file and clean and package your dependencies.  You will need to add Guava and a Spring library that contains helper methods and classes for configuring the cache.

Add dependencies to your pom.xml for google guava cache and helper spring methods
Add dependencies to your pom.xml for guava cache

Create CacheConfig file



You need to create a CacheConfig file to configure the cache using Java config.  Create this config file as a separate class implementing CachingConfigurer and place it in your config folder with your other Java config classes.

Add Cache Manager and setup Guava Cache
Add Cache Manager and setup Guava Cache



Add Cacheable annotation to method to be cached



You will need to add the @Cacheable annotation and pass in the name of the cache which will be used for that method.

If your method has a passed in parameter, results for each different parameter will be cached.  So, each time a new parameter is passed in, this will execute the method and place the results in the cache.  Future calls using that parameter will pull results from the cache and skip execution of the method.

Add Cacheable annotation to the method to be cached
Add Cacheable annotation to the method to be cached





Add Endpoint to Clear Cache on Demand



You will also probably want to add an endpoint to easily refresh the cache.  You can do this by adding an endpoint to a controller with the @CacheEvict annotation.

This method will completely clear the cache.  All future requests will execute the method until the cache is populated again.

You may want to protect this endpoint using basic security implemented through Spring Security


Add an endpoint to clear the cache
Add an endpoint to clear the cache

Other considerations and Source Code



You may want to initially warm the cache and call the method with all possible parameters such that even initial users access the cached version.


You can view the complete source code here: https://gist.github.com/anataliocs/1074e7004b2c99320b7a




Friday, May 15, 2015

Spring Boot Internationalization with Default Locale for Message Strings

How to add Spring Boot Internationalization with Default Locale for Storing Message Strings such as Validation Messages in a message.properties file 


 This article will show you how to use a properties file to define static text in your application such as for validation message.

All the code is appended at the bottom of the article. 


Add Default locale and Message Source beans to your Application class 



 Add these classes to set your default locale and configure the location of your message properties file

 
Add beans to your Spring Boot Application class
Add locale and MessageSource beans to your Application Class


Add a Service and Interface to retrieve message text 


 This service will pull the default locale from the session and then get the message text from your properties file using the messageSource.

Create Service to get messages by locale
Add a service to get the msgs in your props file


In your controller, use the Message service to get the message text 


 You will inject the message service in the controller and then pass in the id to get the value from the props file


Inject svc and get message from i18n props file
Inject service into your controller and get the message



Create the message.properties file in the locale folder 


 In resources, create the locale folder and then create a file called messages_en_US.properties

Create localized message props file
Create message properties file



Review the code here


You can view all the code here: Link to Github Gist here

Thursday, May 7, 2015

Change Port on a Spring Boot Application when using intelliJ

Change Port on a Spring Boot Application when using intelliJ 



Two ways to change the port that the embedded Tomcat is using in a Spring Boot Application.

The first way is to modify the application properties in the resources folder:

Update application properties to change port
Update application props in Spring Boot Application



There are a couple issues with this approach.  You might only want this port change in your local environment and if you check it in by accident you might break things.


Alternatively, you can use a command line parameter.

Go to Run -> Edit Configurations -> VM options

Then enter in the following argument:

-Dserver.port=8090


Then click apply and OK and attempt to run the application again.

Update port on Spring Boot application using VM option
Update port using VM option



Tuesday, April 7, 2015

Convert Multiple Tasks to Sub-Tasks in JIRA similar to Bulk Update using Script Runner


How to Convert A Large Number of JIRA Tasks into Sub-Tasks using the Adaptavist Script Runner Plugin with JIRA



In JIRA, there is no way to convert Tasks into Sub-Tasks using the built-in Bulk Update functionality.  The lack of the feature is described in many JIRA tickets and Confluence posts on the official Atlassian site such as the two listed below:



There are many potential workarounds to this such as using selenium scripting to automate the conversion process using browser automation.  The best solution I have found is to use scripting within JIRA.





Backup your System




Before you attempt this, you should backup your JIRA instance because you potentially can make changes to tasks you did not intend.

Go to System settings and scroll down to the IMPORT & EXPORT section:

Use JIRA Backup functionality
Backup your JIRA instance




Install JIRA Adaptavist Scriptrunner




Download Adaptavist Scriptrunner

Get Adaptavist Scriptrunner:

https://marketplace.atlassian.com/plugins/com.onresolve.jira.groovy.groovyrunner


The file will be named something like this: groovyrunner-3.0.6.jar...

Upload and Install Scriptrunner
Upload your downloaded JIRA plugin as a JAR File
Upload your downloaded JIRA plugin as a JAR File






Open up Scriptrunner and run the script




Here is the script you want to run. This version uses a custom JQL query to find a comma delimited list of items that have certain values in a custom Functional Requirement field. It then loops through the list of issues and converts them to a subtasks then links the task to the parent task.
 
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.security.Permissions
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.issue.UpdateIssueRequest;


//Examples, 8 is my subtask issue type id. Will be different for others
//changeToSubTaskAndLink("AXDIS-509", "AXDIS-1045", "8")
//changeToSubTaskAndLink("AXDIS-509", "AXDIS-1046", "8")

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getUser()

//Add first function req here
//issueKey = 'AR-1231' for searching by id
def queryParamsString = "'Functional Requirement Id' ~ 5.3 " 

//Add all functional reqs after the first here
def functionalReqs = ['5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '5.10', '5.11', '5.12']

functionalReqs.eachWithIndex { a, i ->
  queryParamsString += " OR 'Functional Requirement Id' ~ " + a
  
}

def parentIdKey = "AR-2125"
def subTaskIssueTypeId = "5"

def query = jqlQueryParser.parseQuery("project = AR AND affectedVersion = "Phase 2" AND 'Business Requirement Id' ~ '5' AND (" + queryParamsString + ")")
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
 
results.getIssues().each {documentIssue ->
    //log.debug(documentIssue.key)
    // if you need a mutable issue you can do:
    def issue = issueManager.getIssueObject(documentIssue.id)
    // do something to the issue...
    //changeToSubTaskAndLink("AR-2125", "AR-1977", "5")
    changeToSubTaskAndLink(parentIdKey, documentIssue.key, subTaskIssueTypeId)
}

//Method to do all the work
def changeToSubTaskAndLink(parentId, childId, subTaskIssueTypeId)
{  //Get the parent Issue 
    def parent = ComponentManager.getInstance().getIssueManager().getIssueObject(parentId) 
 //Get the child Issue 
    MutableIssue child = (MutableIssue)ComponentManager.getInstance().getIssueManager().getIssueObject(childId) 
    //Change the child to the subtask type 
    child.setIssueTypeId(subTaskIssueTypeId) 
    
    
    
    //Update the issue 
    //ComponentManager.getInstance().getIssueManager().updateIssue() 
    ComponentAccessor.getIssueManager().updateIssue((ApplicationUser)ComponentManager.getInstance().jiraAuthenticationContext?.user, (MutableIssue)child, UpdateIssueRequest.builder().build())

    //Create the subtask link, if this is not done you'll end up with orphans 
    //ComponentManager.getInstance().getSubTaskManager().createSubTaskIssueLink(parent, child, ComponentManager.getInstance().jiraAuthenticationContext?.user) 
    ComponentAccessor.getSubTaskManager().createSubTaskIssueLink(parent, child, ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()) 
}

Wednesday, April 1, 2015

Tired Engineers: Welcome to the Future of Coffee Automation

Welcome to the Future of Coffee Automation


Introducing Brew().  A Coffee Automation system to initiate coffee brewing whenever your code quality starts to slip.

Brew detects when you start writing crappy code, brews you some coffee, and empowers you to PUT DOWN THE KEYBOARD AND PICK UP THE MUG!

The future of productivity for Software Engineers
The future of productivity for Software Engineers

Brew() will save your life and the lives of your team.  Engineers depend on it.


So what are you waiting for!?!?!

Learn more about brew here:  Brew()


Monday, February 2, 2015

Add Stormpath User Mgmt Dependencies to Grails

Add Stormpath User Mgmt Dependencies to Grails


How to add dependencies for Stormpath to your grails application.


In your BuildConfig.groovy in the dependencies section you need to add 3 dependencies.

These artifacts are up to date as of 2/2/2015 so you may need to look up the newest version here:  http://docs.stormpath.com/java/quickstart/


Here are the dependencies you need to add.

BuildConfig.groovy
 
dependencies {


        //Stormpath user mgmt
        compile 'com.stormpath.sdk:stormpath-sdk-api:1.0.RC3.1'
        runtime 'com.stormpath.sdk:stormpath-sdk-httpclient:1.0.RC3.1'
        runtime 'com.stormpath.sdk:stormpath-sdk-oauth:1.0.RC3.1'
    }


Here are the original Maven imports in XML format for reference:

<dependency>
    <groupId>com.stormpath.sdk</groupId>
    <artifactId>stormpath-sdk-api</artifactId>
    <version>1.0.RC3.1</version>
</dependency>
<dependency>
    <groupId>com.stormpath.sdk</groupId>
    <artifactId>stormpath-sdk-httpclient</artifactId>
    <version>1.0.RC3.1</version>
    <scope>runtime</scope>
</dependency>
<!-- This next runtime dependency is only necessary if you have
     a REST API and you want to secure it with OAuth: -->
<dependency>
    <groupId>com.stormpath.sdk</groupId>
    <artifactId>stormpath-sdk-oauth</artifactId>
    <version>1.0.RC3.1</version>
    <scope>runtime</scope>
</dependency>



Stormpath allows you to rely on their secure infrastructure so that you can focus on writing your application code:
https://stormpath.com/

I use Stormpath as a plugin with Heroku
http://heroku.com/