View Javadoc

1   package net.sf.crispy.impl.rmi;
2   
3   import java.net.BindException;
4   import java.rmi.Remote;
5   import java.rmi.RemoteException;
6   import java.rmi.registry.LocateRegistry;
7   import java.rmi.registry.Registry;
8   import java.rmi.server.ExportException;
9   import java.util.Hashtable;
10  import java.util.Iterator;
11  import java.util.Map;
12  
13  import net.sf.crispy.InvocationException;
14  import net.sf.crispy.impl.MiniServer;
15  import net.sf.crispy.impl.RmiExecutor;
16  import net.sf.crispy.impl.ServiceManager;
17  import net.sf.crispy.server.InterceptorHandlerCreator;
18  import net.sf.crispy.server.ServiceEndpoint;
19  import net.sf.crispy.server.SingleServiceContainer;
20  import net.sf.crispy.util.Util;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  /**
26   * MiniRmiServer has the function to simulate a RMI Server. This is useful for test the RMI Client.
27   * Do not use this Server in production.
28   * 
29   * @author Linke
30   *
31   */
32  public class MiniRmiServer implements MiniServer {
33   
34  	public static final int PORT = 1098;
35      protected static final Log log = LogFactory.getLog (MiniRmiServer.class);
36      
37      private static MiniRmiServer lastStartedRmiServer = null;
38      
39  	private String urlAndPort = null;
40  	private int port = PORT;
41  	private Map lookUpMap = new Hashtable();
42  	private RmiInvocationHandler rmiInvocationHandler = null;
43  	
44  	
45  	public MiniRmiServer() { this (PORT); }
46  	public MiniRmiServer(int pvPort, RmiInvocationHandler pvRmiInvocationHandler) {
47  		this (pvPort);
48  		setRmiInvocationHandler(pvRmiInvocationHandler);
49  	}
50  	public MiniRmiServer(int pvPort) {
51  		setPort(pvPort);
52  	}
53  	
54  	public final int getPort() { return port; }
55  	private void setPort(int pvPort) {
56  		if (isStarted() == false) {
57  			port = pvPort; 
58  		} else {
59  			log.warn("A RMI-Server is already started on port: " + getPort());
60  		}
61  	}
62  	
63  	public static boolean isStarted() { return (lastStartedRmiServer != null); }
64  	private static void setStartedTrue(MiniRmiServer pvMiniRmiServer) { 
65  		lastStartedRmiServer = pvMiniRmiServer;
66  	}
67  	private static void setStartedFalse() { 
68  		lastStartedRmiServer = null;
69  	}
70  
71  	public static MiniRmiServer getLastStartedRmiServer() {
72  		return lastStartedRmiServer;
73  	}
74  	
75  	public void setUrlAndPort(String pvUrlAndPort) { urlAndPort = pvUrlAndPort; }
76  	public String getUrlAndPort() { return (urlAndPort == null ? RmiExecutor.DEFAULT_URL_AND_PORT : urlAndPort); }
77  	
78  	private void setRmiInvocationHandler(RmiInvocationHandler pvRmiInvocationHandler) { 
79  		rmiInvocationHandler = pvRmiInvocationHandler; 
80  	}
81  	public RmiInvocationHandler getRmiInvocationHandler() {
82  		if (rmiInvocationHandler == null) {
83  			rmiInvocationHandler = getDefaultRmiInvocationHandler();
84  		}
85  		return rmiInvocationHandler; 
86  	}
87  	
88  	public RmiInvocationHandler getDefaultRmiInvocationHandler() {
89  		try {
90  			return new RmiInvocationHandlerImpl();
91  		} catch (RemoteException e) {
92  			if (ServiceManager.DEBUG_MODE_ON) {
93  				e.printStackTrace();
94  			}
95  		} 			
96  		return null;
97  	}
98  	
99      public void setInterceptorHandlerCreator(InterceptorHandlerCreator pvCreator) {
100     	if (getRmiInvocationHandler() instanceof ServiceEndpoint) {
101     		((ServiceEndpoint) getRmiInvocationHandler()).setInterceptorHandlerCreator(pvCreator);
102     	} else {
103     		log.warn("The RmiInvocationHandler is not a instance of ServiceEndpoint. Can't set the InterceptorHandlerCreator: " + pvCreator);
104     	}
105 	}
106     public InterceptorHandlerCreator getInterceptorHandlerCreator() {
107     	if (getRmiInvocationHandler() instanceof ServiceEndpoint) {
108     		return ((ServiceEndpoint) getRmiInvocationHandler()).getInterceptorHandlerCreator();
109     	} else {
110     		log.warn("The RmiInvocationHandler is not a instance of ServiceEndpoint.");
111     		return null;	
112     	}
113 	}
114 
115 	
116 	public void addService (String pvServiceInterface, String pvServiceObject) {
117 		try {
118 			Object lvServiceObject = Util.createObject(pvServiceObject);
119 			if (lvServiceObject instanceof Remote) {
120 				addService(pvServiceInterface, (Remote) lvServiceObject);
121 			} else {
122 				addService(pvServiceInterface, lvServiceObject);
123 			}
124 		} catch (Exception e) {
125 			if (ServiceManager.DEBUG_MODE_ON) {
126 				e.printStackTrace();
127 			}
128 		}
129 	}
130 
131 	public void addService (String pvLookName, Object pvServiceObject) {
132 		RmiInvocationHandler lvHandler = getRmiInvocationHandler();
133 		if (lvHandler instanceof SingleServiceContainer) {
134 			((SingleServiceContainer) lvHandler).addService(pvLookName, pvServiceObject);
135 		} else {
136 			throw new InvocationException("Can't add service: " + pvLookName + 
137 					". The RmiInvocationHandler isen't a implementation from the SingleServiceContainer instance.");
138 		}
139 	}
140 
141 	public void addService (String pvLookName, Remote pvServiceObject) {
142 		lookUpMap.put(pvLookName, pvServiceObject);
143 	}
144 	
145 	public void removeService (String pvLookName) {
146 		lookUpMap.remove(pvLookName);
147 		Registry registry = getRegistry(getPort());
148 		try {
149 			registry.unbind(pvLookName);
150 		} catch (Exception e) {
151 			if (log.isDebugEnabled()) {
152 				log.debug("Can't remove service: " + pvLookName + " from MiniRmiServer: " + e, e);
153 			}			
154 		}
155 	}
156 		
157 	public static Registry getRegistry(int pvPort) {
158 		Registry registry = null;
159 		try {
160 			registry = LocateRegistry.getRegistry(pvPort);
161 			registry.list();
162 			return registry;
163 		} catch (Exception t) {
164 			try {
165 				return LocateRegistry.createRegistry(pvPort);
166 			} catch (ExportException e) {
167 				if(e.getCause() != null && e.getCause() instanceof BindException) {
168 					log.error("With the port: " + pvPort + " is a RMI-server already started (other JVM).");
169 				}
170 				if (ServiceManager.DEBUG_MODE_ON) {
171 					e.printStackTrace();
172 				}
173 			} catch (RemoteException e) {
174 				e.printStackTrace();
175 			}
176 		}
177 		return registry;
178 	}
179 	
180 	public void start() {
181 //		if (System.getSecurityManager() == null) {
182 //			log.info("Set RmiSecurityManager");
183 //			System.setSecurityManager(new RMISecurityManager());
184 //		}
185 
186 		if (isStarted() == false) {
187 			try {
188 				Registry registry = getRegistry(getPort()); 
189 
190 				// registered ServiceObjects
191 				// lvHandlerImpl.registerServiceObject(...);
192 				registry.rebind(RmiExecutor.LOOKUP_NAME, getRmiInvocationHandler());
193 
194 				Iterator it = lookUpMap.keySet().iterator();
195 				while (it.hasNext()) {
196 					String lvKey = (String) it.next();
197 					Object lvValue = lookUpMap.get(lvKey);
198 					registry.rebind(lvKey, (Remote) lvValue);
199 				}
200 
201 				setStartedTrue(this);
202 				if (log.isDebugEnabled()) {
203 					log.debug("MiniRmiServer is waiting for requests ...");
204 				}
205 			} catch (Exception e) {
206 				e.printStackTrace();
207 			}
208 		} else {
209 			if (log.isWarnEnabled()) {
210 				log.warn("A RMI-server is already started on port: " + lastStartedRmiServer.getPort() + ". Only one RMI-server-instance per JVM is supported.");
211 			}
212 		}
213 
214 		
215 	}
216 	
217 
218 	public void stop() { 
219 		try {
220 			
221 			Registry registry = getRegistry(getPort());
222 			
223 			Iterator it = lookUpMap.keySet().iterator();
224 			String lvKey = null;
225 			Object lvValue = null;
226 			while (it.hasNext()) {
227 				try {
228 					lvKey = (String) it.next();
229 					lvValue = lookUpMap.get(lvKey);
230 					registry.unbind(lvKey);
231 //					UnicastRemoteObject.unexportObject((Remote) lvValue, true);
232 				} catch (Exception e) {
233 					log.debug("Problem by unbind service: " + lvKey + " --> " + lvValue);
234 				}
235 			}
236 			if (registry != null) {
237 				registry.unbind(RmiExecutor.LOOKUP_NAME);
238 			}
239 			
240 			registry = null;			
241 		} catch (Exception e) {
242 			if (ServiceManager.DEBUG_MODE_ON) {
243 				e.printStackTrace();
244 			}
245 		}
246 		finally {
247 			setStartedFalse();
248 		}
249 		
250 	}
251 
252 	public static void main(String[] args) {
253 		Util.initJdkLogger();  
254 		MiniServer lvMiniServer = new MiniRmiServer();
255 
256 		lvMiniServer.addService("test.crispy.example.service.Echo", "test.crispy.example.service.EchoImpl");
257 		lvMiniServer.addService("test.crispy.example.service.Calculator", "test.crispy.example.service.CalculatorImpl");
258 
259 		lvMiniServer.start();
260 	}
261 }