Serverless and Spring Cloud Function

We have been discussing going to a more serverless architecture at work and so I decided that I should do some research to see where that stuff is now. When I was at Choose we used AWS Lambda to implement the backend of an abandoned shopping cart service. We would then use that data to drive an email campaign to encourage the users to come back and finish purchasing an energy plan. It had a huge effect in driving conversion rates and we were able to implement the service in about 25 lines of vanilla java code. I opted not to use Spring as I judged the startup times to be too slow for it to be worth it. To manage libraries we used the maven shade plugin in our build process to build a fat jar.

In my current role we will deploy on AWS lambda as well. One thing I am looking for in considering serverless frameworks is what allows the developer to have a very nice flow as well, as back when we did the abandoned cart service debugging was a painful experience. At that point I think we did a bunch of console logging messages to figure it out. That won’t scale up for a development team that is going heavy into serverless it is too inefficient.

Then last week I came across this Spring Tips video about a new project Project Riff. I am happy to see Pivotal getting into this space as they build great frameworks and tools. And Riff seems no different it allows a developer to easily install it on their laptop and seems like it has first class support for Google Cloud and anyone’s infrastructure that is already running Kubernetes.

So I really liked the Riff part of that video. But then I was watching the Spring Cloud Function part. Now everyone who knows me knows that I love the Spring framework. I have been using it since 2008, and I think in terms of what it can do for you on Java server apps there is nothing else close. It really accelerates developer productivity and lets them focus on solving business problems. But as I watched this video I was sort of like I don’t get it. Like year I get that people want to use Spring in serverless, but when you watch it take 5 seconds to stand up a function, to me that is a deal breaker. It is too slow and if you are being charged by the second for your service paying 5 seconds to execute a function that will take less than a second is too expensive.

I was pretty much ready to write Spring Cloud Function off as a bad idea based on that then I saw something on Twitter about Dave Syer demoing something at Spring IO this week which brings massively faster startup times. I suspect it has something to do with the spring-context-indexer that Juergen talks about in this video, but I have been unable to find any examples or documentation on how to use it.

The other thing I need to take a look at is the AWS SAM Local tool. The big pain point I had doing Lamda’s a couple of years ago was around debugging them. This looks like it may solve that problem for us by giving us an convenient way to hook this into our development lifecycle.

MacOS Sierra Slowdown update

I have an update on my slowdown issues on Sierra. It appears the real problem lies in the AWS Java SDK. After talking to the spring boot people via github they were able to narrow it down to an Amazon issue. I opened an issue on github with Amazon and they responded that the version of the SDK that ships in the current spring cloud has this issue in it, and it has been fixed in a newer version of the SDK. One of the big value propositions of Spring Boot to me and the release train concept of Spring Cloud or Spring Data is that it is a collection of dependencies that have all been tested together, which lowers my risk of using them together. So I opened a request with Spring Cloud AWS to upgrade their SDK. Unfortunately they don’t seem very timely in responding to issues as I notice it looks like there are no responses on any of the issues raised in the last 2 weeks.

In the meantime I have a work around that doesn’t involve having to manually bump up your AWS SDK version and that is to set the following property in your application.properties file of your Spring Boot App:

cloud.aws.credentials.instanceProfile=false

Obviously setting this flag for your app running on AWS that uses the IAM profiles isn’t good, but it is a good local workaround on your development machine until the SDK gets updated in Spring Cloud.

Spring Boot and Security using Spring Data JPA for authentication

Recently one of my friends was working on a Spring Boot project and he was having trouble finding an example of how to configure user login for his site with Spring Boot using JPA. I had mentioned that there is some mention of configuring security in Greg Turnquist’s book Learning Spring Boot. He had just purchased Spring Boot in Action and I don’t think he was rushing to grab another book, but he hadn’t been able to find a good online tutorial.

Today I was browsing Twitter and I came across exactly what my friend was looking for. Priyadarshini B wrote a great online tutorial on doing just that on her blog. The post was so great I wanted to share it. So head over there and check it out, you won’t be disappointed as it will walk you through the whole process.

Spring autowiring name collisions

I am currently working on a project to move a bunch of data from SQL to Cassandra as the datastore. We have created a Cassandra Framework that looks very similar to the Spring Data JPA Framework that we use for SQL. Our Cassandra Framework we annotate data with @CassandraEntity and @CassandraRepository instead of @Entity and @Repository. For a time the data will live in both the SQL database as well as the Cassandra Cluster at the same time before we drop the SQL table. This will allow us to write to both tables and gradually switch over to the new cluster without as much risk if the cluster falls over.

I came across a weird and interesting issue today. We currently use field level injection to inject our components into our code. In the case of JPA we have something like a @Service which injects our component and into the service and then uses it for the database operations. We do the same thing our custom cassandra annotations. While we are working on this project we are going to for a time be writing to both the SQL database and the Cassandra datastore. At some point we will then switch to reading the data out of Cassandra and then later on drop the SQL tables and remove the JPA Entities entirely. The problem I am seeing is lets say we have 2 Entities:


package com.haskovec.persistence.jpa;

@Entity
public class Person {

@Id
Integer personId;

@Column
String name;
}

package com.haskovec.persistence.cassandra;

@CassandraEntity
public class Person {

@Id
Integer personId;

@Column
String name;
}

We have 2 distinct objects based on package name, but the objects have the same name. In this case we have 2 Repositories as well based on them for the @CassandraRepository and @Repository. The problem I am seeing is that Spring is having trouble qualifying which repository to inject. According to the documents for @Inject and @Autowired they are supposed to wire based on type. Instead I am getting an error where it can’t qualify which bean to wire which makes it look like it is wiring by name. I was able to fix it with the @Qualifier annotation and naming the @CassandraRepository with an @Component("cassandraPersonRepository") annotation.

I don’t really like this fix though. In theory since these are distinct types Spring should be able to auto wire them correctly. According to the Spring documentation wiring by name is done primarily through @Resource but if that were the case then a service injecting 2 repositories of the same name from a different package should work. Then I found this in the documentation:

If no name is specified explicitly, the default name is derived from the field name or setter method. In case of a field, it takes the field name; in case of a setter method, it takes the bean property name.

This makes me think it is wiring by name inspite of what the documentation says about wiring by type for @Autowired and @Inject. Then I found section 6.10.6 of the documentation. The following quote is telling:

When a component is autodetected as part of the scanning process, its bean name is generated by the BeanNameGenerator strategy known to that scanner. By default, any Spring stereotype annotation ( @Component, @Repository, @Service, and @Controller) that contains a name value will thereby provide that name to the corresponding bean definition.

If such an annotation contains no name value or for any other detected component (such as those discovered by custom filters), the default bean name generator returns the uncapitalized non-qualified class name.

So based on this both classes would be named personrepository hence the problem qualifying the bean. So now my thinking is that to fix this without using @Qualifier in my code I will need to implement a custom bean naming strategy by implementing BeanNameGenerator and passing that to the component scanner. The obvious fix to me seems to be to generate the name with the package name plus the class name so that classes of the same name resolve differently under spring. I will need to test it out to see if that works but I am guessing it will.

Field injection is not evil

I am a big fan of the work Oliver Gierke has done in Spring Data. It is a framework I use daily at work and it really is amazing. A while back Greg Turnquist had posted something on Twitter against field injection. So I asked what was wrong with field injection and he pointed me to this post that Oliver had written about it.

This post is going to be my attempt to argue against Oliver’s position on the subject. It may wind up an epic failure, but if nothing else I figured it would help me think through my thoughts and assumptions on the issue and see if I can make an argument in favor of it. First head over to Oliver’s post on the topic and read it before you continue on.

Argument 1: “It’s a null pointer begging to happen

In Oliver’s example he MyCollaborator into MyComponent with the @Inject tag that you would use in Spring or in CDI. Then his argument is that a person would instantiate MyComponent outside of the Container with MyComponent component = new MyComponent().

My first thought is, you are dealing with a container managed component if you have @Inject in it so if someone is standing up the component outside of the container to me that already says they are doing something wrong. Given that I don’t find this a compelling argument. If you are using the component in a framework as it is designed to be used the framework will tell you if it can’t wire up the component due to missing dependencies, whether your container is Spring or it is JavaEE.

I suppose one could imagine designing a component that could be used in either Spring or CDI or standalone without a framework, and Oliver’s constructor example could still work (assuming you don’t blow up on the missing @Inject annotation which I think could happen.) So in my opinion this argument isn’t really valid or a big concern as is someone is misusing your component I am not too concerned with them getting a null pointer in that scenario.

Let’s consider his benefits of Constructor Injection. The first case is you can only create your component by providing all the dependencies. This forces the user of the component to provide everything. While I consider this a valid argument, I think the point is somewhat moot since we are talking about designing a component that already has a lifecycle to it and that a framework will inject the dependency for.

His second benefit is that you communicate mandatory requirements publicly. I have to admit I find this his most compelling argument. I don’t have a counter argument to this.

His third argument is that you can then set those fields final. I have to admit I do like making everything final so that is also a compelling argument to me. But not enough to counter the negatives of it.

Let’s consider the argument that he tries to dispel:

An often faced argument I get is: “Constructors just get too verbose if I have 6 or 7 dependencies. With fields only, this is fine”. Awesome, you’ve effectively worked around a clear indicator that the code you write is doing way too much. An increase in the number of dependencies a type has should hurt, as it makes you think about whether you should split up the component into multiple ones.

I don’t buy his counter argument here. In the project that I am working on we have a bunch of service level business logic components. We have a thin service layer that we expose to the presentation tier, and then do all the heavy lifting of our business logic in these hidden service level components. Given the high volume of business logic code we have we compose the different operations with injected reusable business logic components. This is also a huge benefit when working with a large team you get less merge conflicts as the code is spread out across more files and when you are onboarding new employees you have a lot more smaller business logic classes that are easier to digest than some massive classes with all this business logic in it.

If I split those components up that is what we have already done which is why we have to inject them all over the place to reuse those business methods. I think when dealing with a non-trivial app that is extremely large, breaking things into fine grained components that are reusable in multiple places actually leads to needing to inject more fields and not less.

Argument 2: Testability

In this case Oliver argues that you have to be doing reflection magic in unit tests if you use field level injection. To which I respond if you are running a dependency injection framework why wouldn’t you be using a dependency injection unit test framework. And of course we do. The answer is Mockito. With Mockito you structure your unit test like you would structure your component. So to test my service I might have something like below:

@InjectMocks final MyService service = new MyService();

@Mock Component requiredComponent;

@Test public void myTest() {

when(requiredComponent.methodCall()).thenReturn(new MockedResponse);

final boolean result = service.methodIAmTesting();

assertTrue(result);

}

Now I have a unit test that is structured largely like my service. The testing framework injects the mocked dependencies into our service we are testing and we wire up the results on the mocks so we can test our service. Again this strikes me as very testable as now I am writing tests that look a lot like the way my services themselves look.

So that is my argument against. Basically I think the number of arguments to the constructor actually does get extremely unreasonable in many real world scenarios where you have a lot of finely defined business logic components that can be composed in many different ways to solve the project. You do end up with a lot more boiler plate, and even if you use Lombok to hide it then you have ugly and somewhat cryptic Annotations to tell Lombok to put the @Inject annotation on the constructor. I think if you are running a dependency injection framework, it isn’t reasonable for people to instantiate those objects outside of that framework, and likewise it is very reasonable to expect your unit test framework to also be dependency injection driven.

Let me know if I have persuaded anyone to my point or if you think I am completely wrong and Oliver is right about this, I would love to hear someone explain to me why my arguments are wrong and why Oliver has been right all along, or if there is a 3rd even better way what that way is.

Spring Boot Actuator Guide

One of the most interesting Spring Boot features to me is the Spring Boot Actuator. I just love the concept of having all these restful endpoints to get useful operational data right out of the box. One issue I have had is that I don’t actually know all the endpoints just a few that I have used here and there. Today I saw a link to the Complete Guide for Spring Boot Actuator which is a pretty amazing post that covers everything and anything that you would want to know. The purpose of this post is just so I can go back and find this data later. If you are playing around with Actuators go and check out this post.

Spring Boot for prototyping

I am on a new project at work that looks to be very interesting. I am redesigning our Cassandra layer. Currently we have a beautifully done layer that was designed and implemented by our former architect. It ends up making Cassandra look just like a JPA entity and we have Cassandra Repositories that look just like Spring Data JPA Repositories. After this was in place we discovered the Spring Data Cassandra project. We went to the talk on Spring Data Cassandra and it turns out they had implemented pretty much the system that our architect implemented.

Now my goal for this project is to create a higher level Cassandra abstraction for our system. Often in Cassandra we create multiple tables to represent the same data. The reason is depending on how you structure the data in CQL determines what queries you can run. We have the need to query some tables in many different ways so we need multiple tables to be able to answer the questions that we could in the SQL world. In our architecture we don’t want the developer to worry about which table they need to query for a given question, we would like to present this more like a standard JPA entity where the developer doesn’t need to worry about it and we abstract away which particular table is being queried or which tables are being saved to.

One of the initial thoughts of this project was to use Spring Data Cassandra. The advantage of that is we would have a third party library we could use so we wouldn’t have to maintain the low level Cassandra code. At one point I was considering ripping out our custom Cassandra Data layer and just using the Spring Data one (prior to this project) as ours is so close to what they are doing anyway why should we maintain that code when there is a perfectly good library we could use and we are already using Spring Data JPA. Right now I am not sure if I want to do that anymore though. If I go with Spring Data Cassandra each of the underlying tables would need to be modeled as a separate entity like our current framework. In that case then I would need a second layer on top if I am trying to present 1 domain object backing multiple tables so this seems like it isn’t ideal for what we are thinking. Another thing I am not 100% on with Spring Data Cassandra is that it isn’t backed by Pivotal. It is a community plugin. That isn’t necessarily a problem but I do have concerns about how up to date it will be. One way to look at this is maybe I should be involved in the plugin since clearly I could be working on that as well, but I get a little concerned about if it will be around otherwise. I noticed that the Spring Data Cassandra project is built off of the Datastax 2.0 driver. So if we are running off of Cassandra 2.1 (which we probably will be by the time this project goes live) we aren’t necessarily taking advantage of the new features. Again I could submit a pull request to update it, but given that I am not sure this is the right approach anyway at this point I haven’t decided to go this route (though that may change). Another thing I noticed is Spring’s initializr doesn’t list Cassandra as an option out of the box. Though I suspect if you checked JPA and then added the Spring Data Cassandra to your maven pom or Gradle file it would probably work.

So how does this tie into Spring Boot? Well I am not a big design everything up front kind of person. I tend to like to play around in code to come up with my design ideas. So I decided I want to prototype against what we are doing so I can see how this design would play out in code. I downloaded a new Spring project from the initializr with AOP, JAX-RS, Actuator, and Shell support. I then pulled our code for our Cassandra layer into there and added the Cassandra driver to the maven pom. I updated the application.properties file with my Cassandra database properties and low and behold I was up and running with a framework to test all of my changes in. Even though I have played around with boot, seeing myself able to build a sandbox to play around with this design in so quickly was very impressive to me. So now I can evolve this design without messing up our current code base and when I get to something I am happy with I can just bring those changes into back into our branch and we will be ready to go with our new design. So even though I am stuck with a monolith and I couldn’t easily bring boot into our main product the design of our project is such that it was very easy to pull that whole layer into this project and just be up and running with almost no configuration (aside from setting up the Cassandra connection properties).

So as usual I think Spring Boot is the bomb and everyone should be using it. I look forward to seeing where this design takes me. Once I have my high level sorted out I may try playing with dropping Spring Data Cassandra in the low level to see if we want to use that as our base, but my current guess is we won’t end up going that route.

Spring 4.1 finally!!!

Last Monday I got into the office and I decided that is it, I am going to get our app upgraded to Spring 4.1. I had been working on this off and on for like 9 months, updating dependencies in the pom, doing some testing, wash, rinse, repeat…

As I had mentioned in a previous posts one of the first issues I had was the new aspect j running the hibernate metamodel generator and dumping a bunch of generated class in the root level directory of wherever maven was running. I had opened a Jira against the aspectj-maven-plugin. There was even a user who contributed a patch for the issue, and the developer promised to look at it in January but months went by with no effort to resolve the issue. Now CodeHaus is shutdown and the active projects have moved to MojoHaus. As of yet the aspectj-maven-plugin hasn’t been moved so more and more it looks like my decision to download the code from their SVN repository and fork it on github was correct.

The first thing I did on Monday was to clone that repository and fix a couple of broken unit tests I had in it and then install it locally in our nexus server. Next up I updated the pom files to use my new version of the plugin and added the <proc>none</proc> config option that was introduced in aspectj 1.8.2. I fired up my local environment to test everything and discovered one of the major features of the app was broken. It looks like the way Spring 4.1 handles the ConverterFactories. We use a lot of Hibernate UserTypes in our app to map things to enums. The enums implement a common interface that handles the mapping between the storage of that enum and the value. With a little tweaking on how those enums were used I was able to get Spring to convert them correctly again using our Converter Factories.

I was thinking everything was good to go at this point and my testing discovered that our new feature that is Angular.js driven was broken. After much tracing and debugging I determined that some @ResponseBody parameters that in Spring 4.0 would accept an empty string in 4.1 that empty string was converted to a null and then the method was failing. I marked those methods to be @ResponseBody(required = false) and we were back up and running.

By this point it was already Wednesday morning. So I submitted the code to git and let jenkins run our tests on it. I immediately started getting some unit test failures saying that it couldn’t find the aspectOf() factory method. This didn’t make any sense as when you do compile time aspect weaving this method is supposed to be automatically added to your classes. I ended up digging through the aspectj source code as my first thought was what if somehow @Aspect isn’t being processed when you turn off annotation processing. I wasted way too much time down this path before I realized that it wouldn’t make sense as the whole point of ajc is to compile the aspects. Then in digging through the jenkins build log I realized what was really happening. The maven-java-compiler plugin 3.1 was actually running after the ajc compiler thus rewriting my woven classes with unwoven classes. When researching this issue I see a lot of people set the java-compiler plugin under maven to be <phase>none</phase>. We have ours set to test-compile with the ajc compiler set for the compile phase. When I tried to move test-compile to the ajc compiler it didn’t like some things we were doing with generics. I feel like the ideal fix would be to do that and don’t use the maven one at all. But since I just wanted to get this in and working I just reverted back to the maven-java-compiler version 2.5.1 which doesn’t seem to fire up again and rewrite the class. Todo for the future will be to try to entirely use the ajc compiler for the modules which need aspects woven into them.

After I had the aspectj issues solved I started seeing out of memory errors in our unit test phase. I banged my head on this for a day and a half before I figured out for some reason the combination of powermock-1.6.2 and junit-4.12 seem to be leaking memory or not shutting down some threads that are fired up when running the test. I tested going back to powermock-1.5.6 and junit-4.11 (since 4.12 isn’t compatible with powermock-1.5.6) and finally everything was happen and working. It was code reviewed yesterday and is now merged into master. So I am pretty excited to finally have reached the end of this project. I am hoping that the aspectj-maven-compiler will be resurrected from the dead and brought into mojohaus with my fix so that I can go away from my forked copy, but time will tell on that. Up next will be figuring out how to migrate to Spring Security 4.0.

Spring Security 4.0

I was checking the Spring Blog today to see what was new after taking much of the week off. I came upon the following entry. Of course I was very interested as Spring Security 4.0 has been hyped for a few months now so I figured I would check out the migration guide from 3.2 to see what will be involved for us to upgrade. I found this is the new feature section. They have added a feature which will now automatically prepend ROLE_ to any roles you use in Spring security if your role doesn’t start with that. So if you have a role called ROLE_USER for a standard user you can now just say @PreAuthorize(“hasRole(‘USER’)”).

The problem I have with this, is it assumes that you name all your roles with ROLE_. Unfortunately we don’t. When we migrated to Spring Security for our new architecture we already had a system that had over 700 different user rights in it. We mapped our user right system into Spring Security by implementing GrantedAuthority on our UserRights. This allowed us to maintain compatibility with our legacy architecture which some of our system runs on while seamlessly migrating other parts over to the new architecture. This is one of those opinionated things about the framework that is going to cause us a lot of issues. Now we are forced to conform to what Spring Security thinks we should name things instead of it just checking our collection of granted authorities to see if we have permission to carry out an operation. This is one of those changes that risks breaking things for many people with what gain you don’t have to type 5 characters? I don’t really get it and am annoyed as it means maybe we have to do some ugly hack like have our getter prepend that so we can keep our legacy name, but still satisfy the new “feature”. If nothing else it means it will be longer before we think about making this change as why add extra pain for yourself, unless you see a big benefit which at that point I don’t see a super compelling reason why I need to upgrade right now. So maybe we will get around to upgrading in the next year time will tell.

JHipster webinar

I saw this come across the Spring blog this week. They are going to be doing a webinar for JHipster. As I mentioned in a previous post I am very interested in JHipster as it combines 2 things I am interested in learning Spring Boot and Angular. If you are interested in checking it out sign up here.

Also as a completely unrelated side note, why doesn’t projects.spring.io support HTTPS? This is 2015 and all sites should really support secure access.