Aspect Oriented Spring

11 06 2016

Aspect Oriented Programming is a powerful technique to separate cross-cutting concerns (aspects) in your application apart from your logic.

Where is it used?

Spring uses it widely. Popular use case is Spring Security where each controller needs to have restricted access. It would make no sense to embed the security logic in each controller method. That is where aspects are useful. Thanks to AOP you can keep your aspect  related logic (called Advice) in one place and just define the points (joint points) where that logic should be run.

What is possible with Spring AOP

Spring AOP allows you to define the joint points on a method level by a means of dynamic proxies. It means that you can define in your advice that it should run before, after or around any method of your choice.

And if I need more?

Method interception will probably be enough for majority of your needs. However if you need more (constructor or field interception) you can use another AOP implementation: AspectJ.

How to Code it?

I coded the demo for you. Go ahead and check it out on my GitHub: https://github.com/yacekmm/looksok/tree/AopDemo/Spring/SpringAOP

1. The dependency
First of all I’m gonna use the spring-boot-starter-aop pom and include it in my dependencies:

compile("org.springframework.boot:spring-boot-starter-aop:1.3.5.RELEASE")

2. The controller with advised method
I use the annotation to define the joint point. This is the annotation I created:

public @interface MyAnnotation {}

No I can create sample controller method and annotate it with MyAnnotation:

@RestController
public class MyController {

    private Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    @RequestMapping(value = "/api/my-resource")
    @MyAnnotation
    public String getMyResource(){
        log.info("Returning the resource");
        return "Your resource is here";
    }
}

After running the app I can head over to http://127.0.0.1:8080/api/my-resource to see that it returns the result and logs the message.

3. Define an Aspect (advice)
Time to define your aspect! Create a class annotated with @Aspect and a method that will be run before the methods annotated with @MyAnnotation. Use @Before annotation with parameter pointing to the MyAnnotation class:

@Aspect
@Configuration
public class MyResourceAdvice {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Before("@annotation(pl.looksok.spring.aop.MyAnnotation)")
    public void performImportantJob(){
        log.info("Performing important job in an advice method");
    }
}

@Configuration is needed for Spring to include that class in scans.

4. Check the results

After these few steps you can go to http://127.0.0.1:8080/api/my-resource and watch that in app logs there is controller’s log and Advice log before it:

eAdvice$$EnhancerBySpringCGLIB$$9dc59d93 : Performing important job in an advice method
p.l.spring.controller.MyController       : Returning the resource

You can also note that my aspect class is logged as EnhancerBySpringCGLIB – my controller class was dynamically proxied by cglib.

Tip 1: Readable @Before
If you don’t like the long @Before annotation param you can make it more readable by extracting it as a @Pointcut like that:

@Pointcut("@annotation(pl.looksok.spring.aop.MyAnnotation)")
    private void annotatedWithMyAnnotation() {}

    @Before("annotatedWithMyAnnotation()")
    public void performImportantJob(){
        log.info("Performing important job in an advice method");
    }

By defining @Pointcut you made your @Before definition much more readable. Note that @Pointcut method name may be any of your choice.

Tip 2: Help Spring to find your joint points
Where does the Spring look for annotated methods? Everywhere on your classpath. Do you need to scan all classes? If not, then you can narrow scanned packages:

    @Pointcut("within(pl.looksok.spring.controller.*)")
    private void searchWithinControllersOnly() {}

    @Pointcut("@annotation(pl.looksok.spring.aop.MyAnnotation)")
    private void annotatedWithMyAnnotation() {}

    @Before("annotatedWithMyAnnotation() && searchWithinControllersOnly()")
    public void performImportantJob(){
        log.info("Performing important job in an advice method");
    }
Advertisements




Recent ThoughtWorks Tech Radar

7 05 2016

If you were wondering whether the technology, trend or tool is worth investing your time and effort, the Tech Radar by ThoughtWorks may help you making the decision.

The analysis is based on observations and predictions. New editions come periodially and here is always the recent one: https://www.thoughtworks.com/radar

Some highlits that interested me the most in that edition:

Tools

  • Jenkins 2.0 as deployment pipeline is on hold – still the build pipeline generation is not a first-class-citizen since it is still based on plugins. Authors says that it could be done better. I suppose that it recommendation considers only the pipeline, not the CI itself
  • Apache Kafka is on trial – although quite widely used in industry. Authors have a pragmtic approach building the report

Languages & Frameworks

  • Spring Boot to adopt – seems to be obvious choice right now, so those who bet on it few years ago were right (lucky me!)
  • React.js to adopt – as a JS framework with one-way binding, providing the loose coupling on the front side

Platforms

  • Docker! Docker! Docker!

Techniques

  • GitFlow on hold! That’s right. Authors noted that feature branches tend to stand away from master / develop branch for too long. That causes the merge / integration problems. So the point is to use GitFlow wisely. Feature branch and merge request that have 2 days of coding in it are far too big.




Java equals() vs. compareTo() contract

1 05 2016

The definitions

Object’s equals(Object obj) method:

Indicates whether some other object is "equal to" this one

compareTo(T t) is an abstract method from Comparable interface and it:

Compares this object with the specified object for order. 
Returns a negative integer, zero, or a positive integer 
as this object is less than, equal to, or greater than the specified object.

The contract

That being said here seems to appear the contract between those two methods: compareTo should return 0 if equals returns true. This is yet another contract that the equals() is involved (mind the hashCode()). In fact the Comparable JavaDoc says it clearly:

It is strongly recommended, but not strictly required that 
(x.compareTo(y)==0) == (x.equals(y)).

Since it is not strictly required, the JavaDoc clears out things and says:

Generally speaking, any class that implements the Comparable interface 
and violates this condition should clearly indicate this fact. 
The recommended language is: 
"Note: this class has a natural ordering that is inconsistent with equals."

Natural ordering

A class should implement Comparable interface if it is eligible to natural ordering. Natural ordering is perceived as an order where an object can be compared to another of the same type (alphabetical comparison for String, numerical for Number or any other specific to your domain).

If your class does not have a natural ordering that is consistent with equals() but you still need to sort it, you should consider using the Comparator interface instead of Comparable.

In fact the String class follows the equals() and compareTo() contract and it sorts Strings alphabetically according to ASCII characters ordering. Note that this ordering sorts lowercase letters in front of upper case.

The BigDecimal breaks the contract

The BigDecimal class violates the recommendation and its equals() is not consistent with compareTo() in  a matter of a scale. The documentation clearly states it:

according to equals(): 2.0 is not equal to 2.00
according to compareTo(): 2.0 is equal to 2.00

Why? Who knows. There are discussions that in physics for example the 2.0 definetely should not be considered as equal to 2.00 due to the precision. However in most of the domains the values can be considered as equal.

Problems when violating the contract

The problem that arises is for example putting the BigDecimal in a HashSet:

Set<BigDecimal> set = new HashSet<>();
set.add(new BigDecimal("0.20"));
...
if (set.contains(new BigDecimal("0.2")) { // Returns false, but should return true
    ...
}

Because of that the HashSet is usable with BigDecimal if you define the scale that its elements have. So if you put the number with two digits precision, you should always look for two digits precision as well.

The other solution is to use TreeSet, since it uses the compareTo() to search for elements (ignoring the scale). However the TreeSet is sorted as opposed to the HashSet. If you do not need sorting then you ahve to consider whether it hurts your performance (putting an element to the sorted set is more expensive – due to the sorting).





How to run jMeter tests on Jenkins

24 04 2016

If you monitor your system performance with Apache jMeter test suite, you can easily make it a part of your Continuous Integration and monitor the performance on a regular basis. You need to do three things:

  1. Put your Apache jMeter binary files on Jenkins machine
  2. Run jMeter tests in headless mode from Jenkins job, generating the xml test report
  3. Analyze reports with Jenkins Performance Plugin

Let’s get into details!

1. Put your jMeter binaries on Jenkins

Apache jMeter does not require installation so you can just copy the files that you currently use to the Jenkins server. Thanks to it you will have all the plugins ready to use. Then make sure that user that runs jenkins has access rights to execute jMeter.

2. Run jMeter tests from Jenkins job

Create Jenkins job and, as a Build Step, Execute Shell commands:

#remove previous reports
rm jMeter/reports/*.jtl -f

#run tests
$JMETER_PATH/jmeter -n 
     -t jMeter/suites/sampleSuite.jmx 
     -l jMeter/reports/sampleSuiteReport.jtl 
     -p jMeter/properties/user.properties

where:

  • $JMETER_PATH is a path where you put jMeter binaries (for example /opt/apache-jmeter-2.13/bin/)
  • -n param means that jMeter will be run in headless mode
  • – t jMeter/suites/sampleSuite.jmx is a test suite that you are going to run
  • -l jMeter/reports/sampleSuiteReport.jtl is a result report file that will be generated. This file will be interpreted by Jenkins Performance Plugin
  • -p jMeter/properties/user.properties is a properties file where you configure the report file format to XML (interpreted by default in Jenkins Performance Plugin)

By default the .jtl report file is in the csv format. Jenkins Performance Plugin can read the csv, however the default format for it is xml. By the same token I use user.properties file with one line indicating that the jtl output should be xml:

jmeter.save.saveservice.output_format=xml

3. Analyze reports with Jenkins Performance Plugin

Install the Performance Plugin on your Jenkins instance. To use it, add the Post Build Action to your job, providing the path to .jtl report files:

shot_3

Jtl files will be interpreted each time the job is executed. Moreover in the job page on Jenkins you have new option in menu: Performance Trend, where you can find (on graphs) how your performance was changing over time at each build:

shot_1





StackOverflow developer survey 2016

19 03 2016

StackOverflow,as most visited dev page, conducted a survey asking its visitors interesting questions and publishing interesting results. It’s worth to take a look at the results to know how the environment looks like:

http://stackoverflow.com/research/developer-survey-2016

This year, over fifty thousand developers shared where they work, what they build, and who they are. You are about to read the results of the most comprehensive developer survey ever conducted.





Automate Jenkins job creation with DSL

28 02 2016

Jenkins job creation in Web UI is simple but still – manual creation takes time. Depending on your coding and testing practices you may find it acceptable or burdensome and costly.

Jenkins DSL allows you to define Jenkins job in groovy script file, put it on VCS and allow Jenkins to create and execute jobs based on it. The another advantage is that you get your jobs versioned along with codebase.

So… is that hard? Having Jenkins configured to build your code it requires few steps to build jobs from DSL:

1. Install Jenkins Job DSL plugin

Simple thing to begin: go to your Jenkins’ Management page, find the Job DSL plugin and install it (https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin).

2.Create the Seed Job

That is the job that will create other jobs. Do it like any other job creation: Select the ‘New Item‘, give it a name (in my case ‘dsl-demo’) and select type of ‘Build a free-style software project‘ (or ‘Freestyle project’).

Remember to configure the Code Repository url and credentials where this job will do the checkout and find the DSL script files.

3. Configure DSL scripts files location

Then in your job configuration add build step named: ‘Process Job DSLs’ (provided by Job DSL plugin). I am going to use the script files located in the filesystem (Jenkins’ workspace), versioned in my git repo. All of them will be located under the Jenkins/jobs/ directory in my VCS with the .groovy extension. So the path in my config is:

Jenkins/jobs/*.groovy

Where I have one file as for now, named:

Jenkins/jobs/demoJob.groovy

Remember to follow naming conventions for files: script names may only contain letters, digits and underscores, but may not start with a digit

4. DSL Script file content

First of all to simply make Jenkins create the job it is sufficient to have such content in DSL script:

job('simpliest-job-ever') {
    steps {
        shell('echo hello from your automated job!')
    }
}

Here I am creating the job with a name ‘simpliest-job-ever’ with one step inside. The step is using shell plugin and executing the echo command.

5. Run Seed Job

Now is the time to push the DSL file to the git server and trigger the Seed Job execution. The effect found in Jenkins console after running my Seed job was:

Processing DSL script demoJob.groovy
Added items:
    GeneratedJob{name='simpliest-job-ever'}

So my job was created from DSL file.

6. Run newly created Job

Now, coming back to the Jenkins’ job list the new job actually is there. I did not set the triggers on it yet so I have to fire it manually.

Here is the result of executing my newly generated job, printed in Jenkins console:

Started by user LooksOK!
Building in workspace /var/lib/jenkins/jobs/simpliest-job-ever/workspace
+ echo hello from your automated 'job!'
hello from your automated job!
Finished: SUCCESS

Lovely, isn’t it? :>

Enhance your DSL script

Such a basic configuration and script file prooves that the whole thing works. Now is the time to enhance the scripts and make them creating the fully useful jobs. The plugins supported in DSL and their full documentation is here: https://github.com/jenkinsci/job-dsl-plugin/wiki/Job-DSL-Commands.

A list of most useful plugins is:

    • SCM to connect your Job with code repository
scm {
  git('git@github.com:yacekmm/looksok.git')
}
    • Triggers to setup the schedule on your job execution
triggers {
  scm('*/15 * * * *')
}
    • maven to execute maven tasks
maven('-e clean test')
    • shell to execute shell commands
shell('echo hello from your automated job!')
  • and more…

Thanks for reading, give it a try!

 





Run Protractor tests in Jenkins’ headless browser on Linux with Xvfb

13 02 2016

Automated GUI testing is a must for core buisness functionalities in an application. Running them frequently in an automated manner on Continuous Integration environment guarantees reliable results and gives confidence that system isn’t broken.

Test suite should be written in a way that does not require human attention, generates test report and is repetitive to allow investigation of results. That leads to the need of deploying tests on Continuous Integration server (e.g. Jenkins) and running them regurarly. Having Jenkins deployed on Linux without GUI you can’t run web browser in usual windowed mode – you need to use so called headless mode. Headless software is a software available to work without a Graphical User Interface.

Components

The configuration is built upon following components:

  1. Protractor tests – regular test suites that are fired on usual configuration with GUI
  2. Grunt configuration to run protractor tests
  3. Firefox browser installed on Jenkins’ Linux Operating System (CentOS in my case)
  4. Xvfb installed on Jenkins’ host OS. Xvfb is a software that emulates GUI for non GUI systems
  5. Grunt plugins set to run Protractor tests in a non GUI environment
  6. Jenkins job configuration to run your job in a scheduled, regular manner

Find the configuration details below.

1. Protractor tests

These are the test suites you run on your regular development machine and need to run them on Jenkins.

2. Grunt configuration

My tests are fired from command line with grunt-protractor-runner plugin (https://www.npmjs.com/package/grunt-protractor-runner). Plugin provides the protractor: task and requires config file where you specify all the options: spec files (suites), your system URL (baseUrl), as well as any custom params (params) that you can refer in your specs or browser you run your test against. Check the configuration details and instructions on plugin page.

3. Firefox browser

You can use the browsers of your choice. In my case this is the firefox. On CentOS the installation command is:

yum install firefox

3. Xvfb

This is the key component of running tests in headless mode. Xvfb is a virtual display frame buffer for X – the display system used by Linux. It provides a fake display buffer for graphical programs. This way it allows any program to run headlessly.

To install Xvfb on CentOS execute:

yum install xorg-X11-server-Xvfb

Xvfb usage is simple. To open certain url in browser execute:

xvfb-run firefox https://looksok.wordpress.com

This way you make sure that xvfb is available on your PATH and it opens the firefox application in headless mode with an url as a param.

4. Grunt plugins

To tie it up all together I use Grunt with plugins that starts xvfb buffer: grunt-env (https://github.com/jsoverson/grunt-env) and grunt-shell (https://github.com/cri5ti/grunt-shell-spawn). Whole configuration is described here: https://gist.github.com/nwinkler/f0928740e7ae0e7477dd

The idea behind that config is to execute shell command that create a new display before test. After the test is done, the display is killed.

5. Jenkins job configuration

This is an usual part of the setup. Simply make a new job that will fire up your protractor tests on a schedule you define. In my case Jenkins executes the grunt task:

grunt protractor-xvfb

In most cases that’s all the Jenkins job does. If your your system is already built and running, that Jenkins config enough. You can just target your tests against your running instance.

In my case Jenkins task is more complex. First it checkouts the repository for newest code version, then builds artifacts, starts all system components, fires tests and kills system that it has started. And it all works as a charm :)

 








%d bloggers like this: