Tuesday, February 24, 2015

Factory Pattern using Spring injection

In this article, let us see how to use Spring injection to use the factory design pattern.

What is factory design pattern?

From wikipedia, the factory design pattern is:"In class-based programming, the factory method pattern is a creational pattern which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor."

The advantage of the factory pattern is the caller just sends the information about which class the caller would like to execute based on the runtime scenario.  A typical example is when you want to encrypt a string based on different RSA algorithms, you can write the encrytion methods in individual classes and at run time, the caller can choose to call the factory method to specify which algorithm he needs to encrypt the data.

To implement the above example, I have created an interface called ICrypto which has two methods: encrypt and decrypt:



           public interface ICrypto{
             public byte[] encrypt(byte[] plaintext);
             public byte[] decrypt(byte[] encryptedText);
           }


The implementation of the above interface for AES will be:


           public class AESCrypto implements ICrypto {
             public AESCrypto() {}
             public byte[] encrypt(byte[] plaintext){
               ...
               //your code here
               ...
               return encryptedBytes;
             }

             public byte[] decrypt(byte[] encryptedtext){
               ...
               //your code here
               ...
               return plainTextInBytes;
             }
           }

Similarly, for RC2, the implementation is:

           public class RC2Crypto implements ICrypto {
             public RC2Crypto() {}
             public byte[] encrypt(byte[] plaintext){
               ...
               //your code here
               ...
               return encryptedBytes;
             }

             public byte[] decrypt(byte[] encryptedtext){
               ...
               //your code here
               ...
               return plainTextInBytes;
             }
           }

Define the crypto types enum:

           public enum CryptoTypes{
             AES_CRYPTO_TYPE,
             RC2_CRYPTO_TYPE;
           }


Now we need a factory class which is going to create the instance of one of the implementations above:

           public final class CryptoFactory {
             //make sure the constructor is not accessible.
             private CryptoFactory(){}
             //factory method
             public final static ICrypto getCryptoInstance(CryptoTypes type) {
               switch(type){
                case AES_CRYPTO_TYPE:
                 return new AESCrypto();
                case RC2_CRYPTO_TYPE:
                 return RC2Crypto();
               }
             }
           }

Now the caller can call the CryptoFactory.getCryptoInstance() with the enum value as a parameter and get the instance,

The above is a typical example of the factory pattern in non-spring world.

In Spring, all of the above are the same except the factory class.  Using the injection mechanism, the factory class need not go through the switch() statement.  Lets see how this can be achieved:

  1.  First define all the implemented beans in the spring bean definition XML.For example:
    <bean id="crypto.rc2crypto" class="com.example.RC2Crypto"></bean>
  2. Then define the enum constants also as a bean instance.  For example:                               <bean id="ctyptotype.enum.rc2" class="com.example.CryptoTypes" factory-method="valueOf"            <constructor-arg value="RC2_CRYPTO_TYPE"/>                                                                 </bean>
  3. Now wire up the crypto type bean definitions with the implementation bean definitions as a map.  For example:                                                                                                                                    <util:map id="cryptoMap" map-class="java.util.LinkedHashMap">
    <entry key-ref="ctyptotype.enum.rc2" value-ref="crypto.rc2crypto" />
    <entry key-ref="ctyptotype.enum.aes" value-ref="crypto.aescrypto" />
       </util:map>
  4. Wire the factory bean instance with the map we created in 3.  For example:                    <bean id="crypto.factory" class="com.example.CryptoFactory">                                                            <property name="cryptoTypes" ref="cryptoMap" />                                                   </bean>

With the above implementation, the same CryptoFactory will look like this:


           public final class CryptoFactory {
             private Map cryptoTypes;

             public Map getCryptoTypes() {
               return cryptoTypes;
             }

             public void setcryptoTypes(Map cryptoTypes) {
               this.cryptoTypes = cryptoTypes;
             }

             public ICrypto createCryptoFactory(CryptoTypes cryptoType){
               return cryptoTypes.get(cryptoType);
             }
           }

Now the caller can inject the instance of the crypto factory bean in their bean class and call createCryptoFactory(CryptoType.AES_CRYPTO_TYPE).

Even better way is the caller bean can define allowed crypto types for that bean (for example, the bean can use only AES_CRYPTO_TYPE) and use that variable instance to call createCryptoFactory().   It is now boiled down to the bean implementor's design.

Advantages of using Spring injection

As I mentioned above, once we defined all the possible types as enum, the caller bean can control which subset of enum types it can use to get the crypto implmentation's instance.  This adds more security as module X in the application can use only AES crypto type whereas module Y can use only RC2 crypto type.

Also, turning on or off of any crypto type is going to be only in the spring context XML files rather than in the code.  The factory class is encapsulated from which crypto types it is using.

And that is all folks,,,,


Wednesday, January 7, 2015

Useful Regular Expressions

Often times we need to search and if needed, replace the text in the large document or extract logs based on some fixed string values.  This post lists some of the regular expressions I have used very often.  This post will be updated regularly as I come across new regular expressions for new use cases:

Use Case 1:

Find a position if the first occurrence of the string.  for example, find the first occurrence of the string "SF_".  This will highlight the line up to that string.

^.*?(?=SF_)

Use Case 2:

Select whole line.

(.+)

Use Case 3:

Surround the entire line with the double quotes and add "," after the endquote.

"\1",

Use Case 4:

Find end of the line and add "," at the end.

Search: ([^\n])$
Replace : \1,

Use Case 5:

Find a string and highlight up to the end of the line.

Search: <string>.*

Example:
query.*


That is all for now.  As I mentioned in the beginning, I will update this post as I come across interesting scenarios.

Monday, November 3, 2014

JSON Schema validator

Like XML, JSON also provides schema and the code has to validate the json instance with a schema.  In this post, let us see how we can validate the given instance with its JSON schema.

The validator I would recommend is 'json-schema-validator'.  The version I have used is 2.0.1, which  supports both v3 and v4 Json schemas.  You can take a look at the latest versions of the validator also.

Add the following in your pom.xml:

<dependency>
    <groupId>com.github.fge</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>2.0.1</version>
</dependency>

Then follow these steps:

1) If the schema or the instance are strings, transform them to JsonNode objects:

            ObjectMapper mapper = new ObjectMapper();
             //json instance object
            JsonNode instanceJsonObject = mapper.readTree(jsonInstance);
            //json schema string to json object.
            JsonNode schemaJsonObject = mapper.readTree(jsonSchema);
2) Next step is to get the json schema object:

             //The schema factory supports both Json's v3 and v4 schemas.  Most of the times, the default
             //factory is enough.
             JsonSchemaFactory schemaFactory = JsonSchemaFactory.byDefault();            
             JsonSchema schema = schemaFactory.getJsonSchema(schemaJsonObject );
3) Now the instance can be validated with the validate() of JsonSchema:

             ListProcessingReport report = (ListProcessingReport)schema.validate(instanceNode);
The ListProcessing contains the valiation messages, the missing required field(s) details.  To obtain those details, follow these steps:

            if(!report.isSuccess()){

                JsonNode reportRootNode = report.asJson();            

                if(rootNode.size() > 0){
                    JsonNode errorNode = rootNode.get(0);
                    JsonNode messageNode = errorNode.get("message");
                    if(messageNode != null){
                        logger.error(messageNode.asText());
                    }
                    JsonNode requiredNode = errorNode.get("required");
                    if(requiredNode != null) {
                        logger.error(requiredNode.toString());
                    }
                    JsonNode missingNode = errorNode.get("missing");
                    if(missingNode != null){
                        logger.error((missingNode.toString());
                    }

                }
            }


And...that's all folks.

Monday, October 27, 2014

Debugging Junit tests (in Eclipse)

Let me start my first blog post with what most of the developers don't do:  Writing unit tests.  Just kidding.

Every developer knows the importance of the unit tests.  Before a functionality is implemented, unit tests must be written and it will help to design the implementation effectively.  This post is not about writing the tests.  It is about how to debug the unit tests.

Often times, you may wonder how to find out what is wrong in my test and why it fails.  Debugging it is one of finding what is going wrong.  This post shows how to debug the junit tests using Maven surefire plugin.


Prerequisites:



  1. Setup a Eclipse project using maven artifact.
  2. Make sure pom.xml has  the following entries:

                      <dependency>
                         <groupId>junit</groupId>
                         <artifactId>junit</artifactId>
                         <version>4.10</version>
                         <scope>test</scope>
                      </dependency>

             and

                     <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>2.5</version>
                        <inherited>true</inherited>
                        <configuration>
                            <forkMode>always</forkMode>
                            <trimStackTrace>false</trimStackTrace>
                            <argLine>-Xmx1024m</argLine>
                        </configuration>
                     </plugin>

Note: The plugin version may vary.
         
      
To debug the unit tests, follow these steps:



  1. The surefire plugin allows to run the tests using -Dmaven.surefire.debug option.  This option will open the port 5005 as a debug port.
  2. Using Maven Debug Configuration... create the configuration as shown here:


  3. Then using a remote java application option, create a dummy configuration in Eclipse "Remote Java Application" section.   The port is usually 5005.  The server name is 'localhost'.


  4. Then run the configuration created in step 2).  Make sure you set breakpoints in the test code.  The test get deployed and halt with the message "Listening for transport dt_socket at address: 5005".
  5. Run the configuration created in 2) as "Debug as...", then choose the entry under "Remote Java Application".
  6. The execution will stop at the breakpoint.  Now you can debug the unit tests as you do with the regular java code.

Gotchas:

  • If you kill the remote java application, it will not terminate the maven surefire plugin.  It is a separate process so it will just run the current test case and when it is about to run the second test case, it will halt with the message "Listening for transport dt_socket at address: 5005".
  • If you terminate the remote java application configuration forcibly (by pressing the "Stop" icon in Eclipse), the java process will not be terminated.  Next time if you try to run the maven configuration, it will complain "Address already in use".  You need to terminate the java process manually.