Showing posts with label Spring framework. Show all posts
Showing posts with label Spring framework. Show all posts

Wednesday, January 30, 2013

Developing Webservices using Apache's CXF


In this article I would like to talk about developing web services using CXF and Spring framework. I did this presentation earlier this year for CJUG (Chicgao Java Users Group) on Developing web services using Apache's CXF.

First Thing First

I would plan on discussing few advance topics sometime in the future to cover topics like - CXF Invokers, Interceptors, method level Validation using JSR 303 and using Hibernate validators etc.

Find links to my presentation and sample code used for the presentation below.
You can checkout the code from google code i.e git repository. These are maven projects and shouldn't be big deal in setting up with in your eclipse and running it.
There are 2 projects loanProcessingService and creditHistoryService available to download.
Once you download the source code, you could import the projects as maven projects in to the eclipse.
You could run maven clean install in the eclipse or through command prompt, it doesn't matter.
Find xyz.abc.xyz.local package in either of these projects, you could see client and server classes these would help you test services outside of container.
Simply run the server as java application, once server is ready run the client.

Now you can fire up your tomcat and publish these web applications.
The soap UI project xml file can be found at src/test/resources/soapui/xyz.xml.
Bring up the soap UI, import the project by pointing to the above xml, simply open up the request for the method and execute it.

That's all for now, have fun with code.

References
Here is my CJUG Presentation.
Checkout the source code from here.

Friday, July 27, 2012

Springify The Strategy Pattern


            The strategy pattern, sure we have heard enough and used enough many times before. But if you are wondering how effectively one could use this pattern in a spring powered application then here are few approaches. I wouldn’t waste time talking about strategy pattern. So let’s get started with some code, consider a typical eCommerce company offering various levels of savings on shipping cost based on the type of memberships. So let’s keep this logic simple here to try out various approaches.

First thing First
  Here are few basic components of strategy pattern first. Start with an interface ShippingCostStrategy.java as shown below,
public interface IShippingCostStrategy {
    public double calculate(Item item);
}

Now write few possible strategy implementations like below,

public class PrimeShippingCostStrategyImpl implements IShippingCostStrategy {
     public double calculate(Item item) {
        double cost = 0.0;
        //Calculate the shipping for prime members 
        return cost;
     }
} 
public class PremiumShippingCostStrategyImpl implements IShippingCostStrategy {
     public double calculate(Item item) {
        double cost = 0.0;
        //Calculate the shipping for premium members 
        return cost;
     }
}
public class RegularShippingCostStrategyImpl implements IShippingCostStrategy {
     public double calculate(Item item) {
        double cost = 0.0;
        //Calculate the shipping for regular members 
        return cost;
     }
}
public class Item {
   private int itemId;
   private String code;
   private double price;

   public Item() {
      super();
   }
 
   public Item(int itemId, String code, double price) {
      super();
      this.itemId = itemId;
      this.code = code;
      this.price = price;
   }

   //All the getter and setter methods are omitted for brevity
}

Define these beans in the shippingCost-context.xml like below and these are required no matter what the approach is,

<bean id="primeShippingStrategy" class=" xxx.xxx.PrimeShippingCostStrategyImpl" />
<bean id="premiumShippingStrategy" class=" xxx.xxx.PremiumShippingCostStrategyImpl" />
<bean id="regularShippingStrategy" class=" xxx.xxx.RegularShippingCostStrategyImpl" />


Approach #1
             In this approach we will keep our context for the strategy simple meaning we will let the client (service) to take the responsibility of determining the possible right strategy implementation class and setting in to the context.
The calculateShipping method in the context will then call the calculate method on the strategy that is being set.
The ShippingContext.java we got here is as shown below,

public class ShippingCostContext {
   IShippingCostStrategy shippingCostStrategy = null;
 
   public double calculateShipping(Item item){
      return shippingCostStrategy.calculate(item);
   }
 
   public void setShippingCostStrategy(IShippingCostStrategy shippingCostStrategy) {
      this.shippingCostStrategy = shippingCostStrategy;
   }
  
}

Let’s look at the ShippingCostService that is being the client for this strategy.
Here we are injecting all the strategy classes and context into this client.

public class ShippingCostService {

   private PrimeShippingCostStrategyImpl primeShippingStrategy = null;
   private PremiumShippingCostStrategyImpl premiumShippingStrategy = null;
   private RegularShippingCostStrategyImpl regularShippingStrategy = null;
   private ShippingCostContext shippingContext = null;
 
   public double calculateShipping(Item item, String memberStatus){
      double cost = 0.0;
      if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PRIME))
         shippingContext.setShippingCostStrategy(primeShippingStrategy);
      else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PREMIUM))
         shippingContext.setShippingCostStrategy(premiumShippingStrategy);
      else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_REGULAR))
         shippingContext.setShippingCostStrategy(regularShippingStrategy);
   
      cost = shippingContext.calculateShipping(item);
    return cost;
 }

 //All the setter and getter for the above attributes goes here

}//End of ShippingCostService

Now the spring configuration would be straight forward,


<bean id="shippingContext" class=" xxx.xxx.SpringShippingCostContext" />
<bean id="shippingCostService" class=" xxx.xxx.ShippingCostService" >
   <property name="primeShippingStrategy" ref="primeShippingStrategy"/>
   <property name="premiumShippingStrategy" ref="premiumShippingStrategy"/>
   <property name="regularShippingStrategy" ref="regularShippingStrategy"/>
   <property name="shippingContext" ref="shippingContext"/>
</bean>

         
Simple class to test this out,
public static void main(String args[]) {
   ApplicationContext context = new ClassPathXmlApplicationContext("shippingCost-Context.xml"); 
   ShippingCostService shippingCostService = ShippingCostService)context.getBean("shippingCostService");
  
   String memberStatus = StrategyConstants.MEMBER_PREMIUM; //REGULAR, PREMIUM, PRIME
  
   Item item = new Item(1, "PREMIUM", 20.00);
   double cost = shippingCostService.calculateShipping(item,memberStatus);
   System.out.println("Shipping cost: for Member type: "+ memberStatus+ ", cost: "+cost);
}

Approach #2
             In this approach we are transferring the responsibility of determining the right strategy from client to the context.
So we will have to inject all the strategy implementation classes into the context as shown below,

public class ShippingCostContext {
  
  private PrimeShippingCostStrategyImpl primeShippingStrategy = null;
  private PremiumShippingCostStrategyImpl premiumShippingStrategy = null;
  private RegularShippingCostStrategyImpl regularShippingStrategy = null;
 
 
  public double calculateShipping(Item item, String memberStatus){
     double cost = 0.0;
     if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PRIME))
         cost = primeShippingStrategy.calculate(item);
     else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PREMIUM))
         cost = premiumShippingStrategy.calculate(item);
     else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_REGULAR))
         cost = regularShippingStrategy.calculate(item);
     return cost;
  }
 
  // All the setter and getter for the above attributes goes here
}


As we see the calculateShipping method in context will determine the call to the right strategy class based on the new parameter memberStatus. There by we freed the ShippingCostService from making the decision of injecting the right strategy implementation class into the context.

public class ShippingCostService {
 
     private ShippingCostContext shippingContext = null;
 
     public double calculateShipping(Item item, String memberStatus){
         double cost = 0.0;
         cost = shippingContext.calculateShipping(item, memberStatus);
         return cost;
     }
 
     // All the setter and getter for the above attributes goes here

}

The spring configuration for this approach would be,


<bean id="shippingContext" class=" xxx.xxx.SpringShippingCostContext" >
     <property name="primeShippingStrategy" ref="primeShippingStrategy"/>
     <property name="premiumShippingStrategy" ref="premiumShippingStrategy"/>
     <property name="regularShippingStrategy" ref="regularShippingStrategy"/>
</bean>


<bean id="shippingCostService" class=" xxx.xxx.ShippingCostService" >
     <property name="shippingContext" ref="shippingContext"/>
</bean>


We could test this approach out using the same test class code as given above in approach 1.

Approach #3
            The third approach improvises the approach 2 by introducing a map of available strategies.
So introducing any new strategy would just be a matter of configuring rather than coding in context.

Look at this code for context under this approach,

public class ShippingCostContext {
     private Map shippingStrategies = new HashMap(); 
  
     public double calculateShipping(Item item, String memberstatus){
         double cost = 0.0;
         if(shippingStrategies.containsKey(memberstatus)){
            IShippingCostStrategy shippingCostStrategy = (IShippingCostStrategy)shippingStrategies.get(memberstatus);
         if(shippingCostStrategy != null)
             cost = shippingCostStrategy.calculate(item);
  }
  
     return cost;
 }
 
     public void setShippingStrategies(Map shippingStrategies) {
         this.shippingStrategies = shippingStrategies;
 }
}

Context now holds the map of all configured strategy beans in it. This wouldn’t affect the way client invokes the strategy at all.
All it needs to do is pass an additional parameter memberStatus to the context to help determine the right strategy.

public class ShippingCostService {
     private ShippingCostContext shippingContext = null;
 
     public double calculateShipping(Item item, String memberStatus){
         double cost = 0.0;
         cost = shippingContext.calculateShipping(item, memberStatus);
         return cost;
     }
}

The configuration for this approach is simple enough as we are going to use the util schema to achieve this.
We created the property shippingStrategies of type Map with key using static fields and value would be respective bean.


<bean id="shippingContext" class="xxx.xxx.ShippingCostContext" >
   <property name="shippingStrategies">
     <map>
       <entry>
         <key>
           <util:constant static-field="xxx.xxx.StrategyConstants.MEMBER_REGULAR"/>
         </key>
           <ref bean="regularShippingStrategy" />
        </entry>
        <entry>
            <key>
             <util:constant static-field=" xxx.xxx.StrategyConstants.MEMBER_PREMIUM"/>
            </key>
            <ref bean="premiumShippingStrategy" />
        </entry>
        <entry>
            <key>
             <util:constant static-field=" xxx.xxx.StrategyConstants.MEMBER_PRIME"/>
            </key>
            <ref bean="primeShippingStrategy" />
        </entry>
    </map>
  </property>
</bean>


<bean id="shippingCostService" class=" xxx.xxx.ShippingCostService" >
      <property name="shippingContext" ref="shippingContext"/>
</bean>


Make sure to add the util namespace and shema location information to the header beans of the context xml like as shown,


xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"


That’s it you are ready to test your strategy using the same test class above.

Final Note
    The advantage of approach 1 is, the client will be in control if the business logic in client (service) that determines the strategy to use is inseparable or tightly coupled. The same advantage could turn into a disaster with tight coupling. So approach 2 would bring in the much needed loose coupling and let strategy context take care of determining the right strategy. This brings in an opportunity to add more business intelligence into the context. The last approach as you saw definitely improvises the overall strategy to implement the strategy pattern in spring. Sure there must be even better approaches out there and if you do have one please share.

Reference
  1. Reference to the strategy pattern.
  2. Reference to the Spring Util schema documentation.


Friday, February 10, 2012

Springify the LDAP application

       Spring LDAP makes LDAP operations so simple. Spring lets you write the code and structure the functionalities around LDAP just like any other data access functionality. It provides fine wrapped template to work with LDAP just like JDBC or JMS. Let me share some of the basic operations using spring’s LdapTemplate that are most common in any application. Spring source has put together a very nice and detailed documentation, so please refer http://static.springsource.org/spring-ldap/docs/1.3.x/reference/html/ for Spring LDAP and refer to open source LDAP http://www.openldap.org/ for more details.

First thing First
       Let’s categorize these basic LDAP operations into the following
         • Creating an entry or Binding.
         • Deleting an entry or unbinding.
         • Retrieving basic attributes.
         • Retrieving attributes using filter.
         • Retrieving operational attributes.

Create an Entry
        To add an entry into the LDAP all you have to do is to call bind method on ldapTemplate. There are two ways of binding the new entry.
First way is calling the bind(Name dn, Object obj, Attributes attributes). So create the Attributes with attributes to bind. Here you are creating a new person object with attributes to bind.


BasicAttribute personBasicAttribute = new BasicAttribute("objectclass");
personBasicAttribute.add("person");
personAttributes.put(personBasicAttribute);
personAttributes.put("cn", “Vinay Shivaswamy”);
personAttributes.put("description", “some description here”);

Create the DistinguishedName by providing the path in string format.


DistinguishedName newContactDN = new DistinguishedName("ou=users");
newContactDN.add("cn", “Vinay Shivaswamy”);

Now call the bind method by passing the Attributes and DistinguishedName just created.

ldapTemplate.bind(newContactDN, null, personAttributes);

Second way is to call bind(DirContextOperations ctx). So create the DistinguishedName by providing the path in string format.


DistinguishedName newContactDN = new DistinguishedName("ou=users");

Create the DirContextOperations object by passing the DistinguishedName just created. Once context is created its just matter of setting attributes into this context as shown below.

DirContextOperations ctx = new DirContextAdapter(dn);
ctx.setAttributeValue("cn", "Vinay Shivaswamy");
ctx.setAttributeValue("description", "some description");

Now Call the bind method by passing the DirContextOperations just created.
ldapTemplate.bind(ctx);

Delete an entry
       Deleting an entry is lot easier than creating one. All you have to do is to call unbind method as shown below by passing DistinguishedName,

DistinguishedName newContactDN = new DistinguishedName("ou=users");
newContactDN.add("cn",”Vinay Shivaswamy”);
ldapTemplate.unbind(newContactDN);

Retrieving basic attributes
       The basic attributes can be retrieved using lookup or search methods of LdapTemplate. Below is an example of using search to get the list of matching common name attributes only. Search would return a List and if you are interested in retrieving unique matching entry then use searchForObject method instead.

ldapTemplate.search(baseName, "(objectclass=person)", new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs) throws NamingException {
return attrs.get("cn").get();
}
});

If you simply want to retrieve all the available attributes then write your own AttributesMapper implementation, add all the attributes to return.

Retrieving attributes using filter
       Retrieving attributes based of search criteria would be helpful and you can do that with the help of Filter. Spring Ldap filter package provides various supporting filters. Look at the example below to see how easy it is to build and use the filter.


AndFilter andFilter = new AndFilter();
andFilter.and(new EqualsFilter("objectclass","person"));
andFilter.and(new EqualsFilter("cn",”Vinay Shivaswamy”));
andFilter.and(new EqualsFilter("sn",”Shivaswamy”));

Once the filter is built then it is just the matter of calling search by passing the filter to retrieve the matching email attribute,


ldapTemplate.search("baseName", andFilter.encode(),new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
return attrs.get("email").get();
}
});

Retrieving operational attributes
       Ldap Server maintains many operational attributes internally. Example entryUUID is an operational attribute assigns the Universally Unique Identifier (UUID) to the entry. The createTimestamp, modifyTimestamp are also operational attributes assigned to the entry on create or update. These operational attributes does not belong to an object class and hence they were not returned as part of your search or lookup. You need to explicitly request them by their name in your search or build the custom AttributeMapper implementation with matching attribute names.
Now let’s try to retrieve the entryUUID, first you need to build the search controls like this,


SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningObjFlag(false);
controls.setReturningAttributes(new String[]{"entryUUID"});

Once you have search control then it’s simply calling search method just like retrieving any other attributes.


ldapTemplate.search("baseName", "(objectclass=person)", controls, new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs) throws NamingException {
Attribute attrUuid = attrs.get("entryUUID");
return attrUuid;
}});

Here is another way to do the same using ContextMapper,


ldapTemplate.search("baseName","(objectclass=person)", 1, new String[]{"entryUUID"},
new ContextMapper(){
public Object mapFromContext(Object ctx) {
DirContextAdapter context = (DirContextAdapter)ctx;
return context.getStringAttributes("entryUUID");
}
});

Let’s add the filter based off of operational attributes like below,


OrFilter orFilter = new OrFilter();
orFilter.or(new GreaterThanOrEqualsFilter("createTimestamp", "YYYYMMDDHHMMSSZ"));
orFilter.or(new LessThanOrEqualsFilter("modifyTimestamp", "YYYYMMDDHHMMSSZ"));

Now call the above search with the filter


ldapTemplate.search("baseName", orFilter.encode(), controls, new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs) throws NamingException {
Attribute attrUuid = attrs.get("entryUUID");
return attrUuid;
}});

Final Note
       Spring simplifies the Ldap operations indeed. We just saw that but there is lot more to dig into if you need to and I hope this article serves as a quick reference to jump start your exploration. Good luck.