Tuesday, July 24, 2012

Email filtering using Aspect and Spring Profile

During web application development, often the need for sending emails arise.

However, sometimes the database is populated by data from production and there is a risk of sending emails to real customers during email test execution.

This post will explain  how to avoid it without explicitly write code in the send email function.

We would use 2 techniques:
  1. Spring Profiles - a mechanism to indicate what the running environment is (i.e. development,  production,..)
  2. AOP - in simplified words its a mechanism to write additional logic on methods in decoupled way.

I would assume you already have Profiles set on your projects and focus on the Aspect side.

In that example the class which sends emails is EmailSender with the method send, as specified below:

public class EmailSender {
//empty default constructor is a must due to AOP limitation
public EmailSender() {}

//Sending email function
//EmailEntity - object which contains all data required for email sending (from, to, subject,..)
public void send(EmailEntity emailEntity) {
//logic to send email
}
}


Now, we will add the logic which prevent sending email to customers where code is not running on production.
For this we will use Aspects so we won't have to write it in the send method and by that we would maintain the separation of concern principle.

Create a class that will contain the filtering method:
@Aspect
@Component
public class EmailFilterAspect {

public EmailFilterAspect() {}
}

Then create a PointCut for catching the send method execution:

@Pointcut("execution(public void com.mycompany.util.EmailSender.send(..))")
 public void sendEmail(){}

Since we need to control whether the method should be executed or not, we need to use the Arround annotation.

@Around("sendEmail()")
public void emailFilterAdvice(ProceedingJoinPoint proceedingJoinPoint){
 try {
  proceedingJoinPoint.proceed(); //The send email method execution
 } catch (Throwable e) {                           
  e.printStackTrace();
 }
}

As a last point, we need to access the send method input parameter (i.e. get the EmailEntity) and verify we don't send emails to customers on development.

@Around("sendEmail()")
 public void emailFilterAdvice(ProceedingJoinPoint proceedingJoinPoint){

 //Get current profile
ProfileEnum profile = ApplicationContextProvider.getActiveProfile();

Object[] args = proceedingJoinPoint.getArgs();        //get input parameters
        if (profile != ProfileEnum.PRODUCTION){
            //verify only internal mails are allowed
            for (Object object : args) {
                if (object instanceof EmailEntity){
                    String to = ((EmailEntity)object).getTo();
                    if (to!=null && to.endsWith("@mycompany.com")){//If not internal mail - Dont' continue the method                        
                        try {
                            proceedingJoinPoint.proceed();
                        } catch (Throwable e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }else{
            //In production don't restrict emails
            try {
                proceedingJoinPoint.proceed();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
}

That's it.
Regarding configuration, you need to include the aspect jars in your project.
In Maven it's look like this:

        org.aspectj
 aspectjrt
 ${org.aspectj.version}


 org.aspectj
 aspectjweaver
 ${org.aspectj.version}
 runtime


and in your spring application configuration xml file, you need to have this:




Good luck!

Thursday, July 19, 2012

Seamlessly Static Meta Model generation

I would like to introduce a simple, quick and straight forward way to create Static Meta Model classes.

First, I would like to correct a perception I had in my previous post regarding the place such files are created.
Since the Static Meta Model files are generated classes and should automatically changed for each @Entity modification they should placed in the target folder and not comitted to the repository.

Moreover, creation of static meta model files via Eclipse works correctly if you use the appropriate generation project version and te right plugin.

First step is to get the class generation jar. Put in pom.xml :
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>1.1.1.Final</version>
        </dependency>

Then in eclipse add the annotation generation plugin via Help ->Eclipse Market place -> search for "Apt M2E" and install it.

After the installation right click on your project -> properties -> Java compiler-> Annotation processing -> mark "enable project specific settings" (and actually all the checkboxes on that screen), in the Generated Source Directory put "target\generated-sources" (This will generate the classes in your target folder).

Inside the Annotation processing item there is a Factory Path item, enable this part as well and set the jar we import via maven to generate the classes. You can do it by clicking Add Variable -> M2_REPO -> Extend -> and choose the following: path : /org/hibernate/hibernate-jpamodelgen/1.2.0.Final/hibernate-jpamodelgen-1.2.0.Final.jar

Make sure only that path is checked.

As a final step, please make sure the target\generated-sources folder is on your classpath (right click-> build path -> ad as source folder).

That's it. Every change should trigger automatic static meta model generation.

Friday, June 1, 2012

Spring Data JPA - Limit query size

This one is very informative and short:

If you are using Spring Data JPA, you are probably familiar with the technique of query creation out of methods names.

Following that mechanism, there is no explicit way to use the LIMIT keyword in the query name,
However, there is a simple way to use the SQL LIMIT with these queries.
The implicit way to limit the query result size is to utilize the pagination mechanism.
 
Simply provide and extra paging object with the objects number you need to limit.


Below is a simplified example of how the repository interface should be used:
public interface EntityRepository extends CrudRepository, JpaSpecificationExecutor {

 List findByEntityMemberNameLike(String query, Pageable pageable);//Pageable will limit the query result

}


Below is a simplified example of how the usage of such query could be:
@Autowired
EntityRepository entityRepository;

...

int queryLimit = 10;
List queryResults = entityRepository.findByEntityMemberNameLike(queryString, new PageRequest(0, queryLimit));



LESS is more?

Recently I've been exposed to LESS which is a UI framework.
In a nutshell, this framework extends the standard CSS in a way that insert programming flavor into it, such as inheritance, variables, functions and build.
(By the way - this is not the only framework with such concept)


Using this framework has some pros and cons which I would like to highlight.
Pros:
  • Enable css reuse via inheritance, variables and more.
  • Build *one* css for the final html to use.
Cons:
  • Introduce another development language, which requires strong CSS knowledge (if you use it well, otherwise, no point to use it)
  • End-to-end developers (UI to server) might need another domain to maser
  • Coupling your project with another framework. Disconnecting from less is not simple
  • Produced css are not ideal for development phase and debug
  • CSS changes can be done only via this framework/language


At first review this LESS technique sounds like a css simplification magic, however at the end we stopped using it since its cost/benefit was low.

Please let me specify my claims.
The main disadvantage of this framework, IMHO, is that it makes your project too couples with it.
While the generated CSS is ideal for production, in development environment, it's very hard to work with.
In a typical project where several UI frameworks (e.g. jquery) are involved - imagine how long the one output css file will be.
Moreover, not only that it would be very hard to work on the CSS output directly, it would be very hard in the future to separate it to file per framework since LESS does not support it.

Another disadvantage is that in order to use this framework properly, the developer need to learn another language and expertise in a domain which is not necessary the developer strong side.

This tool is mainly used by UI side people, so knowing that tool is like Java developer to know Spring framework, however, this does not work the other way around - for Java developers such tool added complexity. It is one thing to know JS or modify slightly css, and another thing to have experience in CSS inheritance and advanced techniques.

I think it applies for LESS developers as well. How many UI developers do you know who master Spring or Hibernate...

Anyway I hope my experience would help other to estimate whether to use such framework or not.

Eclipse metamodel generation (JPA 2.0) issues

Update:
Please see updated post in that manner which simplifies the process a bit better.

Static Metamodel classes are uses for type safe queries in JPA2.0 standard.

There are few ways to create these classes:
1. Define the IDE (e.g. eclipse) to generate the files automatically (like the IDE automatic build which generates the class files on each Java file change).
2. Define maven to generate the files. The generation will be done when running the maven script.

 I would recommend to avoid the generation via the Eclipse IDE, since I've noticed that the generated static meta model are inaccurate (e.g. some members were missing).

 I'm not sure what the reason is since the missing member has no special attribute that differentiate it form the other class members that are generated, however, the fact is that it is constantly not generated.

Static meta model files generation via maven overcome this issue.


Good luck !

Thursday, May 10, 2012

Too L@zy for Debug

If you use JPA in your application and have @Lazy fetching on your Entities properties, please note that debugging might be impossible.

for example:
@Entity
public class Order[
@OneToMany(fetch=FetchType.LAZY,mappedBy = "order")
Set items;
//...
}
I encounter the issue with Spring IDE (STS 2.9), Spring 3.1 and JUnit 4.
When running a JUnit test  against the Service layer which needed to read lazy properties - same line of code (the invocation of a Lazy property) failed on Debug (exception) however succeeded on Run mode.

The problematic line is something like that:
Order order = getOrderById(orderId);
order.getItems(); // Exception on debug

Black magic indeed.

Hope this save time to someone..



Friday, April 20, 2012

When developers responsible to UX

While browsing in a mobile eCommerce site, I found something I haven't seen before and which I think quite amusing.
I guess that how web sites would have been look if developers would be responsible for UI.. :-)
 


Pay attention to the number the counting start with. :-)