Pages

Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Friday, August 22, 2014

Developing a dynamic JEE service client with CDI (part 2)

In the previous blog entry I described how to develop an JEE service client that performs lazy lookups and is injectable to satisfy a service dependency. In this article I want to describe how to extend this service client to allow client-side service call interception.

Before I dive into the details of the interception, I want to outline the reasons why client-side call interception might be useful.

Background

In our current project we aspired a RESTful component-based architecture. For each of the components it should be possible to integrate them in a service oriented architecture via WebService, deploy them in a JEE environment accessing it as JNDI-locateable services or access them via a RESTful lightweight interface. Each component should be deployable standalone and should be operational as long as their lower-level component dependencies are satisfied. To be RESTful, our architecture followed the seven principles of REST, described in the famous thesis of Roy Fielding.

With JEE we could easily add caching behavior on the service side of a service consumer-provider relationship by adding an interceptor that serves a call with data from a cache and therefore reducing processing resource usage on the service side.

On the consumer side there is no such mechanism as to transparently intercept a service call before it is actually sent to the service. Such a client-side call interception could be of use for a range of use-cases
  • caching, to reduce network resource usage
  • error handling and fault tolerance
  • logging
  • security
 The following description uses the service client I described in a previous blog post.

Adding Interceptor support

In order to add call interceptors to the service client, we have to extend the invocation handler that delegates the service method invocation to the actual service by adding a stack of interceptors that are invoked consecutively.

When a JEE interceptors is invoked an InvocationContext is passed to the interceptor. The interceptor may decide to fully intercept the request and not proceeding the invocation further. This is behavior is needed for caching or security concern. Alternatively, interceptors may execute some additional operations before or after proceeding with the invocation which is useful for logging or error handling.

The InvocationContext is an interface introduced by JEE6. I used my own implementation of this interface where the getter methods defined by the interface simply return the values that are passed to the InvocationHandler of the dynamic proxy (see the ProxyServiceInvocationHandler of the previous blog post), the getTimer() method returns null, as I don't really need it. The main functionality of the InvocationContext however resides in the proceed() method. I used a stack (Deque) to maintain a list of registered interceptors of which each is checked whether it may intercept the method invocation or not.

The check is done in the method isInterceptedBy and does check the class of the interceptor instance as well as the method whether they both are annotated with the same the InterceptorBinding annotation. I deviated a bit from the JEE6 standard as I allowed an interceptor without an explicit interceptor binding to intercept any method invocation, but that is up to you.
The main method of my InvocationContext implementation are shown in the next listing

class ProxyInvocationContext implements InvocationContext {

  ...

  @Override
  public Object proceed() 
    throws IllegalAccessException, 
           IllegalArgumentException, 
           InvocationTargetException {
    if (!interceptorInvocationStack.isEmpty()) {
      final Object interceptor = interceptorInvocationStack.removeFirst();
      if (isInterceptedBy(interceptor)) {
        final Method aroundInvoke = interceptorMethods.get(interceptor);
        return aroundInvoke.invoke(interceptor, this);
      }
    }
    return this.method.invoke(target, this.parameters);
  }
  
  private boolean isInterceptedBy(final Object interceptor) {
    boolean hasNoBinding = true;
    for (final Annotation an : interceptor.getClass().getAnnotations()) {
      if (an.annotationType().getAnnotation(InterceptorBinding.class) != null) {
        hasNoBinding = false;
        if (getMethod().getAnnotation(an.annotationType()) != null) {
          return true;
        }
      }
    }
    return hasNoBinding;
  }
}

Instantiating Interceptors in CDI Context using DeltaSpike

Now we want to create interceptors and put them into the interceptor stack. The JEE 6 standard already defines interceptors so we could simply re-use this specification. JEE6 compliant interceptors may be used in a CDI lifecycle, that means lifecycle methods annotated with @PostConstruct or @PreDestroy are executed as well as injection of dependencies.
With the implementation of the InvocationContext described above, we need a collection of interceptor instances. In our project I used a configuration file (similar to the beans.xml where you have to define which interceptors should be loaded) where I defined the interceptor classes that should be loaded.

Creating an instance of a class by the fully qualified name of the class is trivial using reflection (i.e. Class.forName("...").newInstance()). But when you have a CDI container you want to let the container do the creation and further process the lifecycle of the the instance including dependency injection.

JEE6 itself does not provide the means for that but it defines an SPI. The Apache DeltaSpike project offers an implementation for that SPI (btw. it is developed by the same guys behind CDI in JEE6 itself). DeltaSpike allows to interact directly with the CDI container.

The following code snippet assumes, that you have already loaded the interceptor class and verified it is annotated with the @Interceptor annotation. It first checks, if a CDI environment is active, if not, the interceptor is instantiated the traditional way. If it is active, a BeanManager reference is obtained, an injection target is created using the interceptor class. This is needed to create the instance and inject dependencies to the instance. With the injection target, an interceptor Bean is created using the BeanBuilder of DeltaSpike. The Bean is a Contextual instance that is required by the manager to create a creational context. Having this context we can create a managed instance using the create method. DeltaSpikes contribution to the snippet is the BeanManagerProvider , the BeanBuilder and the DelegatingContextualLifecycle.

private <I> I createInterceptor(final Class<I> interceptorClass) 
  throws InstantiationException, IllegalAccessException {
  
  final I interceptor;
  
  if (BeanManagerProvider.isActive()) {
    final BeanManager manager = BeanManagerProvider.getInstance().getBeanManager();
    final InjectionTarget<I> target = manager.createInjectionTarget(
                                            manager.createAnnotatedType(interceptorClass));
            
    final Bean<I> interceptorBean = 
      new BeanBuilder<I>(manager)
          .beanClass(interceptorClass)
          .beanLifecycle(new DelegatingContextualLifecycle<I>(target))
          .create();
    interceptor = interceptorBean.create(
                     manager.createCreationalContext(interceptorBean));

  } else {
    interceptor = interceptorClass.newInstance();
  }
  return interceptor;
}

Conclusion

In this article I described how the Dynamic Service Client can be extended in order to provide client-side service call interception and how Interceptors (or Beans in general) can be instantiated in a CDI context using Apache DeltaSpike.

Wednesday, July 23, 2014

Developing a dynamic JEE service client with CDI (part 1)

With JEE6 CDI was introduced in and standardized for the Java Enterprise world. The main scope for the CDI extension was for enterprise services as it simplified various mechanisms in the JEE world such as EJB lookup or invocation interception. Unfortunately the new features fall a bit short on the consumer side of services implemented with CDI, in particular the lookup or service locator pattern, and client side invocation interception.
In this first article I want to describe a dynamic service client that performs lazy service dependency resolution (lookup) and that can be injected into a CDI injection point.
It is a good base for being extended to use sophisticated configuration or error handling mechanisms.

Defining a Dynamic Service Locator

In JEE6 its quite easy to perform a JNDI lookup for an EJB using the @EJB annotation. Unfortunately this is done during construction of the service consumers. When you have a multi-module project where each module should be deployable independently from the others, deployment will fail if the dependencies defined by the @EJB annotation could not be satisfied, that is, the EJB lookup fails.
The key to this problem is a lazy lookup, that is done first time the dependency is actually needed. But that is not supported by the @EJB annotation.
In our current project we solved the problem by implementing a dynamic service proxy that implements the interface of the service and performs the lookup using a JNDI lookup or another strategy on the first actual service call.

Creating a Proxy

Creating a dynamic proxy is relatively simple, you need a custom implementation of an InvocationHandler that performs the actual method invocation and need to specify the interfaces the dynamic proxy should implement. A factory method is used to create such a proxy instance. The the following code example shows such a factory method:
public abstract class DynamicServiceClient {

  public static <T> T newInstance(final Class T serviceInterface) {
    return (T) java.lang.reflect.Proxy.newProxyInstance(
      getClassLoader(),
      new Class[] { serviceInterface }, 
      new ProxyServiceInvocationHandler T(config));
    }
 
  private static ClassLoader getClassLoader(){
     ...
  }
}

Invocation Handler

The invocation handler delegates all service call to an instance of the actual service. The service is kept as an instance field of the invocation handler that is initialized upon the first service call using a Service Locator. The invoke method of the Invocation Handler delegates the call to the service instance.

class ProxyServiceInvocationHandler<T> 
  implements InvocationHandler {
 /**
  * The service reference that is lazily initialized
  */
  private T service; 

 /**
  * The service locator that performs the actual lookup
  */
  private final ServiceLocator<T> locator;

    ...

  @Override
  public Object invoke(final Object proxy, final Method method, final Object[] args) 
    throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    //do the lookup if not already done
    if (this.service == null) {
      this.service = this.locator.locate();
    }
    //do the actual service call and return the result
    return method.invoke(this.service, args);
  }
}

Service Locator

The service locator that is used in the the above listing performs the actual lookup. In our project I used an implementation that allowed to define a location strategy in a configuration, with the JNDI lookup being implemented in one of the strategies. The following example however shows a simple implementation that performs a straightforward JNDI lookup using a lookupName.

public class ServiceLocator<T>{
 /**
  * the name for the JNDI lookup
  */
  private String lookupName;

    ...

  public T locate() {
    final Context context = new InitialContext();
    T service = (T)context.lookup(this.lookupName);
    return service;
  }
}

Service Injection

In order to use the dynamic service shown above and inject it via CDI, I used a producer method that creates instances of the dynamic service and a qualifier to distinguish the dynamic service client from the actual service implementation that might be available in the CDI container as well.
The creation of the instance itself is done by the static factory method shown in the first listing. The producer extends the DynamicServiceClient I described earlier and uses its static factory method. In order to keep the producer class simple, we need to extend some methods to the DynamicServiceClient.

The extended DynamicServiceClient that is shown in the following listing contains the logic for the actual service proxy instantiation and an abstract method returning the interface class of the service to be instantiated that has to be implemented by the producer.

public abstract class DynamicServiceClient<T>{
  /**
   * Instance of the service client
   */
  private T serviceInstance;

  /**
   * The method has to return the interface of the service 
   */
  protected abstract Class<T> getServiceInterface();

  /**
   * Creates a new instance of the service client. 
   */
  protected T getInstance() {
   if (serviceInstance == null) {
       serviceInstance = newInstance(getServiceInterface());
   }
   return serviceInstance;
 }

  /**
   * The factory method to create a new service instance
   */
  public static <T> T newInstance(final Class serviceInterface) {
    return (T) Proxy.newProxyInstance(
        getClassLoader(),
        new Class[] { serviceInterface }, 
        new ProxyServiceInvocationHandler());
    }
  }

  private static ClassLoader getClassLoader(){
     ...
  }
}

To qualify an injection point and the producer method to create and inject instances of the service client that implement the service interface and not instances of the actual service, I used a qualifier as shown in the next listing.

@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER })
public @interface ServiceClient {}

Now we're ready to define a producer using the DynamicServiceClient as base class. The producer is relatively simple as it only contains two simple methods.


public class MyServiceClientProducer 
  extends DynamicServiceClient<MyBusinessService> {

  @Produces @ServiceClient 
  public MyBusinessService getInstance() {
    return super.getInstance();
  }

  protected Class<MyBusinessService> getServiceInterface() {
    return MyBusinessService.class;
  }
}
To inject the dynamic service client into an injection point we simply have to define the Service interface class and use the qualifier. That's it.

public class MyServiceConsumer {

  @Inject @ServiceClient
  private MyBusinessService service;

  ... 
}

Instead of
public class MyServiceConsumer {

  @EJB(lookup="...")
  private MyBusinessService service;

  ... 
}

Conclusion

In this article I described how to implement a dynamic service locator that can be used in a CDI container. The service locator performs a lookup upon the first call of a service method and therefore provides a mechanism for fault tolerant dependency resolving and further a foundation for implementing client-side service call interception - which I will a describe in a future post.

Tuesday, April 29, 2014

JUnit Testing with Jackrabbit

Writing unit tests for your code is not only best practices, it's essential for writing quality code. In order to write good unit tests, you should use mocking of code not under test. But what if you're using a technology or an API that would require quite a lot of complicated mocks?
In this article I'd like to describe how you write unit tests for code that accesses a JCR repository.

At first I really tried to mock the JCR API using Mockito, but stopped my attempt at the point where I had to mock the behavior of the Query Object Model. It became apparent, that writing mocks would outweigh the effort to write the actual production code by far. So I had to search for an alternative and found one.

The reference implementation of JCR is the Apache Jackrabbit project. This implementation comes with a set of JCR Repository implementations, one of these is the TransientRepository. The TransientRepository starts the repository on first login and shuts it down on the last session being closed. The repository is created in memory which works pretty fast and makes it the best solution for unit testing. But nevertheless, a directory structure is created for the repository and unless not specified a config file is created as well.

For writing unit tests against this repository, we need the following:
  • a temporary directory to locate the directory structure of the repository
  • a configuration file (unless you want one created on every startup)
  • the repository instance
  • a CND content model description to initialize the repository data model (optional) 
  • an admin session to perform administrator operations
  • a cleanup operation to remove the directory structure
  • the maven dependencies to satisfy all dependencies
Let's start with the Maven dependencies. You need the JCR Spec, the Jackrabbit core implementation and the Jackrabbit commons for setting up the repository.

<properties>
  <!-- JCR Spec -->
  <javax.jcr.version>2.0</javax.jcr.version>
  <!-- JCR Impl -->
  <apache.jackrabbit.version>2.6.5</apache.jackrabbit.version>
</properties>
...
<dependencies>
<!-- The JCR API -->
  <dependency>
    <groupId>javax.jcr</groupId>
    <artifactId>jcr</artifactId>
    <version>${javax.jcr.version}</version>
  </dependency>
  <!-- Jackrabbit content repository -->
  <dependency>
    <groupId>org.apache.jackrabbit</groupId>
    <artifactId>jackrabbit-core</artifactId>
    <version>${apache.jackrabbit.version}</version>
    <scope>test</scope>
  </dependency>
  <!-- Jackrabbit Tools like the CND importer -->
  <dependency>
    <groupId>org.apache.jackrabbit</groupId>
    <artifactId>jackrabbit-jcr-commons</artifactId>
    <version>${apache.jackrabbit.version}</version>
    <scope>test</scope>
  </dependency>
</dependencies> 

Now let's create the directory for the repository. I recommend to locate it in a temporary folder so multiple test runs don't affect each other if cleanup failed. We use the Java TempDirectory facility for that:
//prefix for the repository folder
import java.nio.file.Files;
import java.nio.file.Path;
...
private static final String TEST_REPOSITORY_LOCATION = "test-jcr_";
...
final Path repositoryPath = 
      Files.createTempDirectory(TEST_REPOSITORY_LOCATION);

Next, you require a configuration file. If you already have a configuration file available in the classpath, i.e. in src/test/resource, you should load it first:
final InputStream configStream = 
  YourTestCase.class.getResourceAsStream("/repository.xml");

Knowing the location and the configuration, we can create the repository:
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.apache.jackrabbit.core.TransientRepository;
...
final Path repositoryLocation = 
      repositoryPath.toAbsolutePath();
final RepositoryConfig config = 
      RepositoryConfig.create(configStream, repositoryLocation.toString());
final TransientRepository repository = 
  new TransientRepository(config);

If you ommit the config parameter, the repository is created in the working directory including the repository.xml file, which is good for a start, if you have no such file.

Now that we have the repository, we want to login to create a session (admin) in order to populate the repository. Therefore we create the credentials (default admin user is admin/admin) and perform a login:
final Credentials creds = 
  new SimpleCredentials("admin", "admin".toCharArray());
final Session session = repository.login(creds);

With the repository running and an open session we can initialize the repository with our content model if require some extensions beyond the standard JCR/Jackrabbit content model. In the next step I import a model defined in the Compact Node Definition (CND) Format, described in JCR 2.0
import org.apache.jackrabbit.commons.cnd.CndImporter;
...
private static final String JCR_MODEL_CND = "/jcr_model.cnd.txt";
...
final URL cndFile = YourTestCase.class.getResource(JCR_MODEL_CND);
final Reader cndReader = new InputStreamReader(cndFile.openStream());
CndImporter.registerNodeTypes(cndReader, session, true);

All the code examples above should be performed in the @BeforeClass annotated method so that the repository is only created once for the entire test class. Otherwise a lot of overhead will be generated. Nevertheless, in the @Before and @After annotated methods, you should create your node structures and erase them again (addNode() etc).

Finally, after you have performed you test, you should cleanup the test environment again. Because a directory was created for the transient repository, we have to remove the directory again, otherwise the temp folder will grow over time.
There are three options for cleaning it up.
  1. Cleaning up in @AfterClass annotated method
  2. Cleaning up using File::deleteOnExit()
  3. Cleaning up using shutdown hook
I prefer combining 1 and 3 for fail-safe deletion. For option 1 we require a method to destroy the repository and cleaning up the directory. For deleting the directory I use Apache Commons FileUtil as it allows deletion of directory structures containing files and subdirectories. The method could look like this:

import org.apache.commons.io.FileUtils;
...
@AfterClass
public static void destroyRepository(){
  repository.shutdown();
  String repositoryLocation = repository.getHomeDir();
  try {
    FileUtils.deleteDirectory(new File(repositoryLocation));
  } catch (final IOException e) {
   ...
  }
  repository = null;
}

As fail-safe operation I prefer to add an additional shutdown hook that is executed when the JVM shuts down. This will delete the repository even when the @AfterClass method is not invoked by JUnit. I do not use the deleteOnExit() method of File as it requires the directory to be empty while I could call any code in the shutdown hook using my own cleanup implementation.


A shutdown hook can easily be added to the runtime by specifying a Thread to be executed on VM shutdown. We simply add a call to the destroy methode to the run() method.
Runtime.getRuntime().addShutdownHook(new Thread("Repository Cleanup") {
  @Override
  public void run() {
    destroyRepository();
  }
});

Now you should have everything to set-up you Test JCR Repositoy and tear-down the test environment. Happy Testing!

Friday, September 11, 2009

Creating a singleton using Eclipse Code Templates

In this post I'd like to demonstrate the Eclipse Code Template feature for implementing a singleton pattern.
The Singleton is a creational pattern of the set of Gang-of-Four Java Design patterns. It uses a single static variable (the singleton), a private constructor to prevent public instantiation and a public static getter method to retrieve the instance. For lazy instantiation, the singleton instance is not preinitialized, instead, the static getter method checks if the instance is null and instantiates a new instance on its first call. Lazy instantiation (as used in the following example) is not uncommon, though it may cause race conditions in multithreaded environments.
The Code Template feature is an extension to the code-completion functionality that is accessible by pressing Ctrl+Space. When the user types in code, he may hit Ctrl+Space to auto-complete, what he was typing. Eclipse proposes a set of options for completion, i.e. a Type, method of that type etc.
The Code Template feature might be known from typing in "sysout", pressing Ctrl+Space and Eclipse completes this to "System.out.println("");".
To add a new code template,
  1. open to Window -> Preferences
  2. navigate to Java -> Editor -> Templates.
  3. click on "New..."
  4. set the name of the new template to "singleton" (this is what you type into the editor)
  5. as pattern enter
    /**
     * static Singleton instance
     */
    private static ${enclosing_type} instance;
    /**
     * Private constructor for singleton
     */
    private ${enclosing_type}(){
    }
    /**
     * Static getter method for retrieving the singleton instance
     */
    public static ${enclosing_type} getInstance(){
      if(instance == null) {
        instance = new ${enclosing_type}();
      }
      return instance;
    }

The variable ${enclosing_type} resolves to the Class you are editing. From now on, it is possible to create the entire singleton pattern by just typing "singleton" and hitting Ctrl+Space - saving lots of keystrokes!