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

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

The newest version!
/*
 *  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 org.asteriskjava.live.AgentState;
import org.asteriskjava.live.AsteriskAgent;
import org.asteriskjava.live.ManagerCommunicationException;
import org.asteriskjava.lock.LockableMap;
import org.asteriskjava.lock.Locker.LockCloser;
import org.asteriskjava.manager.ResponseEvents;
import org.asteriskjava.manager.action.AgentsAction;
import org.asteriskjava.manager.event.*;
import org.asteriskjava.util.Log;
import org.asteriskjava.util.LogFactory;

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

/**
 * 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 final Log logger = LogFactory.getLog(this.getClass());

    private final AsteriskServerImpl server;

    /**
     * A Map of agents by thier agentId.
     */
    private final LockableMap 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 LockableMap ringingAgents;

    AgentManager(AsteriskServerImpl asteriskServerImpl) {
        this.server = asteriskServerImpl;
        agents = new LockableMap<>(new HashMap<>());
        ringingAgents = new LockableMap<>(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() {
        try (LockCloser closer = agents.withLock()) {
            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) {
        try (LockCloser closer = agents.withLock()) {
            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) {
        try (LockCloser closer = agents.withLock()) {
            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);
        try (LockCloser closer = agent.withLock()) {
            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) {
        try (LockCloser closer = ringingAgents.withLock()) {
            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) {
            try (LockCloser closer = agents.withLock()) {
                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) {
            try (LockCloser closer = agents.withLock()) {
                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;

        try (LockCloser closer = agents.withLock()) {
            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 - 2024 Weber Informatics LLC | Privacy Policy