KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > agent > DefaultAgentManager


1 package com.sslexplorer.agent;
2
3 import java.io.IOException JavaDoc;
4 import java.net.URL JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.Collection JavaDoc;
7 import java.util.Collections JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.concurrent.ArrayBlockingQueue JavaDoc;
12 import java.util.concurrent.ThreadPoolExecutor JavaDoc;
13 import java.util.concurrent.TimeUnit JavaDoc;
14
15 import javax.servlet.http.HttpServletRequest JavaDoc;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19
20 import com.maverick.multiplex.Request;
21 import com.maverick.util.ByteArrayReader;
22 import com.maverick.util.ByteArrayWriter;
23 import com.sslexplorer.core.CoreException;
24 import com.sslexplorer.policyframework.LaunchSession;
25 import com.sslexplorer.security.LogonControllerFactory;
26 import com.sslexplorer.security.SessionInfo;
27 import com.sslexplorer.util.TicketGenerator;
28
29 /**
30  * Manages <i>Agent</i> instances.
31  *
32  * @author Lee David Painter <a HREF="mailto: lee@3sp.com">&lt;lee@3sp.com&gt;</a>
33  */

34 public class DefaultAgentManager {
35
36     static Log log = LogFactory.getLog(DefaultAgentManager.class);
37
38     HashMap JavaDoc<String JavaDoc, AgentTunnel> agentsByAgentId = new HashMap JavaDoc<String JavaDoc, AgentTunnel>();
39     HashMap JavaDoc<String JavaDoc, AgentTunnel> agentsByLogonTicket = new HashMap JavaDoc<String JavaDoc, AgentTunnel>();
40
41     static DefaultAgentManager instance = null;
42
43     static final String JavaDoc AGENT_ID = "agentId";
44     static final String JavaDoc SESSION_INFO = "sessionInfo";
45     
46     HashMap JavaDoc<Class JavaDoc, AgentService> agentServices = new HashMap JavaDoc<Class JavaDoc, AgentService>();
47     ResourceRequestHandler resourceRequestHandler = new ResourceRequestHandler();
48     ThreadPoolExecutor JavaDoc agentBroadcastExecutor;
49
50     private DefaultAgentManager() {
51         agentBroadcastExecutor = new ThreadPoolExecutor JavaDoc(1, 5, 30, TimeUnit.SECONDS, new ArrayBlockingQueue JavaDoc<Runnable JavaDoc>(1000));
52     }
53     
54     /**
55      * Get an instance of the agent manager.
56      *
57      * @return agent manager
58      */

59     public static DefaultAgentManager getInstance() {
60         return instance == null ? instance = new DefaultAgentManager() : instance;
61     }
62     
63     public List JavaDoc<AgentService> getServices() {
64         return new ArrayList JavaDoc(agentServices.values());
65     }
66     
67     public AgentService getService(Class JavaDoc cls) {
68         return agentServices.get(cls);
69     }
70     
71     /**
72      * Get an thread pool executor to use for broadcasting messages
73      * to all Agents.
74      *
75      * @return execturo
76      */

77     public ThreadPoolExecutor JavaDoc getAgentBroadcastExecutor() {
78         return agentBroadcastExecutor;
79     }
80     
81     /**
82      * Register an AgentService implementation with the agent.
83      * @param cls
84      * @throws InstantiationException
85      * @throws IllegalAccessException
86      */

87     public void registerService(Class JavaDoc cls) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
88         agentServices.put(cls, (AgentService)cls.newInstance());
89     }
90     
91     /**
92      * Unregister an AgentService implementation on the agent.
93      * @param cls
94      */

95     public void unregisterService(Class JavaDoc cls) {
96         agentServices.remove(cls);
97     }
98
99     /**
100      * Register a new agent.
101      *
102      * @param ticket unique ticket
103      * @param session session
104      * @param tunnel agent
105      * @throws AgentException
106      */

107     public void registerAgent(String JavaDoc ticket, SessionInfo session, AgentTunnel tunnel) throws AgentException {
108
109         LogonControllerFactory.getInstance().removeAuthorizationTicket(ticket);
110         
111         if (session != null) {
112             
113             
114             synchronized (session) {
115                 agentsByAgentId.put(ticket, tunnel);
116                 agentsByLogonTicket.put(session.getLogonTicket(), tunnel);
117                 tunnel.setProperty(AGENT_ID, ticket);
118                 tunnel.setProperty(SESSION_INFO, session);
119 // session.notifyAll();
120

121                 tunnel.register();
122                 
123                 tunnel.addListener(new DefaultAgentStartupListener(session));
124                 tunnel.registerRequestHandler("getResources@3sp.com", resourceRequestHandler);
125                 
126                 // Make sure all services are initialized before agent begins
127
if (tunnel != null) {
128                     for(Iterator JavaDoc it = agentServices.values().iterator();it.hasNext();) {
129                         ((AgentService)it.next()).initializeTunnel(tunnel);
130                     }
131                 }
132             }
133         } else {
134             tunnel.close();
135             throw new AgentException("");
136         }
137     }
138
139     
140
141     /**
142      * Inform the agent to open the specified URL with its local default browser
143      *
144      * @param agent agent
145      * @param url URL to open
146      * @param launchSession launch session
147      * @return return code
148      * @throws CoreException on any error
149      */

150     public int openURL(AgentTunnel agent, URL JavaDoc url, LaunchSession launchSession) throws CoreException {
151
152         try {
153             ByteArrayWriter msg = new ByteArrayWriter();
154             msg.writeString(url.toExternalForm());
155             msg.writeString(launchSession.getId());
156             Request JavaDoc request = new Request JavaDoc("openURL@3sp.com", msg.toByteArray());
157             if (agent.sendRequest(request, true)) {
158                 if(request.getRequestData()!=null) {
159                 ByteArrayReader rdr = new ByteArrayReader(request.getRequestData());
160                 return (int) rdr.readInt();
161                 }
162             }
163
164         } catch (Exception JavaDoc e) {
165             throw new CoreException(0, "", e);
166         }
167         return -1;
168     }
169
170     /**
171      * Unregister an agent. If the agent is running it will be shutdown.
172      *
173      * @param tunnel
174      */

175     public void unregisterAgent(AgentTunnel tunnel) {
176
177         if (tunnel != null) {
178             
179             tunnel.unregister();
180             
181             String JavaDoc ticket = (String JavaDoc) tunnel.getProperty(AGENT_ID);
182
183             if (log.isDebugEnabled())
184                 log.debug("Unregistering agent with id " + ticket);
185
186             SessionInfo session = (SessionInfo) tunnel.getProperty(SESSION_INFO);
187
188             
189             agentsByAgentId.remove(ticket);
190             agentsByLogonTicket.remove(session.getLogonTicket());
191
192             if (tunnel.isRunning()) {
193                 try {
194                     tunnel.sendRequest(new Request JavaDoc("shutdown@3sp.com", "".getBytes()), false, 10000);
195                 } catch (IOException JavaDoc e) {
196                     log.error("Failed to send shutdown request to agent. The agent may not be responding or the network link may now be down.",
197                         e);
198                 }
199                 tunnel.close();
200             }
201  
202             if(session.getHttpSession() == null) {
203                 log.info("Non UI session so cleaning up session.");
204                 LogonControllerFactory.getInstance().logoff(session.getLogonTicket());
205             }
206         }
207     }
208
209     /**
210      * Unregister an agent given the session it attached to. If the agent is
211      * running it will be shutdown.
212      *
213      * @param session session
214      */

215     public void unregisterAgent(SessionInfo session) {
216         unregisterAgent((AgentTunnel) agentsByLogonTicket.get(session.getLogonTicket()));
217     }
218     
219     /**
220      * Get all active agents.
221      *
222      * @return all agents
223      */

224     public Collection JavaDoc<AgentTunnel> getAgents() {
225         return Collections.synchronizedCollection(agentsByAgentId.values());
226     }
227
228     /**
229      * Get the agent attached to the specified session
230      *
231      * @param session session
232      * @return agent
233      */

234     public AgentTunnel getAgentBySession(SessionInfo session) {
235         if (session == null)
236             return null;
237         return (AgentTunnel) agentsByLogonTicket.get(session.getLogonTicket());
238     }
239
240     /**
241      * Get the session attached to the agent with the provided unique ticket.
242      *
243      * @param ticket unique ticket of agent
244      * @return session agent is attached to
245      */

246     public SessionInfo getSessionByAgentId(String JavaDoc ticket) {
247         if (ticket == null)
248             return null;
249
250         return (SessionInfo) LogonControllerFactory.getInstance().getAuthorizationTicket(ticket);
251     }
252
253     /**
254      * Create a new unique 'pending' ticket for agent authentication and
255      * register it with the logon controller. The returned ticket should be
256      * passed to the agent when it starts up.
257      *
258      * @param session session
259      * @return pending agent ticket
260      */

261     public String JavaDoc registerPendingAgent(SessionInfo session) {
262
263         String JavaDoc ticket = TicketGenerator.getInstance().generateUniqueTicket("AGENT");
264         LogonControllerFactory.getInstance().registerAuthorizationTicket(ticket, session);
265         return ticket;
266
267     }
268
269     /**
270      * Get if the provided session has an active agent attached to it.
271      *
272      * @param session session
273      * @return agent attached to session
274      */

275     public boolean hasActiveAgent(SessionInfo session) {
276         return session != null && agentsByLogonTicket.containsKey(session.getLogonTicket());
277     }
278
279     /**
280      * Convenience method to get if the session of the provided request has an
281      * active agent attached to it.
282      *
283      * @param request request
284      * @return agent attached to session
285      */

286     public boolean hasActiveAgent(HttpServletRequest JavaDoc request) {
287         SessionInfo session = LogonControllerFactory.getInstance().getSessionInfo(request);
288         if (session != null)
289             return hasActiveAgent(session);
290         else
291             return false;
292     }
293
294     
295
296     /**
297      * Wait for agent registration and synchronization. When this method exits
298      * the agent should be in a fully active state.
299      * <p>
300      * A timeout value (milliseconds) must be provided. If the process has not
301      * completed by this time the method with exit with <code>false</code>.
302      * Note, its is possible the agent may start after this timeout (e.g. if the
303      * client is running on very slow hardware and / or network or if the
304      * timeout value is too low).
305      *
306      * @param ticket agents unique ticket
307      * @param timeout time in milliseconds to wait for registration and
308      * synchronization.
309      * @return boolean indicating whether agent is running or not
310      */

311     public boolean waitForRegistrationAndSynchronization(String JavaDoc ticket, int timeout) {
312         SessionInfo session = getSessionByAgentId(ticket);
313         synchronized (session) {
314
315             // Has the agent already registered?
316
if (agentsByAgentId.containsKey(ticket))
317                 return true;
318
319             long left = timeout;
320             try {
321                 while (left >= 0) {
322                     if (agentsByAgentId.containsKey(ticket)) {
323                         AgentTunnel agent = agentsByAgentId.get(ticket);
324                         if (log.isInfoEnabled()) {
325                             log.info("Client registered, waiting for client synchronized request");
326                         }
327                         if(agent.waitForSync(500)) {
328                             return true;
329                         }
330 // Request request = agent.waitForRequest("synchronized@3sp.com", left);
331
// if (request != null) {
332
// if (log.isInfoEnabled()) {
333
// log.info("Got client synchronized request");
334
// }
335
// Request request = performStartup(agent);
336
// if(request == null) {
337
// return false;
338
// }
339
// try {
340
// ByteArrayWriter baw = new ByteArrayWriter();
341
// baw.writeString(VersionInfo.getVersion().toString());
342
// request.setRequestData(baw.toByteArray());
343
// return agent.sendRequest(request, false);
344
// }
345
// catch(IOException ioe) {
346
// log.error("Failed to reply with server details.", ioe);
347
// return false;
348
// }
349
// } else {
350
// log.error("Client failed to synchronized.");
351
// }
352
}
353 // try {
354
session.wait(500);
355 // } catch (InterruptedException e) {
356
// }
357
left = left - 500;
358                 }
359             } catch (InterruptedException JavaDoc e) {
360             }
361         }
362         return false;
363     }
364
365     public void startServices(AgentTunnel tunnel) {
366         if (log.isDebugEnabled()) {
367             log.debug("Starting agent services for tunnel");
368         }
369         for(Iterator JavaDoc it = agentServices.values().iterator();it.hasNext();) {
370             ((AgentService)it.next()).performStartup(tunnel);
371         }
372         if (log.isDebugEnabled()) {
373             log.debug("Started agent services for tunnel");
374         }
375     }
376
377
378
379 // protected Request performStartup(AgentTunnel tunnel) {
380
// try {
381
// if (log.isDebugEnabled()) {
382
// log.debug("Performing startup, waiting for client sync request");
383
// }
384
// Request request = tunnel.waitForRequest("synchronized@3sp.com", 30000);
385
// if (log.isDebugEnabled()) {
386
// log.debug("Got client synchronization request, continuing with startup");
387
// }
388
// // Make sure all services are initialized before agent begins
389
// if (tunnel != null) {
390
// for(Iterator it = agentServices.values().iterator();it.hasNext();) {
391
// ((AgentService)it.next()).performStartup(tunnel);
392
// }
393
// }
394
// return request;
395
// } catch (InterruptedException e) {
396
// }
397
// return null;
398
//
399
// }
400

401     
402 }
403
Popular Tags