Package com.adito.agent

Source Code of com.adito.agent.DefaultAgentManager

package com.adito.agent;

import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.maverick.multiplex.Request;
import com.maverick.util.ByteArrayReader;
import com.maverick.util.ByteArrayWriter;
import com.adito.core.CoreException;
import com.adito.policyframework.LaunchSession;
import com.adito.security.LogonControllerFactory;
import com.adito.security.SessionInfo;
import com.adito.util.TicketGenerator;

/**
* Manages <i>Agent</i> instances.
*/
public class DefaultAgentManager {

  static Log log = LogFactory.getLog(DefaultAgentManager.class);

  static DefaultAgentManager instance = null;

  static final String AGENT_ID = "agentId";
  static final String SESSION_INFO = "sessionInfo";
 
  // Private instance variables
  private HashMap<String, AgentTunnel> agentsByAgentId = new HashMap<String, AgentTunnel>();
    private HashMap<String, AgentTunnel> agentsByLogonTicket = new HashMap<String, AgentTunnel>();
  private HashMap<Class, AgentService> agentServices = new HashMap<Class, AgentService>();
  private ResourceRequestHandler resourceRequestHandler = new ResourceRequestHandler();
  private ThreadPoolExecutor agentBroadcastExecutor;

  private DefaultAgentManager() {
    agentBroadcastExecutor = new ThreadPoolExecutor(1, 5, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000));
  }
 
  /**
   * Get an instance of the agent manager.
   *
   * @return agent manager
   */
  public static DefaultAgentManager getInstance() {
    return instance == null ? instance = new DefaultAgentManager() : instance;
  }
 
  /**
   * Get all registered services.
   *
   * @return all registered services
   */
  public Collection<AgentService> getServices() {
    return agentServices.values();
  }
 
  /**
   * Get a service given its class.
   *
   * @param cls class
   * @return server
   */
  public AgentService getService(Class<?> cls) {
    return agentServices.get(cls);
  }
 
  /**
   * Get an thread pool executor to use for broadcasting messages
   * to all Agents.
   *
   * @return agent broadcast executor
   */
  public ThreadPoolExecutor getAgentBroadcastExecutor() {
    return agentBroadcastExecutor;
  }
 
  /**
   * Register an AgentService implementation with the agent.
   * @param cls
   * @throws InstantiationException
   * @throws IllegalAccessException
   */
  public void registerService(Class<?> cls) throws InstantiationException, IllegalAccessException {
    agentServices.put(cls, (AgentService)cls.newInstance());
  }
 
  /**
   * Unregister an AgentService implementation on the agent.
   * @param cls
   */
  public void unregisterService(Class<?> cls) {
    agentServices.remove(cls);
  }

  /**
   * Register a new agent.
   *
   * @param ticket unique ticket
   * @param session session
   * @param tunnel agent
   * @throws AgentException
   */
  public void registerAgent(String ticket, SessionInfo session, AgentTunnel tunnel) throws AgentException {

    LogonControllerFactory.getInstance().removeAuthorizationTicket(ticket);
   
    if (session != null) {
     
     
      synchronized (session) {
        agentsByAgentId.put(ticket, tunnel);
        agentsByLogonTicket.put(session.getLogonTicket(), tunnel);
        tunnel.addListener(new DefaultAgentStartupListener(session));
        tunnel.registerRequestHandler("getResources", resourceRequestHandler);
       
        // Make sure all services are initialised before agent begins
        if (tunnel != null) {
          for(AgentService service : agentServices.values()) {
            service.initializeTunnel(tunnel);
          }
        }
      }
    } else {
      tunnel.close();
      throw new AgentException("");
    }
  }

 

  /**
   * Inform the agent to open the specified URL with its local default browser
   *
   * @param agent agent
   * @param url URL to open
   * @param launchSession launch session
   * @return return code
   * @throws CoreException on any error
   */
  public int openURL(AgentTunnel agent, URL url, LaunchSession launchSession) throws CoreException {

    try {
      ByteArrayWriter msg = new ByteArrayWriter();
      msg.writeString(url.toExternalForm());
      msg.writeString(launchSession.getId());
      Request request = new Request("openURL", msg.toByteArray());
      if (agent.sendRequest(request, true)) {
        if(request.getRequestData()!=null) {
        ByteArrayReader rdr = new ByteArrayReader(request.getRequestData());
        return (int) rdr.readInt();
        }
      }

    } catch (Exception e) {
      throw new CoreException(0, "", e);
    }
    return -1;
  }

  /**
   * Unregister an agent. If the agent is running it will be shutdown.
   *
   * @param tunnel
   */
  public void unregisterAgent(AgentTunnel tunnel) {

    if (tunnel != null) {
     
      if (log.isDebugEnabled())
        log.debug("Unregistering agent with id " + tunnel.getId());

      agentsByAgentId.remove(tunnel.getId());
      agentsByLogonTicket.remove(tunnel.getSession().getLogonTicket());

      if (tunnel.isRunning()) {
        try {
          tunnel.sendRequest(new Request("shutdown", "".getBytes()), false, 10000);
        } catch (IOException e) {
          log.error("Failed to send shutdown request to agent. The agent may not be responding or the network link may now be down.",
            e);
        }
        tunnel.close();
      }
      if(tunnel.getSession().getHttpSession() == null) {
        log.info("Non UI session so cleaning up session.");     
        LogonControllerFactory.getInstance().logoff(tunnel.getSession().getLogonTicket());
      }
    }
  }

  /**
   * Unregister an agent given the session it attached to. If the agent is
   * running it will be shutdown.
   *
   * @param session session
   */
  public void unregisterAgent(SessionInfo session) {
    unregisterAgent((AgentTunnel) agentsByLogonTicket.get(session.getLogonTicket()));
  }
 
  /**
   * Get all active agents.
   *
   * @return all agents
   */
  public Collection<AgentTunnel> getAgents() {
    return Collections.synchronizedCollection(agentsByAgentId.values());
  }

  /**
   * Get the agent attached to the specified session
   *
   * @param session session
   * @return agent
   */
  public AgentTunnel getAgentBySession(SessionInfo session) {
    if (session == null)
      return null;
    return (AgentTunnel) agentsByLogonTicket.get(session.getLogonTicket());
  }

  /**
   * Get the session attached to the agent with the provided unique ticket.
   *
   * @param ticket unique ticket of agent
   * @return session agent is attached to
   */
  public SessionInfo getSessionByAgentId(String ticket) {
    if (ticket == null)
      return null;

    return (SessionInfo) LogonControllerFactory.getInstance().getAuthorizationTicket(ticket);
  }

  /**
   * Create a new unique 'pending' ticket for agent authentication and
   * register it with the logon controller. The returned ticket should be
   * passed to the agent when it starts up.
   *
   * @param session session
   * @return pending agent ticket
   */
  public String registerPendingAgent(SessionInfo session) {

    String ticket = TicketGenerator.getInstance().generateUniqueTicket("AGENT");
    LogonControllerFactory.getInstance().registerAuthorizationTicket(ticket, session);
    return ticket;

  }

  /**
   * Get if the provided session has an active agent attached to it.
   *
   * @param session session
   * @return agent attached to session
   */
  public boolean hasActiveAgent(SessionInfo session) {
    return session != null && agentsByLogonTicket.containsKey(session.getLogonTicket());
  }

  /**
   * Convenience method to get if the session of the provided request has an
   * active agent attached to it.
   *
   * @param request request
   * @return agent attached to session
   */
  public boolean hasActiveAgent(HttpServletRequest request) {
    SessionInfo session = LogonControllerFactory.getInstance().getSessionInfo(request);
    if (session != null)
      return hasActiveAgent(session);
    else
      return false;
  }

 

  /**
   * Wait for agent registration and synchronization. When this method exits
   * the agent should be in a fully active state.
   * <p>
   * A timeout value (milliseconds) must be provided. If the process has not
   * completed by this time the method with exit with <code>false</code>.
   * Note, its is possible the agent may start after this timeout (e.g. if the
   * client is running on very slow hardware and / or network or if the
   * timeout value is too low).
   *
   * @param ticket agents unique ticket
   * @param timeout time in milliseconds to wait for registration and
   *        synchronization.
   * @return boolean indicating whether agent is running or not
   */
  public boolean waitForRegistrationAndSynchronization(String ticket, int timeout) {
    SessionInfo session = getSessionByAgentId(ticket);
    synchronized (session) {

      // Has the agent already registered?
      if (agentsByAgentId.containsKey(ticket))
        return true;

      long left = timeout;
      try {
        while (left >= 0) {
          if (agentsByAgentId.containsKey(ticket)) {
            AgentTunnel agent = agentsByAgentId.get(ticket);
            if (log.isInfoEnabled()) {
              log.info("Client registered, waiting for client synchronized request");
            }
            if(agent.waitForSync(500)) {
              return true;
            }
          }
          session.wait(500);
          left = left - 500;
        }
      } catch (InterruptedException e) {
      }
    }
    return false;
  }

  /**
   * Start all services for the supplied agent connection.
   *
   * @param tunnel agent connection
   */
  public void startServices(AgentTunnel tunnel) {
    if (log.isDebugEnabled()) {
      log.debug("Starting agent services for tunnel");
    }
    for(AgentService service : getServices()) {
      service.performStartup(tunnel);
    }     
    if (log.isDebugEnabled()) {
      log.debug("Started agent services for tunnel");
    }
  }
}
TOP

Related Classes of com.adito.agent.DefaultAgentManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.