Showing posts with label spring. Show all posts

Spring-Security: Different AuthenticationEntryPoint for API vs webpage

This is just a real quick post, on a little bit of Spring that I came across today. It's a very simple thing, but, in my opinion, beautiful in it's simplicity.

I found myself working on some Spring-Security stuff, and an app where I needed to define my AuthenticationEntryPoint (I am in the process of adding the security stuff, so this is not done yet).  Simple enough - normally in config you can just add it to the exception handling setup. However, this time I wanted to define two different entry points: one for when a user attempts to access an API (JSON) and one for normal site pages.

It's not unusual to have an API baked into an app (maybe under /api/** etc), and the ideal behaviour would be to return an appropriate HTTP Status code for the API (401) plus a JSON payload, and for a logged in web page the user would be bounced to the login page before continuing.


Having dealt with this split for error handling, controller routing and security elsewhere, I assumed I would have to implement a custom AuthenticationEntryPoint, chuck in a fer IF statements checking the logged in user and requested URL and either redirect or respond with the status appropriately. However, Spring has us covered with its DelegatingAuthenticationEntryPoint - which is what it sounds like, and super simple to use.  Probably best demonstrated with the code (because it's just that simple!)

In our normal configure method we just set the entrypoint as usual. But in the DelegatingAuthenticationEntryPoint we simply initialise it with a map of RequestMatcher: AuthenticationEntryPoint (defined in Groovy above, so we have nice Map definition etc - would be slightly more verbose in Java)  - The RequestMatcher can be any implementation you like, but of course simple path matchers will probably work fine; For the AuthenticationEntryPoint there are also lots of really nice Spring implementations - including the two used in the example above, which perfectly provide what I need.


This genuinely elicited an "awww yeah" from me.

Spring, Reactor & Event driven programming on the JVM

Following my previous outing playing with the Spring-Boot microservices stuff, I once again found myself looking through some of the Spring libraries and came across the Reactor integration stuff.  It looked interesting, and thought I would have a quick look at the asynchronous event-driven model.

As always with Spring Boot, it was super simple to get an app up and running - it's worth noting that the app doesn't really get that much into the async processing side (or really expose scenarios with potential benefits/pitfalls of the approach) - but it gets an app up and running pretty easily.


Event streaming

Obviously, to get started I needed some kind of event source (I could have just stubbed out some code to just randomly create events in the system, but I wanted something more real). Obviously, with the modern web & big data, we have a tonne of events that we could use. I went for the obvious choice of the Twitter streaming API - as it exposes a streaming API I could just connect to that and on receipt of any tweet then just push an event on to my EventBus for any interested parties to process.

The basics of connecting to the Twitter streaming API are pretty simple using Spring-Boot and Spring-Social - I just created a simple Spring-Boot webapp that just exposed a simple page to connect to Twitter (OAuth via Spring-Social) and then on connection just connected to the streaming API and started listening.




First I just connected to the sample "firehose" stream, which is supposed to be 1% of the total twitter stream (I saw reported that there are 500million tweets a day, so you'd be looking at about 5million random tweets sent a day) - But I decided to consume the tweet events to pull out data about the current ongoing Rugby World Cup (England 2015), so I switched to the search stream limiting by references to the world cup.

The searching stream provided a reasonable number of tweets, and I think whilst I was running during the England vs Australia game I processed ~500,000 rugby related tweets.


Configuring reactor

Getting reactor up and running is really easy with Spring:

The EventBus configuration is interesting, as it has options to use different patterns including the LMAX pattern - in this case I just went with a standard thread pool approach.

The tweet-eater

To be honest, the use of reactor was overkill for this experiment, as the Spring-Social API allows you to define listeners for the streaming APIs which have a handle tweet method, much like an event consuming interface. But as it was just an experiment I continued and just used that listener to push the events on to the event bus.

As you can see above, its pretty simple - the listener just creates the event object and pushes it onto the EventBus.  So, with that done, and the basic Spring-Social connection setup to listen to the stream we will have a nice flow of events being pushed (at quite a high rate!) onto the EventBus. Now we just need something to consume those events.


Event consumers

The first consumer I created was just a very basic logging consumer - all it did was count events and then log numbers

Pretty simple


Next up,  I created a basic consumer to inspect the tweets, identify rugby teams mentioned and persist the data to Redis - this was also pretty easy, as Redis integration works pretty simply and Twitter created a set of standard team hashtags for the competition - So I just mapped those to countries, and setup my consumer to check for those

I quickly stuck some lipstick on the interface to display number of tweets per country and we were off!



Like I said, it's only barely scratching the surface of async event based programming, but it shows how easy it is to get the EventBus up and running with Spring.

As always, the code for the full app is over on GitHub - if you just clone the project and add in your own Twitter API keys in the config then you should just be able to build the JAR and run it directly.

Spring-Boot & Netflix OSS - An adventure into microservices

Honestly, I still need convincing on microservices.

I can see that they are a compelling argument compared to a monolithic application, but I think I need to get my head around some of the challenges they face - the first one that comes to mind being how to effectively define the microservice boundaries - as it seems to me a lot of the applications I have ever worked with are monolithic because these boundaries are so blurred.


Anyway, I wanted to do some tech stuff, so decided to start building out an application using the microservice architectural pattern and Spring Boot seemed like a good place to get started.

This is very much a work in progress, and I am continuing to progress through different aspects of the application and at the moment there is very little actual code written (in part that is due to the simplicity that Spring-Boot provides).  All code is being kept up to date in GitHub so feel free to have a look at that.


There are lots of great blogs covering this stuff already, so won't re-cover their work, the following article gives a great write up of the Netflix OSS and the Spring integration which is worth reading:

http://callistaenterprise.se/blogg/teknik/2015/04/10/building-microservices-with-spring-cloud-and-netflix-oss-part-1/

(Image from: Building Microservices with Spring-Cloud and Netflix OSS)


Getting started: A service registry - Eureka

One of the first things that is needed is a central Service Registry to allow service-discovery - this is not a new concept to microservices and is an approach used by SOA.  Straight out of the box, Spring-Boot provides integration with Netflix's OSS application Eureka, that provides this.  I opted to have a dedicated application for my registry (code can be seen here) and it really is as simple as adding the relevant dependencies to the build.gradle file, adding an @EnableEurekaServer annotation to our application config then a simple config file defining the server port/name etc and its done!  You can just run gradle assemble in that project to build the JAR file, then run java -jar [the new JAR file] and the application will spin up - you should then be able to go to http://localhost:1111 and you will see the Eureka dashboard (with no microservices registered of course).



My first microservice

So, I had Eureka up and running, but it was looking pretty lonely with no services registered.

A microservice in Spring is also very simple - as really, all it is is a simple web application that runs in its own process with a limited domain - so spinning up a Spring Boot MVC RESTful webapp with a single controller/endpoint is enough to get me a microservice (even just a tweet would do it..)
So we can create our new microservice to do anything we like, in my case I created a QuoteService (the application is slowly evolving into an insurance engine).  Just having the standalone app isn't helping much, so we need to add some configuration to tell the service to register with our Eureka server - this will make our new microservice discoverable by other services wanting to use it. 

Again this is quite simple: we need to tell our application it should try and register with Eureka, and we should add the config to do so:

You can see that we simply annotate our application config in java, and then add some properties that define where the Eureka server is hosted and that's basically it.

Now if we build the project JAR and start up again (and we still have our Eureka service registry running) then after 30seconds or so you should see the Quote-Service registered and ready to use.


On to the next one.. 

Now, we have a microservice, and we have a registry that makes it discoverable, but still - just one microservice is pretty lonely. So next I created another dummy RESTful microservice, this time called ProductService which just followed the same pattern as the first.

Once that was started up then the Eureka dashboard started looking a bit happier with the two services registered - the obvious next challenge is seamless interaction between the two: splitting the services into their own processes is all good an well, but meaningless if you can't easily integrate them.  The way I look at it is when reading the application code of a service (or application using microservices) then it should just look like a normal application with sevice classes - there shouldn't be any fanfare around the fact that my service class actually gets the data from a dedicated microservice over HTTP/AMQP rather than just getting directly from the DB in the traditional way.


So, still just stubbing out the endpoints, I updated my QuoteService endpoint to make a call to my ProductService, and then just jammed that response into the JSON response I was returning anyway:

As you can see, it could be a standard controller in a normal monolithic application from this point, we are just calling a method on our autowired ProductService class and returning that.


So the really interesting part is in the ProductService class - at the moment this isn't a really elegant, abstracted class yes, so there is still some boiler plate, but that will have the advantage of making it clear what is going on:

As you can see, it's just making a REST call to the Product microservice and returning the response cast as a Map - but the really nice part of this is that the service url is just the service name (in this case "PRODUCT-SERVICE", that is injected to the class)  and with the RestTemplate annotated with Spring-Cloud's @LoadBalanced that microservice will be looked up in Eureka (and load balanced if there is more than one PRODUCT-SERVICE running).

So our setup is starting to take shape now - we have two microservices, both registered with Eureka and able to interact with each other in a fairly clean, loosely coupled way.


Don't push me, 'cos I'm close to the edge..

As your microservices start to proliferate, you will get different levels of service granularity, and undoubtedly you won't just want to expose all your microservices as a public API.  One option would be to create a RESTful application and define nicely named endpoints you want to expose and then use the standard integration described above to integrate it.

Fortunately, there is an easier way - Netflix provides a library called Zuul that can be simply configured to map URL patterns to given defined service names (and again looks up in the Eureka service registry).  Much like Eureka, this is super easy to setup and just needs an annotation and the config again:

And the config is pretty easy to understand:

As you can see, we just define service names against URL patterns.

Now once all are apps are up and running, and the microservices are registered on Eureka then you have a single API interface to start interacting with the services (rather than having to access each service on its designated port etc).


Conclusion

 So that's as far as I have got - I wired up the QuoteService to MongoDB so the data all gets persisted there (and have added a get quote endpoint which gets the same data from mongo) and starting to wire up the product service with JPA.  So far it's been enjoyable, and things are making more sense than when I started - but there are a few questions still:

  • It seems like there is still duplication of service names throughout the different projects - for example the ProductService name ("product-service" - case insensitive) is proliferated throughtout - the service itself defines it, the QuoteService needs to know the name of the service, the Zuul edge server needs to know the name etc.  I guess this is unavoidable as these are intrinsic dependencies but still seems a bit flaky.
  • It feels like the Service classes could be factored out - our ProductService class that allows HTTP REST interactions with the Product microservice would likely need to be re-used across all applications/microservices that need to use the Product microservice

NerdAbility - A presentation

I recently had to give a presentation about NerdAbility, so for fun, here are the slides I put together. It was just an intro to the product, where the idea came from and what it was trying to solve, followed by a brief jump into one or two interesting elements of the project from a tech point of view.

Spring MVC - Page caching and If-Modified-Since

Spring (and in general Java/groovy etc) support a range of caching layers for your web application - with options for Hibernate first/second level cache, Spring's @Cacheable and simple integration with lots of providers (EHCache, Redis, etc), but aside from server side caching, you can also implement page level caching using the standard If-Modified-Since cache headers.

If your web application is sitting behind an apache web server, then using this mechanism, you can set it up such that Apache will do a lot of the work, and a lot of requests never even trouble our web application.  This will of course only work if you have fairly static pages that don't update to frequently, and aren't user specific (e.g. so its actually possible to cache at a web-page level - user account pages obviously are harder to cache at this level as they are very user specific).  Even without Apache in the mix, most modern browsers are built to handle If-Modified-Since headers and 304 response codes, so using the approach can mean that browsers are less eager to even request the page from your server whilst a user is browsing the site if we have said its cache-able.


Thankfully, the machinery for this stuff is all baked into Spring MVC.


Updating the RequestMappingHandlerAdapter

This walkthrough is assuming that your app is using standard @Controller annotations and a standard RequestMappingHandlerAdapter to route the requests - although there are still relatively easy mechanisms to do this if you are using other Controller/HandlerAdapter patterns.

The RequestMappingHandlerAdapter class has a method that can be overridden called getLastModifiedInternal() - This method simply returns a long value (the epoch time) that the requested resource was last modified. All we need to do is extend the RequestMappingHandlerAdapter and implement this method to return a timestamp.  For example:



The above assumes we have initialised a timestamp at startup (easy to do using Java config) and assumes that if you have visited the site since last app startup, then there is no change (in reality, we will likely need something more complicated to calculate this)

And that's really all we need, as Spring will handle the rest for us - from this, if a brand new request comes in with no If-Modified-Since headers, then Spring will take this date/time stamp and return it with our response as the Last-Modified date (HTTP standard header - this will inform the browsers/web servers action next time).  If however, a user has already visited your site and the browser has received a valid Last-Modified timestamp, then on the next request it will include this value in the request If-Modified-Since header, when Spring recieves this request, it compares the timestamp against the value that is returned from our getLastModifiedInternal() method, and if there has been no change then Spring will automatically return the response to the client with a 304 response - so none of the Controller code will be executed.

As you can probably guess, this can provide huge efficiencies and improvement on latency, server overhead etc.



More complex Last Modified Dates

As mentioned, in all likelyhood you will need a more sophisticated mechanism than just checking the application start time - So we have plenty of options here: we could query the DB for changes, we could have other flags/properties set for when particular resources are set (bare in mind that if static resources like CSS are changed, these need to be considered)

If you need to consider a fairly unique LastModified date for every endpoint, then this solution isn't a good fit, as this is the more generic approach - you can alternatively implement a similar last modified method on your (every) controllers.


Another option that I have considered is a halfway compromise - where I need endpoints to have specific considerations, but I only have a set of 4-5 (or relatively manageable) specific queries/checks that need to happen, and every endpoint will just need to check some subset of these conditions - this solution involves custom annotations and marking up Controller methods with this annotation to signal to our HandlerAdapter what checks should be considered for the Last Modified timestamp.  This has the advantage of relatively little intrusion in all my controller endpoints, but granular enough to provide enough control for effective page caching.


A custom annotation

First we define a simple annotation that can be used to mark up Controller methods to indicate which conditions are important to the endpoint:



The above code shows the annotation code, a sample enum (just to provide some type safety whilst using the annotation - this could be a string or anything else) and an example of the annotation on a controller endpoint.


Updating our Last Modified method

Now, in our last modified method, we have access to the Handler (e.g. the controller method being invoked) so we can quite simply check the controller method for our annotation, and if found we can just check the values said and perform the appropriate checks to work out what the last modified date needs to consider:




As mentioned, this won't work if there are lots of pages with lots of different requirements, but if you have a manageable of changing entities in your application this can strike a nice balance between clean code and flexibility.



Spring MVC & custom routing conditions

I have recently been building a Spring MVC app (well, actually using the Spring Boot project - which is quite nice in parts, and crazy frustrating in others - but the underlying mechanics are the same).  The application is actually a re-build of another application, so it has involved a lot of playing and exploring Spring source code to try and replicate the apps functionality like for like.

One of the first things I found, was that Spring doesn't really cater for the concept of a single app running on different sub-domains.  I assume the thinking is that you would build separate applications for different sub-domains, but in this case, we just have a single app.

There are two main speed-bumps I have come across so far:
  1. Controller routing based on subdomain
  2. Security considerations based on subdomain

Basically, as you can probably imagine, once you have subdomains on a single web application, the URL path is no longer unique (e.g. http://automateddeveloper.blogspot.com/ is clearly not the same as http://blogspot.com/ )


The rest of this post, I will look at the routing element of it. I will do another post later in the week about the Spring security stuff (I haven't solved all of that yet - but got far enough to make it work).


Understanding the subdomain

The first thing you need to sort out is a common and consistent way to determine the subdomain of any given request. There are a variety of ways to do this, for example, you could parse it from the request in apache and set a header, so your app doesn't have to worry about it, or you could just parse it from the request object server name. I will assume you have some bean/service/helper class to do this everywhere (although for now we only need it in one place).


An annotation

First up, we need a new annotation, that we can easily apply to a Controller, just like we would use the @RequestMapping - at the moment, the nice built in Spring RequestMapping handling allows you to define a URL path (plus other bits and pieces) to map a request to a URL to a given controller & method - what we want is to also specify the subdomain element of the requested URL

Defining an annotation is simple:

For the sake of simplicity of this example, I will only allow it to be used at class level (so no method based subdomain routing - but that will be pretty easy to do once you have understood the rest of the post).  You will also note that the value is defined as a String array, this will allow us to define mappings to multiple subdomains if needed.


The mapping condition

So, that was easy. Obviously, at this point the annotation doesn't actually do anything - you can add it to all the controllers you like, but it won't actually make any difference to your request routing.

To get our new annotation involved, we can implement something called a RequestCondition.  This is exactly what it sounds like, Spring lets you implement additional request conditions that must be satisfied for a request mapping.

The condition could be based on any logic you like, but in our case we just simply need to check for an annotation and then examine the value provided.  If the annotation value matches our incoming request then the condition is met, easy!  Returning the condition indicates to Spring that the condition has been met, returning the null value indicates that the condition is not met.


Adding the condition to the mapping handler

Usually, we would use the standard Spring RequestMappingHandlerMapping to handle all the routing of requests based on the URLs, but now we need to also ask Spring to consider our new custom condition from above.

This is a simple case of extending the normal RequestMappingHandlerMapping class and adding our new condition as a custom condition.  Luckily, this is really easy:

Allwe are doing is checking to see if the handler class (our controller) has our new @Subdomain annotation and if it does, we register our new custom condition for consideration.



Basically..

That's really all there is to it - we can then decorate our controller class with @Subdomain("subdomain") and have them handle the routing of requests. 

As you may have noticed, this is a pretty nice pattern for any kind of custom routing you might want to use - the same template could be used for routing by any request info/header or any user info (e.g. routing requests to different controllers based on their logged in role etc)

Spring 4: XML to @Annotation Configuration

I got 99 problems, but an XML based security configuration aint one..

I have for a long time preferred to use Spring (or generally Java) annotations over XML config for my development (I concede the point on XML configuration allowing a central place to understand all Controllers etc, but with modern decent IDEs this info can still be viewed centrally even if using annotations).

A while ago I made the switch to pure code configuration for my Spring webapps, with the exception of the web.xml (dependency on using Tomcat7 that I didn't want to enforce just yet) and the security config - which Spring didn't support.  Along with Spring 4, Spring have announced that they will now support security config as code, which is great news!


XML Configuration

Below is an example of a typical XML based configuration.

This basically turns on security for the webapp, it:
  • Adds a single intercept URL rule (in this case, our rule says all URLs are open to everyone - so not that secure! We would likely add more URL intercept rules above this as we have more URLs we want to secure - these rules are read top to bottom and fall through until a match is found, so permitAll must be the lowest rule found)
  • Defines a login form - including location of the form, the submission target URL, login failure redirect URL and the logout URL. Spring will automatically handle all these. If you submit a form to the login-processing-url then Spring will intercept it and attempt to authenticate - you don't need a specific controller handler defined.
  • Defines an authentication manager - this will be used to authenticate submitted requests. In this case, I have overriden the standard Spring User Service with my own implementation (this will be a common requirement as you will want to authenticate against users in your DB etc)


The config is all pretty simple really - the only unpleasantness is the requirement to have XML!


Code Configuration

And here is the config in code using the latest and greatest Spring dependencies.

Let's have a lookat what is going on here.
  • I am @Autowiring in my custom User Service class - this will be used in the Authentication manager later.
  • The configure() method is where we set the URL intercept rules and login form - it should be pretty self explanatory reading it through if you are familiar with old fashioned xml config (will come back to CSRF config shortly - but it is NOT recommended that you disable this! this is just in development)
  • The registerAuthentication() method sets up the Authentication Manager using our User Service implementation. Whilst setting up the Authentication Manager, we also define a password encryptor - you will note in the code config I am using the BCrypt password encoder, and in XML using a base64 MD5 hash - but whichever encoder you want to use you can configure it in the same fashion using the secondary method to instantiate and return the encoder desired (although you probably shouldn't be using MD5 over BCrypt.. really, you shouldn't ).



Observations and Gotchas

As you can see in the above code example, I am explicitly disabling CSRF. As of Spring 3.2 onwards, the security layer provides CSRF protection by default - so if this is not disabled then you have to provide a CSRF token to prove your request is legit. Should you need to disable it, you can using the above syntax, but obviously CSRF protection is built in to help you out, so probs best not to disable it on a prod system!

The link above details how to include tokens in requests for your webapp. It's really pretty easy to do.


The second point to note is one that caught me out.  Previously in Spring, when submitting a form to authenticate, the default field names had to be j_username and j_password. If you are hoping to switch the config out on an existing webapp then you have to make sure you update your login form with the correct field names (Spring 3.2 with XML config you still need j_*, its only Spring 3.2 & Java config..)



As always, the code is on GitHub - feel free to check it out.

Eclipse & LESS - Better Development time with Incremental Builds

All source code for this app is on GitHub at the moment - feel free to fork/download/etc

So one of my recent experiments I decided to start playing with LESS (CSS pre-processing, letting you use variables etc in CSS code, which has been long needed) - It's all actually relatively simple (although you can do some nice, powerful stuff with it) to code with if you are coming from an development background, so I found myself quickly getting to grips with basics like defining variables for colour schemes (very basic stuff, but sooooo much better than having to maintain masses of CSS and every time you want to tweak the colour scheme having to search for hex codes..).

However, I found myself wanting to start using LESS on new/existing web app projects which were largely Spring MVC/Java based apps, which was more problematic. LESS requires pre-processing/compilation to generate CSS, which is kind of a pain in the ass when trying to prototype web app projects - being used to just altering some CSS and then hitting refresh in the browser (at most, having to re-load the tomcat server inside  eclipse), having to try and generate the full LESS/CSS files everytime anything changes was not something I was going to be doing.

Thankfully, having done some digging, I managed to get it all setup and working like a charm - Every change I made to the LESS, Eclipse performed an incremental build (like it does for other compiled code like Java etc) and voila! I could just change the LESS and press F5 in the browser.  Here's what I did:

Software

  • Eclipse
  • Maven
  • LESS
  • WRO4J Maven plugin

Directory Structure

As I am using maven, I am of course following the standard /src/main/webapp convention - so that is assumed here.
In the webapp root, I created a new "less" folder, alongside the "css" - This holds all my *.less files - I won't go into detail about LESS here, but assume you will only include valid, compiling LESS files here (non-compiling LESS files will cause you a headache here)



As you can see, in my normal "css" folder I have only included vendor CSS files - I will not be placing any custom CSS here (All valid CSS is also valid LESS, so even if I wanted to just write CSS, I can do in my "less" directory).

Maven Configuration

The incremental build will be performed by the use of a Maven plugin. This will also mean that any formal full build/packaging that you do will also include the LESS compile step.

The below configuration simply defines a "group" that will attempt to compile and the target folders we will generate the artefacts to (more on that later).



We also define a little more confuration regarding what we want WRO (Web Resource Optimizer) to do:

/WEB-INF/wro.properties defines exactly what optimization we want to perform - in this case I have selected some pre & post processing steps:


/WEB-INF/wro.xml defines the location of the source files:


The above config will make Eclipse perform the incremental builds on your LESS files as well as generating a CSS file if you perform a regular maven build.  As can be seen below, Eclipse incremental build has generated a web-all CSS file in the target "css" directory.


Including Generated CSS

The simple part of this is of course to include it in the webpage header as an import - Despite it not being in your /src/main/webapp/css folder, you can still reference it the same as the static vendor stuff we have included as we know it will be generated there for us (either as part of full app build/deploy or incrementally in Eclipse).


There is also another gotcha at this point - You have to check that your Eclipse will be deploying the contents of your m2e-wtp directory to your webapp. This should be happening by default, but you can check (and fix if necessary) by right-clicking on your project in Eclipse and going to "properties".  In the left hand menu, select "Deployment Assembly" - this will show the directories/libraries that will be deployed as part of your application (obviously this only takes effect if you are deploying the app to a server inside of Eclipse).

As you can see below, my Eclipse defaults to deploy /target/m2e-wto/web-resources to the root of the webapp. If yours doesn't just add an entry for this and everything should work!






Footnote:

If you are struggling to generate the LESS files in the m2e directory, then there is a chance you have an compilation problem with your LESS files.  With the incremental build, if LESS compilation fails then it will fail silently - for full details you should run the full maven build to see errors logged.

Spring MVC 4.0

I have had a post coming for some time on my thoughts experience in starting to play with the changes that come as part of the latest major upgrade to the Spring suite.

There are lots of changes, that were announced at last year's Spring One event - including a flashy new spring.io website and several new packages to the framework such as Spring Boot (which they describe as an oppionated way to start building Spring apps - basically out of the box components that reduce work, but configured to Spring's tastes and conventions).



The interesting parts for me are in Spring MVC (as that is where I don most of my Spring dev) - most notably, the ability to write Spring apps in pure Groovy is of interest (as I do a lot of Groovy dev, and once you get used to the luxuries of its collection based closure functions then its hard to go back!) and also the ability to now configure the Spring Security stuff also entirely programatically (my previous attempt of pure code config spring app were thwarted only by having to use XML configuration for the security).

I am yet to convert an app to Groovy, but I have created a basic web app using the Spring 4.0 Milestone releases and converted the security config to code.  Full source code of the webapp is on github.

I will stick that up on GitHub soon, and when I do I will write in more detail about it (I also played around with LESS on that project and configured MAven/Eclipse to build the LESS/CSS files nicely, which I will also write up soon)

As it happens, I also stuck the demo app up on cloud hosting service AppFog.com (given that CloudFoundry is no longer with us in it's free form.. which kinda sucks, as that was really nice). It's by no means a complete app, and doesn't really do anything - just lets you connect your Facebook/Twitter accounts and see all your contacts etc - but as you can see - there is a lot of filler text and the LogOut link is always in the navbar etc.. But anyway, its here, for now..

Spring 4 App homepage


Spring 4 App Dashboard


  http://socialcrm.eu01.aws.af.cm/

Google Shortening URLs

As another quick follow on note from the below, one of the features that was built in to the application was the ability to share your resume or particular achievements with your friends on Twitter. To do this, I obviously wanted to share a link back to the URL of the resume, so to maximise the potential additional text I investigated URL shortening.

Their is a bit.ly API that uses OAuth, but for what I wanted to do, I decided that was overkill, as I didn't necessarily need to associate the shortened URLs to a users bit.ly account, all I really cared about was getting a shortened URL.

Fortunately, Google came to the rescue with their goo.gl URL shortening service that also exposes a public API without need for authentication.

So I simply wrote a service class that utilised the Spring RestTemplate class to shorten URLs:

@Service("urlShortenService")
public class UrlShortenService {

       private RestTemplate restTemplate;

       public UrlShortenService() {
              restTemplate = new RestTemplate(ClientHttpRequestFactorySelector.getRequestFactory());
              List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
              messageConverters.add(new StringHttpMessageConverter());
              messageConverters.add(new MappingJacksonHttpMessageConverter());
              restTemplate.setMessageConverters(messageConverters);
       }
	   
       public String shortenUrl(String url) {
              Map<String, String> request = new HashMap<String, String>();
              request.put("longUrl", url);
              LinkedHashMap<String, String> shortUrl = restTemplate.postForObject("https://www.googleapis.com/urlshortener/v1/url", request, LinkedHashMap.class);
              return shortUrl.get("id");
       }
}


I didn't worry too much about validating that the string passed in was a URL for the time being as I always had control of that, but that should be something that would need to be considered.

Spring Social Integration

So, you may notice that I am something of a Spring fan, and generally like to try out different Spring projects where I get the chance. I have been aware of the Spring Social project for a little while (was looking at integrating LinkedIn with flutterby but decided against it), so recently, when a competition was announced in work to create a Java web app in the cloud for a chance to win a new Android tablet I thought this would be a good chance to put together something of a showcase of technology.

As always, the web app is a straight forward Spring MVC project built with the current latest Spring libraries (3.1 - also making use of declarative caching with ehcache, which was nice) and also includes the Spring Data MongoDB integration (again - primarily because it seems to be the most commonly supported NoSQL db in the cloud.. well CloudFoundry and OpenShift anyways). I also took the opportunity to integrate some Spring Social stuff, so I will go through that, as its pretty easy (will post again on some thoughts about Redhat's OpenShift platform and further SpringSocial stuff).



Maven Configuration

First of all, there is obviously some Maven configuration needed in the pom. It took me a little while to find the correct repositories to get all the different Spring Social libraries from (some implementations are less mature than others so not all have full proper releases yet)


	 spring-snapshot
	 Spring Maven Snapshot Repository
	 http://maven.springframework.org/snapshot



	 spring-milestone
	 Spring Maven Milestone Repository
	 http://maven.springframework.org/milestone




 Next we need to add the libraries we need:


	org.springframework.social
	spring-social-web
	${spring-social.version}
	
		
			spring-core
			org.springframework
		
		
			spring-web
			org.springframework
		
		
			spring-webmvc
			org.springframework
		
	



	org.springframework.social
	spring-social-github
	${spring-social-github.version}



	org.springframework.social
	spring-social-twitter
	${spring-social-twitter.version}


As you can see, we take the core Spring Social library, and for my project I also used Twitter and GitHub integration (I also had LinkedIn early on, but removed that as the LinkedIn terms of use on the API are pretty limiting). I added the exclusions to ensure that the latest Spring libraries were being used, as these were declared elsewhere in the Pom.



Storing User Connection Details

Spring Social supports both OAuth1 and OAuth2, and provides the underlying mechanisms to perform the "OAuth Dance" which enables your application (once approived by a user) to capture the access token required to enable your application to access the third party API. Usually your application would capture the user details including access token and store them (encrypted of course!) so the user does not need to approve the application every time they use it. There are examples in the Spring Social showcase on GitHub of doing this with a standard JDBC connection implementation, but as I was capturing my user details in Hibernate I decided to implement a Hibernate version.

To implement your own storage mechanism you need two classes, a ConnectionRepository and a UsersConnectionRepository and must implement the same interfaces:

public class HibernateUsersConnectionRepository implements UsersConnectionRepository { 

public class HibernateConnectionRepository implements ConnectionRepository {


You can see my hibernate implementations here. Obviously I also needed a Hibernate entity to represent this connection details, but that was a straight forward entity as follows:

@Entity
@Table(name = "CV_CONNECTION")
public class SocialConnection {

       @Id
       private Long id;
       private String providerId;
       private String providerUserId;
       private String displayName;
       private String profileUrl;
       private String imageUrl;
       private String accessToken;
       private String secret;
       private String refreshToken;
       private Long expireTime;
       private Integer rank;


Configuring the Beans

The next step is to define the  Spring Social beans to use (such as Twitter, GitHub etc) so they can be used throughout the application.

For this I used a Configuration class rather than adding the config directly to my application context xml (this just involves creating a POJO and annotating it with the @Configuration annotation - this then allows you to create code equivalents of xml config that would normally exist in app context xml - we will see more in the details below).

@Configuration
public class SocialConfiguration {


The beans we need to define are the ConnectionRepository, UsersConnectionRepository, ConnectionFactoryLocator and then any Social interface that we are using, in our case Twitter and GitHub.

ConnectionFactoryLocator:


@Bean
public ConnectionFactoryLocator connectionFactoryLocator() {
	  ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
	  registry.addConnectionFactory(new GitHubConnectionFactory(gitHubKey, gitHubSecret));
	  registry.addConnectionFactory(new TwitterConnectionFactory(twitterKey, twitterSecret));
	  return registry;
}

The ConnectionFactoryLocator is simply used to initialise the UsersConnectionRepository, for every SpringSocial third party you want to use, you need to add a ConnectionFactory instance as per above - all Spring Social implementations will provide a ConnectionFactory implementation.

The @Bean annotation is like defining a <bean> in the application context xml.

UsersConnectionRepository:


@Bean
@Scope(value = "singleton", proxyMode = ScopedProxyMode.INTERFACES)
public UsersConnectionRepository usersConnectionRepository() {
	  HibernateUsersConnectionRepository repository = new HibernateUsersConnectionRepository(connectionFactoryLocator(), Encryptors.noOpText());
	  return repository;
}

This is to configure the UsersConnectionRepository - as you can see, in this case we are telling Spring to instantiate a HibernateUsersConnectionRepository.


ConnectionRepository:

This one is straight forward as well - again, using the Hibernate implementation of the interface and

@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public ConnectionRepository connectionRepository() {
	  Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	  if (authentication == null) {
			 throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
	  }
	  ApplicationUser user = (ApplicationUser) authentication.getPrincipal();
	  return usersConnectionRepository().createConnectionRepository(String.valueOf(user.getAccountId()));
}

You will note that this method also includes an @Scope annotation the value is set to "request" - this is because for every individual user that accesses the applciation, we want them to have access to their own connection (so the application connects to their twitter/github accounts etc, so this bean is scoped to each individual user request (but for user session life). 

ThirdParty Interfaces:

Finally we need a config method for every third party interface that we want to use - they all take a common form as follows:

@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public Twitter twitter() {
	if (connectionRepository().findPrimaryConnection(Twitter.class) != null) {
		return connectionRepository().findPrimaryConnection(Twitter.class).getApi();
	}
	return null;
}

You will note once again these are scoped to  a user's request and simply gets the connection from the ConnectionRepository for the given interface.



Using the Interfaces

Every implementation exposes the third party API, so each will have a specific API available to it to allow you to perform common tasks (depending on the maturity of the implementation, it may only offer a limited subset of the overall API) .

Below is an example of using the Twitter interface in the Spring-Social-Twitter library to post an update:

@Autowired
private Twitter twitter;
public void postTweet(String content) {
	  twitter.timelineOperations().updateStatus(content);
}

As you can see, once the Twitter interface has been configured and injected, it becomes very simple to utilise the API.



On the whole, it is a relatively simple set of libraries to use and offers (an ever growing) set of integrations with third party sites so worth having a look at.


As always, the entire code base is on my GitHub account (if this link fails, then check the GitHub link on the right) and for the time being the application is being hosted on the CloudFoundry platform (although this is still in development, so it may come up and down, and data may be cleared out intermittently - it is not intended as a live production site and you should not put any data in there that you want to keep!) - The application is a dynamic online resume/CV application, that allows users to create a CV as well as pull in data from their GitHub accounts to show off actual examples of code and skills etc.

Spring and Neo4J integration - A Quick WebApp



Following my experimentation with MongoDB and the SpringData integration, I was keen to try out a few other NoSQL options - notably something outside of a document based data store. I had heard about a competition asking for submissions for Neo4J on the Heroku platform, which initially sparked my interest (although as of yet I have not tried it on Heroku) and seeing as Spring Data already had the Neo4J integration I thought I would have a go at it. Plus, I enjoy graphs as a data structure. I have fairly recently done some work on graphs having to implement Dijkstra's algorithm (also the A*) so this seemed like it was going to be fun.

Firstly, the documentation, in the form of an online e-book, for Neo4J Spring Data is awesome. Some guys have put together the e-book based on their experience setting up a Neo4J website and it really does cover everything from the first steps through to more complex stuff around traversal and transaction management. This also means, there is little point in me going through my every step in my app, as it wouldnt be very different from their advice, so most importantly, read this!!!

I will however, just highlight some interesting points i discovered along the way:

1. Simple Annotation based Entites
As you would expect, much like JPA or MongoDB, Neo4J supports simple annotation based configuration of your domain model to simply and quickly describe some pretty rich graph relationships. This is not that unexpected, as it is Spring after all, but worth noting that it is pretty comprehensive and easy to use.


2. Magic Repository Methods
A bit like in Grails, the Neo4J supports "magic" methods, that allow you to just define method names and the query implementation will be completed for you. For example, in your Movie repository (As per the book example, and also my example) if you defined a method such as:

Movie getMovieById(String id);

Then you do not need to provide an implementation, and Spring will automagically do the rest. (the convention being get[DOMAIN_ENTITY]By[ENTITY_PROPERTY]()

From the book: "In our wildest dreams we imagined the method names we would come up with, and what kinds of queries those could generate"

3. Arbor JS Graph Framework
A little while ago I discovered the Arbor JS framework for visualisation of graphs, and its really nice - I had to try and achieve something similar some time last year and got some of the way using core html5/JS but this library is a lot more comprehensive so wanted to have a go.
First, you should check out the demos over at http://arborjs.org/, they are really nice, and make for a really nice graph UI (see screenshot of my app).


4. The Data
I wanted to get some real data, and looked at a few big datasets available online such as the Stanford Large Data Set Network but being as Im only running locally, and I didnt really want to spend too much time getting the data into my graph model I decided to go for a far smaller, simpler dataset - this years Oscar nominations (actors/directors/movies/awards - hopefully you can make out the graph from the screenshot). The data I got from the Guardian (probably UK only) data set blog which also had some nice data sets in it, but this one seemed to be a small enough size for me not to loose too much time to the data.


As always, the code is up on my github, so feel free to check it out, fork/download/mistreat etc..

Integrating MongoDB & Spring

Further to my previous post with a deck walking through MongoDB & Spring integration, I also recently wrote it up as a technical article for work (my day job), and I thought I would share the detailed article here for you as well..


Introduction

With the explosion in the amounts of data being generated in recent years, more and more organisations are looking at alternative data storage options to the traditional relational model. This in turn has lead to huge growth in the NoSQL space, with leading web companies such as Facebook, Google, Twitter, Reddit, etc adopting NoSQL solutions.
Within the NoSQL space there are several different implementation options (Graph based DBs such as Neo4J, Wide Column DBS such as Cassandra and Haddop, Document based DBs such as MongoDB and CouchDB) and careful consideration is needed before choosing an implementation.
This article will look at integrating the Document oriented database MongoDB with a Spring MVC Web Application – it is important to note that due to the nature of Document based storage solutions, they are not applicable for all problems. For example, if the data you are modelling cannot naturally be stored as “documents”, then a Document-oriented DB probably isn’t the best solution (an easy way to think about whether the model can be stored as a document is to think of it being stored on paper – does it make sense for all the elements to be intrinsically grouped in to a single document? E.g. if you were storing an essay, all the chapters are intrinsically linked to the essay as a whole document, and a single chapter doesn’t make much sense as an individual object on its own).
For that reason, this article will look at a simple web app that allows users to create Resumes – Similar to an essay, resume storage is naturally suited to the Document based approach rather than a Relational approach.


Getting Started

This article will not cover details of creating a Spring MVC web application, and will assume a prior knowledge of the Spring MVC framework and core Spring principles. The example application itself is very simple, and there are several aspects of it that have not been included (these have been intentionally left out for simplicity), such as security/authentication features, advanced UI/screen flow/editing, etc, the purpose of the example application is purely to demonstrate MongoDB integration with Spring.
The source code for the application is all available from my GitHub Account (see links on the right), and if you want to follow the code below are the required pre-requisites:
  • Install MongoDB – this is a straight forward process and details can be found here: http://www.mongodb.org
  • Install Maven – the example project uses Maven to manage it dependencies, details can be found here: http://maven.apache.org/
  • Install STS Eclipse build and install the CloudFoundry extension (Optional) – If you want to follow the steps to deploy the application to the cloud then this is required
  • Sign up for a CloudFoundry account (www.cloudfoundry.com) (Optional) – Currently in Beta so its recommended that you sign up for the account as soon as possible as requests can take time to come through






Project Dependencies

Spring currently has a project underway to integrate core Spring functionality with various non–relational data technologies, including MongoDB, called “Spring Data”. We will use this library to facilitate our integration, so we will need to include the following maven dependency in our project pom:

              <dependency>
                     <groupId>org.springframework.data</groupId>
                     <artifactId>spring-data-mongodb</artifactId>
                     <version>1.0.0.M3</version>
              </dependency>


We also need to include the MongoDB Java driver:

              <dependency>
                     <groupId>org.mongodb</groupId>
                     <artifactId>mongo-java-driver</artifactId>
                     <version>2.6.5</version>
              </dependency>


And finally, to deploy on to CloudFoundry’s hosted service we need their runtime library:

              <dependency>
                     <groupId>org.cloudfoundry</groupId>
                     <artifactId>cloudfoundry-runtime</artifactId>
                     <version>0.7.1</version>
              </dependency>




Building the Domain Model

If you are familiar with using popular JPA frameworks in your Spring web apps (Hibernate/Eclipselink, etc) then this part should look familiar – Like any application we will need to create some objects to model our underlying data (the “M” in the MVC). For our simple application we will have three basic objects:



As you can see, we have three simple objects in our model, Resume, ResumePage, Section (we will just use these objects to split our document down in to several sections/chapters). One of the advantages of using Document-oriented DBs is that as it is schema-less, objects can be added to the document in the future without affecting existing data.
We model these objects as simple POJOs, just like modelling entities in JPA, but there are a few simple annotations Spring-Data provides for us
Resume.java:

@Document
public class Resume {
      
       @Id
       private String id;
      
       private List<ResumePage> pages = new ArrayList<ResumePage>();
...


That’s it! We use the @Document and @Id annotation to indicate any object that we want to treat as a Document, and the ID. We only need to add these annotations on our Resume object, as in this case the Resume is our document, we do not want to store our pages or sections as individual documents in themselves.



Data Access Layer

Now we have our data model we need to create our Data Access layer, so we can easily perform CRUD updates on our documents.
Creating our Data Access Objects is incredibly simple using MongoDB’s MongoRepository, and we automatically get basic CRUD functionality by just extending that interface. In our example app, we only want CRUD functionality so we just create a basic Interface that extends MongoRepository:

@Transactional
public interface IResumeRepository extends MongoRepository<Resume, String>{}

Next, in our Service layer we will auto-wire our new Interface in to our service classes (this is normal Spring stuff, using the @Autowired annotation we are telling Spring to handle the dependency injection for this interface):

@Repository("profileService")
@Transactional
public class ProfileService{

       @Autowired
       private IResumeRepository resumeRepo;


This makes the CRUD functionality available in our Service class to perform common functions, such as loadResume (in this case, we are using the resume owner’s name as the ID for the documents):

public Resume get(String userName) {
       return resumeRepo.findOne(userName.toLowerCase());
}


Or createResume:

       public Boolean createResume(Resume r) {
              try {
                     // Insert to db
                     resumeRepo.save(r);
                     return true;

              } catch (Exception e) {
                     //log exceptions here!
                     return false;
              }
       }


By simply extending the MongoRepository Interface and then auto-wiring it into our Service classes, we have provided basic CRUD functionality through the MongoRepository API as well as ensuring that our service class is not tightly coupled with the DAO implementation. However, often applications will need custom queries beyond basic CRUD. This can also be simply achieved using the MongoTemplate class provided, for example:

Query query = new Query(where("id").is(“rob”));
Resume r = mongoTemplate.findOne("mycollection", query, Resume.class);

The above query will retrieve the Resume belonging to “Rob”. The Query object provides rich API for accessing and updating documents in your data store.



Spring Configuration

The final step of our integration is to configure the Spring beans to handle the data source properties.
The Spring configuration resides in the Application Context XML file (in our case, it’s a file named “applicationContext.xml” and can be found in src/main/resources/META-INF/spring/.
This file is used to declare some of the Spring beans (although not all beans will be declared in here – some beans are declared using annotations, such as our Service classes), for our MongoDB integration we need to include the following configuration:

       <!-- Mongo Configuration -->
       <mongo:repositories base-package="com.tmm.nosql.mongodb.repo" />
      
       <bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
              <constructor-arg ref="mongoDbFactory" />
       </bean>
      
       <!-- local config -->
       <mongo:db-factory id="mongoDbFactory" dbname="resume_db" host="localhost" port="27017"/>


The first element of the config declares the name of the package that our Repositories are stored in (this is where the our DAO Repository lives) – we declare this so to enable the package to be scanned for relevant repository classes.
The second configuration element declares the Mongo Template bean (provided by the Spring Data library) and we declare that we want Spring to inject our MongoDbFactory bean using Constructor based Dependency Injection.
The final configuration option declares the MongoDbFactory that we will be injecting in to our MongoTemplate bean – here we need to define the database server and port name. The default port number is 27017, so unless you have altered from the standard MongoDB install and configuration then you should use these details.




Running the Application

Running Locally

To test the application, set up a Tomcat server within your Eclipse (IDE) and add the project to the server, start the server and navigate to http://localhost:8080/ and you should see a simple welcome page.

Running on CloudFoundry

Before running on CloudFoundry we need to make a very minor tweak to the configuration. Previously we had added the configuration option:

<mongo:db-factory id="mongoDbFactory" dbname="resume_db" host="localhost" port="27017"/>

As we are no longer running on localhost and want to bind these options to CloudFoundry’s services, we change this to:

<cloud:mongo-db-factory id="mongoDbFactory"/>

Simple enough again – we just declare our MongoDbFactory, and leave CloudFoundry to inject the required parameters.


The next step to deploying the application on CloudFoundry is to add a CloudFoundry server instance to your eclipse:
  • Open the “Servers” view in Eclipse (Window>Show View>Servers)
  • Right-click and select New>Server

  • Select VMWare > Cloud Foundry and then press the “Next” button
  • You will then have to enter your Cloud Foundry account information:



  • Complete your email and password information, leaving the URL as it is and select the Next button.
  • The final screen will give you the option to add the project to the server, add the server and press Finish



Now the Cloud Foundry server instance is setup within your IDE you need to configure the deployed application so you can bind it to the required services:
  • Double-click on your deployed project within the “Servers” view:


  • This will open the “Applications” page – you will notice in the bottom left had corner an empty box titled Services, 




  • Press the “Add Service” button to the top right of the Services panel:




  • The MongoDB service will now be listed in the Services box, now drag it across to the right to the “Application Services” section. The “Applications” panel should now appear something like this:



  • Press the “Start” button under the General tab, then watch the log as the application is started up on the CloudFoundry – there should be no errors reported
  • Now navigate to the URL you assigned to the application (this can be edited in the above panel under the “General” section


You now have a MongoDB powered NoSQL application running in the Cloud!