From 1cb62f543b7b8d8c9205fc2b88980dac4b3ff311 Mon Sep 17 00:00:00 2001 From: MSaifAsif Date: Sat, 6 Dec 2014 02:39:54 +0500 Subject: [PATCH] Implementatation of the Service locator pattern --- pom.xml | 1 + service-locator/etc/model.ucls | 74 ++++++++++++++++++ service-locator/etc/service-locator.png | Bin 0 -> 38210 bytes service-locator/pom.xml | 9 +++ .../src/main/java/com/iluwater/App.java | 20 +++++ .../main/java/com/iluwater/InitContext.java | 29 +++++++ .../src/main/java/com/iluwater/Service.java | 29 +++++++ .../main/java/com/iluwater/ServiceCache.java | 46 +++++++++++ .../main/java/com/iluwater/ServiceImpl.java | 37 +++++++++ .../java/com/iluwater/ServiceLocator.java | 37 +++++++++ 10 files changed, 282 insertions(+) create mode 100644 service-locator/etc/model.ucls create mode 100644 service-locator/etc/service-locator.png create mode 100644 service-locator/pom.xml create mode 100644 service-locator/src/main/java/com/iluwater/App.java create mode 100644 service-locator/src/main/java/com/iluwater/InitContext.java create mode 100644 service-locator/src/main/java/com/iluwater/Service.java create mode 100644 service-locator/src/main/java/com/iluwater/ServiceCache.java create mode 100644 service-locator/src/main/java/com/iluwater/ServiceImpl.java create mode 100644 service-locator/src/main/java/com/iluwater/ServiceLocator.java diff --git a/pom.xml b/pom.xml index 1e6b6e98c..1a0a0c9b7 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ visitor double-checked-locking servant + service-locator diff --git a/service-locator/etc/model.ucls b/service-locator/etc/model.ucls new file mode 100644 index 000000000..bf17e5eba --- /dev/null +++ b/service-locator/etc/model.ucls @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/service-locator/etc/service-locator.png b/service-locator/etc/service-locator.png new file mode 100644 index 0000000000000000000000000000000000000000..72016b972c12b3b0ba64bd363b6b258b003df94e GIT binary patch literal 38210 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 literal 0 HcmV?d00001 diff --git a/service-locator/pom.xml b/service-locator/pom.xml new file mode 100644 index 000000000..a7cb56f8e --- /dev/null +++ b/service-locator/pom.xml @@ -0,0 +1,9 @@ + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.0-SNAPSHOT + + service-locator + \ No newline at end of file diff --git a/service-locator/src/main/java/com/iluwater/App.java b/service-locator/src/main/java/com/iluwater/App.java new file mode 100644 index 000000000..9905b68df --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/App.java @@ -0,0 +1,20 @@ +package com.iluwater; +/** + * Service locator pattern, used to lookup jndi services + * and cache them for subsequent requests. + * @author saifasif + * + */ +public class App { + public static void main(String[] args) { + Service service = ServiceLocator.getService("jndi/serviceA"); + service.execute(); + service = ServiceLocator.getService("jndi/serviceB"); + service.execute(); + service = ServiceLocator.getService("jndi/serviceA"); + service.execute(); + service = ServiceLocator.getService("jndi/serviceA"); + service.execute(); + } + +} diff --git a/service-locator/src/main/java/com/iluwater/InitContext.java b/service-locator/src/main/java/com/iluwater/InitContext.java new file mode 100644 index 000000000..8c6e0f8d1 --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/InitContext.java @@ -0,0 +1,29 @@ +package com.iluwater; + +/** + * For JNDI lookup of services from the web.xml. Will match name of the service name that + * is being requested and return a newly created service object with the name + * @author saifasif + * + */ +public class InitContext { + + /** + * Perform the lookup based on the service name. The returned object will need to be + * casted into a {@link Service} + * @param serviceName + * @return + */ + public Object lookup(String serviceName){ + if( serviceName.equals("jndi/serviceA") ){ + System.out.println("Looking up service A and creating new serivce for A"); + return new ServiceImpl("jndi/serviceA"); + } else if( serviceName.equals("jndi/serviceB") ){ + System.out.println("Looking up service B and creating new serivce for B"); + return new ServiceImpl("jndi/serviceB"); + } else { + return null; + } + } + +} diff --git a/service-locator/src/main/java/com/iluwater/Service.java b/service-locator/src/main/java/com/iluwater/Service.java new file mode 100644 index 000000000..cda1a9d7e --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/Service.java @@ -0,0 +1,29 @@ +package com.iluwater; + +/** + * This is going to be the parent service interface which we will + * use to create our services. All services will have a + *
  • service name
  • + *
  • unique id
  • + *
  • execution work flow
  • + * @author saifasif + * + */ +public interface Service { + + /* + * The human readable name of the service + */ + public String getName(); + + /* + * Unique ID of the particular service + */ + public int getId(); + + /* + * The workflow method that defines what this service does + */ + public void execute(); + +} diff --git a/service-locator/src/main/java/com/iluwater/ServiceCache.java b/service-locator/src/main/java/com/iluwater/ServiceCache.java new file mode 100644 index 000000000..ec727126b --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/ServiceCache.java @@ -0,0 +1,46 @@ +package com.iluwater; + +import java.util.HashMap; +import java.util.Map; + +/** + * The service cache implementation which will cache services that are being created. + * On first hit, the cache will be empty and thus any service that is being requested, will be + * created fresh and then placed into the cache map. On next hit, if same service name will + * be requested, it will be returned from the cache + * @author saifasif + * + */ +public class ServiceCache { + + private Map serviceCache; + + public ServiceCache() { + serviceCache = new HashMap(); + } + + /** + * Get the service from the cache. null if no service is found matching the + * name + * @param serviceName + * @return {@link Service} + */ + public Service getService(String serviceName){ + Service cachedService = null; + for (String serviceJndiName : serviceCache.keySet()){ + if( serviceJndiName.equals( serviceName ) ){ + cachedService = serviceCache.get(serviceJndiName); + System.out.println("(cache call) Fetched service " + cachedService.getName() + "("+cachedService.getId()+") from cache... !"); + } + } + return cachedService; + } + + /** + * Adds the service into the cache map + * @param newService + */ + public void addService(Service newService){ + serviceCache.put(newService.getName(), newService); + } +} diff --git a/service-locator/src/main/java/com/iluwater/ServiceImpl.java b/service-locator/src/main/java/com/iluwater/ServiceImpl.java new file mode 100644 index 000000000..335ebef78 --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/ServiceImpl.java @@ -0,0 +1,37 @@ +package com.iluwater; + +/** + * This is a single service implementation of a sample service. This is the actual + * service that will process the request. The reference for this service is to + * be looked upon in the JNDI server that can be set in the web.xml deployment descriptor + * @author saifasif + * + */ +public class ServiceImpl implements Service { + + private String serviceName; + private int id; + + public ServiceImpl(String serviceName) { + // set the service name + this.serviceName = serviceName; + + // Generate a random id to this service object + this.id = (int)Math.floor(Math.random()*1000)+1; + } + + @Override + public String getName() { + return serviceName; + } + + @Override + public int getId() { + return id; + } + + @Override + public void execute() { + System.out.println("Service " + getName() + " is now executing with id " + getId()); + } +} diff --git a/service-locator/src/main/java/com/iluwater/ServiceLocator.java b/service-locator/src/main/java/com/iluwater/ServiceLocator.java new file mode 100644 index 000000000..e2fbae2b8 --- /dev/null +++ b/service-locator/src/main/java/com/iluwater/ServiceLocator.java @@ -0,0 +1,37 @@ +package com.iluwater; + +/** + * The service locator module. + * Will fetch service from cache, otherwise creats a fresh service and update cache + * + * @author saifasif + * + */ +public class ServiceLocator { + + private static ServiceCache serviceCache = new ServiceCache(); + + /** + * Fetch the service with the name param from the cache first, + * if no service is found, lookup the service from the {@link InitContext} and + * then add the newly created service into the cache map for future requests. + * @param serviceJndiName + * @return {@link Service} + */ + public static Service getService(String serviceJndiName){ + Service serviceObj = serviceCache.getService(serviceJndiName); + if ( serviceObj != null ){ + return serviceObj; + } else { + /* + * If we are unable to retrive anything from cache, then + * lookup the service and add it in the cache map + */ + InitContext ctx = new InitContext(); + serviceObj = (Service) ctx.lookup(serviceJndiName); + serviceCache.addService(serviceObj); + return serviceObj; + } + } + +}