All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.asteriskjava.live.internal.AgentManager Maven / Gradle / Ivy

/*
 * Copyright 2004-2006 Stefan Reuter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.asteriskjava.live.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.asteriskjava.live.AgentState;
import org.asteriskjava.live.AsteriskAgent;
import org.asteriskjava.live.ManagerCommunicationException;
import org.asteriskjava.manager.ResponseEvents;
import org.asteriskjava.manager.action.AgentsAction;
import org.asteriskjava.manager.event.AgentCallbackLoginEvent;
import org.asteriskjava.manager.event.AgentCallbackLogoffEvent;
import org.asteriskjava.manager.event.AgentCalledEvent;
import org.asteriskjava.manager.event.AgentCompleteEvent;
import org.asteriskjava.manager.event.AgentConnectEvent;
import org.asteriskjava.manager.event.AgentLoginEvent;
import org.asteriskjava.manager.event.AgentLogoffEvent;
import org.asteriskjava.manager.event.AgentsEvent;
import org.asteriskjava.manager.event.ManagerEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Manages all events related to agents on Asterisk server. For correct work
 * ensure enabled AgentCalledEvents. You have to set
 * eventwhencalled = yes in queues.conf.
 *
 * @author Patrick Breucking
 * @version $Id$
 * @since 0.3.1
 */
public class AgentManager {

    private static final Logger logger = LoggerFactory.getLogger(AgentManager.class);

    private final AsteriskServerImpl server;

    /**
     * A Map of agents by thier agentId.
     */
    private final Map agents;

    /**
     * A Map of agent in state RINGING by the caller id. Needed to return agent
     * into idle state, if call was not conneted.
     */
    private final Map ringingAgents;

    AgentManager(AsteriskServerImpl asteriskServerImpl) {
        this.server = asteriskServerImpl;
        agents = new HashMap<>();
        ringingAgents = new HashMap<>();
    }

    /**
     * Retrieves all agents registered at Asterisk server by sending an
     * AgentsAction.
     *
     * @throws ManagerCommunicationException
     *             if communication with Asterisk
     *             server fails.
     */
    void initialize() throws ManagerCommunicationException {
        ResponseEvents re;

        re = server.sendEventGeneratingAction(new AgentsAction());

        for (ManagerEvent event : re.getEvents()) {
            if (event instanceof AgentsEvent) {
                logger.info("{}",event);
                handleAgentsEvent((AgentsEvent) event);
            }
        }
    }

    void disconnected() {
        synchronized (agents) {
            agents.clear();
        }
    }

    /**
     * On AgentsEvent create a new Agent.
     *
     * @param event
     *            generated by Asterisk server.
     */
    void handleAgentsEvent(AgentsEvent event) {
        AsteriskAgentImpl agent = new AsteriskAgentImpl(server, event.getName(),
                "Agent/" + event.getAgent(), AgentState.valueOf(event.getStatus()));
        logger.info("Adding agent " + agent.getName() + "(" + agent.getAgentId() + ")");

        addAgent(agent);
    }

    /**
     * Add a new agent to the manager.
     *
     * @param agent
     *            agent to add.
     */
    private void addAgent(AsteriskAgentImpl agent) {
        synchronized (agents) {
            agents.put(agent.getAgentId(), agent);
        }
        server.fireNewAgent(agent);
    }

    /**
     * Return the requested agent.
     *
     * @param agentId
     *            identifier for agent
     * @return the requested agent
     */
    AsteriskAgentImpl getAgentByAgentId(String agentId) {
        synchronized (agents) {
            return agents.get(agentId);
        }
    }

    /**
     * Update state if agent was called.
     *
     * @param event
     */
    void handleAgentCalledEvent(AgentCalledEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId(event.getAgentCalled());
        if (agent == null) {
            logger.error("Ignored AgentCalledEvent for unknown agent " + event.getAgentCalled());
            return;
        }
        updateRingingAgents(event.getChannelCalling(), agent);
        updateAgentState(agent, AgentState.AGENT_RINGING);
    }

    /**
     * Set state of agent.
     *
     * @param agent
     */
    private void updateAgentState(AsteriskAgentImpl agent, AgentState newState) {
        logger.info("Set state of agent " + agent.getAgentId() + " to " + newState);
        synchronized (agent) {
            agent.updateState(newState);
        }
    }

    /**
     * Updates state of agent, if the call in a queue was redirect to the next
     * agent because the ringed agent doesn't answer the call. After reset
     * state, put the next agent in charge.
     *
     * @param channelCalling
     * @param agent
     */
    private void updateRingingAgents(String channelCalling, AsteriskAgentImpl agent) {
        synchronized (ringingAgents) {
            if (ringingAgents.containsKey(channelCalling)) {
                updateAgentState(ringingAgents.get(channelCalling), AgentState.AGENT_IDLE);
            }
            ringingAgents.put(channelCalling, agent);
        }
    }

    /**
     * Update state if agent was connected to channel.
     *
     * @param event
     */
    void handleAgentConnectEvent(AgentConnectEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId(event.getChannel());
        if (agent == null) {
            logger.error("Ignored AgentConnectEvent for unknown agent " + event.getChannel());
            return;
        }
        agent.updateState(AgentState.AGENT_ONCALL);
    }

    /**
     * Change state if agent logs in.
     *
     * @param event
     */
    void handleAgentLoginEvent(AgentLoginEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId("Agent/" + event.getAgent());
        if (agent == null) {
            synchronized (agents) {
                logger.error("Ignored AgentLoginEvent for unknown agent " + event.getAgent()
                        + ". Agents: " + agents.values()
                                .toString());

            }
            return;
        }
        agent.updateState(AgentState.AGENT_IDLE);
    }

    /**
     * Change state if agent logs out.
     *
     * @param event
     */
    void handleAgentLogoffEvent(AgentLogoffEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId("Agent/" + event.getAgent());
        if (agent == null) {
            logger.error("Ignored AgentLogoffEvent for unknown agent " + event.getAgent()
                    + ". Agents: " + agents.values()
                            .toString());
            return;
        }
        agent.updateState(AgentState.AGENT_LOGGEDOFF);
    }

    /**
     * Change state if agent logs in.
     *
     * @param event
     */
    void handleAgentCallbackLoginEvent(AgentCallbackLoginEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId("Agent/" + event.getAgent());
        if (agent == null) {
            synchronized (agents) {
                logger.error("Ignored AgentCallbackLoginEvent for unknown agent " + event.getAgent()
                        + ". Agents: " + agents.values()
                                .toString());

            }
            return;
        }
        agent.updateState(AgentState.AGENT_IDLE);
    }

    /**
     * Change state if agent logs out.
     *
     * @param event
     */
    void handleAgentCallbackLogoffEvent(AgentCallbackLogoffEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId("Agent/" + event.getAgent());
        if (agent == null) {
            logger.error("Ignored AgentCallbackLogoffEvent for unknown agent " + event.getAgent()
                    + ". Agents: " + agents.values()
                            .toString());
            return;
        }
        agent.updateState(AgentState.AGENT_LOGGEDOFF);

    }

    /**
     * Return all agents registered at Asterisk server.
     *
     * @return a collection of all agents.
     */
    Collection getAgents() {
        Collection copy;

        synchronized (agents) {
            copy = new ArrayList(agents.values());
        }
        return copy;
    }

    /**
     * Change state if connected call was terminated.
     *
     * @param event
     */
    void handleAgentCompleteEvent(AgentCompleteEvent event) {
        AsteriskAgentImpl agent = getAgentByAgentId(event.getChannel());
        if (agent == null) {
            logger.error("Ignored AgentCompleteEvent for unknown agent " + event.getChannel());
            return;
        }
        agent.updateState(AgentState.AGENT_IDLE);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy