org.asteriskjava.live.internal.AgentManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of asterisk-java Show documentation
Show all versions of asterisk-java Show documentation
The free Java library for Asterisk PBX integration.
/*
* 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 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.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.asteriskjava.util.Log;
import org.asteriskjava.util.LogFactory;
/**
* 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);
}
}