Search in sources :

Example 1 with AgentSession

use of org.jivesoftware.xmpp.workgroup.AgentSession in project Openfire by igniterealtime.

the class RoundRobinDispatcher method getBestNextAgent.

/**
     * <p>Locate the next 'best' agent to receive an offer.</p>
     * <p>Routing is based on show-status, max-chats, and who has
     * already rejected the offer.
     * show status is ranked from most available to least:
     * chat, default (no show status), away,
     * and xa. A show status of dnd indicates no offers should be routed to an agent.
     * The general algorithm is:</p>
     * <ul>
     * <li>Mark the current position.</li>
     * <li>Start iterating around the circular queue until all agents
     * have been considered. For each agent:
     * <ul>
     * <li>Skip if session is null. Should only occur if no agents are in the list.</li>
     * <li>Skip if session show state is DND. Never route to agents that are dnd.</li>
     * <li>Skip if session current-chats is equal to or higher than max-chats.</li>
     * <li>Replace current best if:
     * <ul>
     * <li>No current best. Any agent is better than none.</li>
     * <li>If session hasn't rejected offer but current best has.</li>
     * <li>If both session and current best have not rejected the
     * offer and session show-status is higher.</li>
     * <li>If both session and current best have rejected offer and
     * session show-status is higher.</li>
     * </ul></li>
     * </ul></li>
     * </li>
     *
     * @param initialAgent the initial agent requested by the user.
     * @param ignoreAgent agent that should not be considered as available.
     * @param offer the offer about to be sent to the best available agent.
     * @return the best agent.
     */
private AgentSession getBestNextAgent(String initialAgent, String ignoreAgent, Offer offer) {
    AgentSession bestSession;
    // Look for specified agent in agent list
    if (initialAgent != null) {
        final AgentSessionList agentSessionList = queue.getAgentSessionList();
        for (AgentSession agentSession : agentSessionList.getAgentSessions()) {
            String sessionAgent = agentSession.getAgent().getAgentJID().toBareJID();
            boolean match = sessionAgent.startsWith(initialAgent.toLowerCase());
            Workgroup workgroup = offer.getRequest().getWorkgroup();
            if (agentSession.isAvailableToChat() && agentSession.getCurrentChats(workgroup) < agentSession.getMaxChats(workgroup) && match) {
                bestSession = agentSession;
                // Log debug trace
                Log.debug("RR - Initial agent: " + bestSession.getJID() + " will receive offer for request: " + offer.getRequest());
                return bestSession;
            }
        }
    }
    // Let's iterate through each agent and check availability
    final AgentSessionList agentSessionList = queue.getAgentSessionList();
    final List<AgentSession> possibleSessions = new ArrayList<AgentSession>();
    for (AgentSession agentSession : agentSessionList.getAgentSessions()) {
        String sessionAgent = agentSession.getAgent().getAgentJID().toBareJID();
        boolean ignore = ignoreAgent != null && sessionAgent.startsWith(ignoreAgent.toLowerCase());
        if (!ignore && validateAgent(agentSession, offer)) {
            possibleSessions.add(agentSession);
        }
    }
    // Select the best agent from the list of possible agents
    if (possibleSessions.size() > 0) {
        AgentSession s = agentSelector.bestAgentFrom(possibleSessions, offer);
        // Log debug trace
        Log.debug("RR - Agent SELECTED: " + s.getJID() + " for receiving offer for request: " + offer.getRequest());
        return s;
    }
    return null;
}
Also used : AgentSession(org.jivesoftware.xmpp.workgroup.AgentSession) AgentSessionList(org.jivesoftware.xmpp.workgroup.AgentSessionList) ArrayList(java.util.ArrayList) Workgroup(org.jivesoftware.xmpp.workgroup.Workgroup)

Example 2 with AgentSession

use of org.jivesoftware.xmpp.workgroup.AgentSession in project Openfire by igniterealtime.

the class RoundRobinDispatcher method dispatch.

/**
     * Dispatch the given request to one or more agents in the agent pool.<p>
     *
     * If this method returns, it is assumed that the request was properly
     * dispatched.The only exception is if an agent is not in the pool for routing
     * within the agent timeout period, the dispatch will throw an AgentNotFoundException
     * so the request can be re-routed.
     *
     * @param offer the offer to send to the best agent available.
     */
public void dispatch(Offer offer) {
    // The time when the request should timeout
    long timeoutTime = System.currentTimeMillis() + info.getRequestTimeout();
    final Request request = offer.getRequest();
    boolean canBeInQueue = request instanceof UserRequest;
    Map<String, List<String>> map = request.getMetaData();
    String initialAgent = map.get("agent") == null || map.get("agent").isEmpty() ? null : map.get("agent").get(0);
    String ignoreAgent = map.get("ignore") == null || map.get("ignore").isEmpty() ? null : map.get("ignore").get(0);
    // Log debug trace
    Log.debug("RR - Dispatching request: " + request + " in queue: " + queue.getAddress());
    // to overflow the current request
    if (!agentList.isEmpty()) {
        for (long timeRemaining = timeoutTime - System.currentTimeMillis(); !offer.isAccepted() && timeRemaining > 0 && !offer.isCancelled(); timeRemaining = timeoutTime - System.currentTimeMillis()) {
            try {
                AgentSession session = getBestNextAgent(initialAgent, ignoreAgent, offer);
                if (session == null && agentList.isEmpty()) {
                    // Stop looking for an agent since there are no more agent available
                    break;
                } else if (session == null || offer.isRejector(session)) {
                    initialAgent = null;
                    Thread.sleep(1000);
                } else {
                    // Recheck for changed maxchat setting
                    Workgroup workgroup = request.getWorkgroup();
                    if (session.getCurrentChats(workgroup) < session.getMaxChats(workgroup)) {
                        // Set the timeout of the offer based on the remaining time of the
                        // initial request and the default offer timeout
                        timeRemaining = timeoutTime - System.currentTimeMillis();
                        offer.setTimeout(timeRemaining < info.getOfferTimeout() ? timeRemaining : info.getOfferTimeout());
                        // Make the offer and wait for a resolution to the offer
                        if (!request.sendOffer(session, queue)) {
                            // Log debug trace
                            Log.debug("RR - Offer for request: " + offer.getRequest() + " FAILED TO BE SENT to agent: " + session.getJID());
                            continue;
                        }
                        // Log debug trace
                        Log.debug("RR - Offer for request: " + offer.getRequest() + " SENT to agent: " + session.getJID());
                        offer.waitForResolution();
                        // and reset the offer
                        if (offer.isAccepted()) {
                            // Get the first agent that accepted the offer
                            AgentSession selectedAgent = offer.getAcceptedSessions().get(0);
                            // Log debug trace
                            Log.debug("RR - Agent: " + selectedAgent.getJID() + " ACCEPTED request: " + request);
                            // Create the room and send the invitations
                            offer.invite(selectedAgent);
                            // has finished
                            for (AgentSession agent : offer.getAcceptedSessions()) {
                                agent.removeOffer(offer);
                            }
                            if (canBeInQueue) {
                                // Remove the user from the queue since his request has
                                // been accepted
                                queue.removeRequest((UserRequest) request);
                            }
                        }
                    } else {
                        // Log debug trace
                        Log.debug("RR - Selected agent: " + session.getJID() + " has reached max number of chats");
                    }
                }
            } catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
    }
    if (!offer.isAccepted() && !offer.isCancelled()) {
        // Calculate the maximum time limit for an unattended request before cancelling it
        long limit = request.getCreationTime().getTime() + (info.getRequestTimeout() * (getOverflowTimes() + 1));
        if (limit - System.currentTimeMillis() <= 0 || !canBeInQueue) {
            // Log debug trace
            Log.debug("RR - Cancelling request that maxed out overflow limit or cannot be queued: " + request);
            // Cancel the request if it has overflowed 'n' times
            request.cancel(Request.CancelType.AGENT_NOT_FOUND);
        } else {
            // Overflow if request timed out and was not dispatched and max number of overflows
            // has not been reached yet
            overflow(offer);
            // If there is no other queue to overflow then cancel the request
            if (!offer.isAccepted() && !offer.isCancelled()) {
                // Log debug trace
                Log.debug("RR - Cancelling request that didn't overflow: " + request);
                request.cancel(Request.CancelType.AGENT_NOT_FOUND);
            }
        }
    }
}
Also used : AgentSession(org.jivesoftware.xmpp.workgroup.AgentSession) Request(org.jivesoftware.xmpp.workgroup.request.Request) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest) AgentSessionList(org.jivesoftware.xmpp.workgroup.AgentSessionList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Workgroup(org.jivesoftware.xmpp.workgroup.Workgroup) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest) UnauthorizedException(org.jivesoftware.xmpp.workgroup.UnauthorizedException) NotFoundException(org.jivesoftware.util.NotFoundException)

Example 3 with AgentSession

use of org.jivesoftware.xmpp.workgroup.AgentSession in project Openfire by igniterealtime.

the class ChatMetadataProvider method executeGet.

public void executeGet(IQ packet, Workgroup workgroup) {
    IQ reply = IQ.createResultIQ(packet);
    try {
        AgentSession agentSession = workgroup.getAgentManager().getAgentSession(packet.getFrom());
        if (agentSession == null) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.not_authorized));
            workgroup.send(reply);
            return;
        }
    } catch (AgentNotFoundException e) {
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(new PacketError(PacketError.Condition.not_authorized));
        workgroup.send(reply);
        return;
    }
    Element chatSessions = reply.setChildElement("chat-metadata", "http://jivesoftware.com/protocol/workgroup");
    Element iq = packet.getChildElement();
    String sessionID = iq.element("sessionID").getTextTrim();
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    Map<String, String> map = new HashMap<String, String>();
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(GET_SESSION_METADATA);
        pstmt.setString(1, sessionID);
        rs = pstmt.executeQuery();
        while (rs.next()) {
            String name = rs.getString(1);
            String value = rs.getString(2);
            map.put(name, value);
        }
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    // Add metadata
    chatSessions.add(getMetaDataElement(map));
    workgroup.send(reply);
}
Also used : AgentSession(org.jivesoftware.xmpp.workgroup.AgentSession) HashMap(java.util.HashMap) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PacketError(org.xmpp.packet.PacketError) AgentNotFoundException(org.jivesoftware.xmpp.workgroup.AgentNotFoundException) PreparedStatement(java.sql.PreparedStatement) AgentNotFoundException(org.jivesoftware.xmpp.workgroup.AgentNotFoundException)

Example 4 with AgentSession

use of org.jivesoftware.xmpp.workgroup.AgentSession in project Openfire by igniterealtime.

the class ChatNotes method executeSet.

public void executeSet(IQ packet, Workgroup workgroup) {
    IQ reply;
    Element iq = packet.getChildElement();
    try {
        // Verify that an agent is requesting this information.
        AgentSession agentSession = workgroup.getAgentManager().getAgentSession(packet.getFrom());
        if (agentSession != null) {
            String sessionID = iq.element("sessionID").getTextTrim();
            Element notes = iq.element("notes");
            String noteText = notes.getTextTrim();
            appendNote(sessionID, noteText);
            reply = IQ.createResultIQ(packet);
        } else {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
        }
    } catch (AgentNotFoundException e) {
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(new PacketError(PacketError.Condition.item_not_found));
    }
    workgroup.send(reply);
}
Also used : AgentSession(org.jivesoftware.xmpp.workgroup.AgentSession) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) PacketError(org.xmpp.packet.PacketError) AgentNotFoundException(org.jivesoftware.xmpp.workgroup.AgentNotFoundException)

Example 5 with AgentSession

use of org.jivesoftware.xmpp.workgroup.AgentSession in project Openfire by igniterealtime.

the class SiteTracker method handleUserHistoryRequest.

private void handleUserHistoryRequest(IQ packet, Workgroup workgroup) {
    IQ reply;
    Element iq = packet.getChildElement();
    try {
        AgentSession agentSession = workgroup.getAgentManager().getAgentSession(packet.getFrom());
        if (agentSession == null) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.not_authorized));
            workgroup.send(reply);
            return;
        }
    } catch (AgentNotFoundException e) {
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(new PacketError(PacketError.Condition.not_authorized));
        workgroup.send(reply);
        return;
    }
    // Define default values
    String sessionID = iq.attribute("sessionID").getText();
    reply = IQ.createResultIQ(packet);
    Element views = reply.setChildElement("site-user-history", "http://jivesoftware.com/protocol/workgroup");
    views.addAttribute("sessionID", sessionID);
    SiteUser siteUser = siteUsers.get(sessionID);
    if (siteUser != null) {
        for (PageView view : siteUser.getViews()) {
            Element pageView = views.addElement("page-view");
            pageView.addElement("title").setText(view.getTitle());
            pageView.addElement("url").setText(view.getUrl());
            pageView.addElement("time").setText(Long.toString(view.getTimeViewed()));
        }
        workgroup.send(reply);
    }
}
Also used : AgentSession(org.jivesoftware.xmpp.workgroup.AgentSession) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) PacketError(org.xmpp.packet.PacketError) AgentNotFoundException(org.jivesoftware.xmpp.workgroup.AgentNotFoundException)

Aggregations

AgentSession (org.jivesoftware.xmpp.workgroup.AgentSession)11 Element (org.dom4j.Element)6 AgentNotFoundException (org.jivesoftware.xmpp.workgroup.AgentNotFoundException)6 IQ (org.xmpp.packet.IQ)6 Workgroup (org.jivesoftware.xmpp.workgroup.Workgroup)4 PacketError (org.xmpp.packet.PacketError)4 NotFoundException (org.jivesoftware.util.NotFoundException)3 AgentSessionList (org.jivesoftware.xmpp.workgroup.AgentSessionList)3 ArrayList (java.util.ArrayList)2 RequestQueue (org.jivesoftware.xmpp.workgroup.RequestQueue)2 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 UnauthorizedException (org.jivesoftware.xmpp.workgroup.UnauthorizedException)1 Request (org.jivesoftware.xmpp.workgroup.request.Request)1 UserRequest (org.jivesoftware.xmpp.workgroup.request.UserRequest)1