001 package com.khubla.pragmatach.plugin.cluster;
002
003 import java.util.HashMap;
004 import java.util.Map;
005 import java.util.Set;
006
007 import javassist.util.proxy.ProxyFactory;
008 import javassist.util.proxy.ProxyObject;
009
010 import org.slf4j.Logger;
011 import org.slf4j.LoggerFactory;
012
013 import com.khubla.pragmatach.framework.annotation.Controller;
014 import com.khubla.pragmatach.framework.api.PragmatachException;
015 import com.khubla.pragmatach.framework.controller.PragmatachController;
016 import com.khubla.pragmatach.framework.scanner.AnnotationScanner;
017 import com.khubla.pragmatach.plugin.cluster.annotation.Clustered;
018 import com.khubla.pragmatach.plugin.cluster.multicast.JGroupsSenderReceiver;
019
020 /**
021 * A collection of the clustered controller instances
022 *
023 * @author tome
024 */
025 public class ClusteredControllers {
026 /**
027 * logger
028 */
029 private final Logger logger = LoggerFactory.getLogger(this.getClass());
030 /**
031 * instance
032 */
033 private static ClusteredControllers instance;
034
035 /**
036 * singleton
037 */
038 public static ClusteredControllers getInstance() throws PragmatachException {
039 if (null == instance) {
040 instance = new ClusteredControllers();
041 }
042 return instance;
043 }
044
045 /**
046 * cluster object
047 */
048 private final JGroupsSenderReceiver jGroupsSenderReceiver;
049 /**
050 * controllers
051 */
052 private final Map<String, PragmatachController> controllerInstances = new HashMap<String, PragmatachController>();
053 /**
054 * clustered beans
055 */
056 private final Set<Class<?>> clusteredControllerClasses;
057
058 /**
059 * ctor
060 */
061 private ClusteredControllers() throws PragmatachException {
062 /*
063 * create the controllerCluster
064 */
065 jGroupsSenderReceiver = new JGroupsSenderReceiver();
066 try {
067 jGroupsSenderReceiver.startup();
068 } catch (final Exception e) {
069 logger.error("Exception starting ClusteredControllers", e);
070 }
071 clusteredControllerClasses = findClusteredControllerClasses();
072 instantiateControllers();
073 }
074
075 /**
076 * find all the beans annotated with @Clustered
077 */
078 private Set<Class<?>> findClusteredControllerClasses() throws PragmatachException {
079 try {
080 return AnnotationScanner.getAllClasses(Clustered.class);
081 } catch (final Exception e) {
082 throw new PragmatachException("Exception in findClusteredControllerClasses", e);
083 }
084 }
085
086 public Set<Class<?>> getClusteredControllerClasses() {
087 return clusteredControllerClasses;
088 }
089
090 private String getClusteredControllerName(Class<?> clazz) throws PragmatachException {
091 try {
092 final Controller controller = clazz.getAnnotation(Controller.class);
093 if (null != controller) {
094 return controller.name();
095 } else {
096 throw new Exception("ClusteredController '" + clazz.getName() + "' does not have a @Controller annotation");
097 }
098 } catch (final Exception e) {
099 throw new PragmatachException("Exception in getClusteredControllerName", e);
100 }
101 }
102
103 public Map<String, PragmatachController> getControllerInstances() {
104 return controllerInstances;
105 }
106
107 /**
108 * create the instances and return proxies to them
109 */
110 private void instantiateControllers() throws PragmatachException {
111 try {
112 for (final Class<?> controllerClazz : clusteredControllerClasses) {
113 final ProxyFactory proxyFactory = new ProxyFactory();
114 proxyFactory.setSuperclass(controllerClazz);
115 final Class<?> c = proxyFactory.createClass();
116 final PragmatachController pragmatachController = (PragmatachController) c.newInstance();
117 ((ProxyObject) pragmatachController).setHandler(new ControllerMethodHandler());
118 final String name = getClusteredControllerName(controllerClazz);
119 controllerInstances.put(name, pragmatachController);
120 }
121 } catch (final Exception e) {
122 throw new PragmatachException("Exception in instantiateControllers", e);
123 }
124 }
125 }