Search in sources :

Example 1 with Workgroup

use of org.jivesoftware.xmpp.workgroup.Workgroup 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 Workgroup

use of org.jivesoftware.xmpp.workgroup.Workgroup 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 Workgroup

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

the class ChatHistoryUtils method getTotalWaitTimeForWorkgroup.

/**
     * Returns the number of canceled requests.
     *
     * @param workgroupName the workgroup to search
     * @param startDate the time to begin the search from.
     * @param endDate the time to end the search.
     * @return the total number of requests
     */
public static long getTotalWaitTimeForWorkgroup(String workgroupName, Date startDate, Date endDate) {
    Workgroup workgroup = null;
    try {
        workgroup = WorkgroupManager.getInstance().getWorkgroup(new JID(workgroupName));
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    }
    if (workgroup == null) {
        return 0;
    }
    int waitTime = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(WORKGROUP_WAIT_TIME);
        pstmt.setLong(1, workgroup.getID());
        // Set the state the ignored requests.
        pstmt.setInt(2, 1);
        pstmt.setString(2, StringUtils.dateToMillis(startDate));
        pstmt.setString(3, StringUtils.dateToMillis(endDate));
        rs = pstmt.executeQuery();
        rs.next();
        waitTime = rs.getInt(1);
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    return waitTime;
}
Also used : JID(org.xmpp.packet.JID) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Workgroup(org.jivesoftware.xmpp.workgroup.Workgroup) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) SQLException(java.sql.SQLException)

Example 4 with Workgroup

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

the class ChatHistoryUtils method getNumberOfChatsAccepted.

/**
     * Returns the number of chat requests that were accepted.
     *
     * @param workgroupName the name of the workgroup where the request(s) were made.
     * @param startDate the start date.
     * @param endDate the end date.
     * @return the number of chats requests accepted by the workgroup.
     */
public static int getNumberOfChatsAccepted(String workgroupName, Date startDate, Date endDate) {
    Workgroup workgroup = null;
    try {
        workgroup = WorkgroupManager.getInstance().getWorkgroup(new JID(workgroupName));
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    }
    if (workgroup == null) {
        return 0;
    }
    int count = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(ACCEPTED_CHATS_COUNT);
        pstmt.setLong(1, workgroup.getID());
        pstmt.setString(2, StringUtils.dateToMillis(startDate));
        pstmt.setString(3, StringUtils.dateToMillis(endDate));
        rs = pstmt.executeQuery();
        if (rs.next()) {
            count = rs.getInt(1);
        }
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    return count;
}
Also used : JID(org.xmpp.packet.JID) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Workgroup(org.jivesoftware.xmpp.workgroup.Workgroup) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) SQLException(java.sql.SQLException)

Example 5 with Workgroup

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

the class ChatHistoryUtils method getNumberOfRequestsForWorkgroup.

/**
     * Returns the number of request made to a workgroup between
     * specified dates.
     *
     * @param workgroupName the workgroup to search
     * @param startDate the time to begin the search from.
     * @param endDate the time to end the search.
     * @return the total number of requests
     */
public static int getNumberOfRequestsForWorkgroup(String workgroupName, Date startDate, Date endDate) {
    Workgroup workgroup = getWorkgroup(workgroupName);
    if (workgroup == null) {
        return 0;
    }
    int count = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        con = DbConnectionManager.getConnection();
        pstmt = con.prepareStatement(WORKGROUP_REQUEST_COUNT);
        pstmt.setLong(1, workgroup.getID());
        pstmt.setString(2, StringUtils.dateToMillis(startDate));
        pstmt.setString(3, StringUtils.dateToMillis(endDate));
        rs = pstmt.executeQuery();
        if (rs.next()) {
            count = rs.getInt(1);
        }
    } catch (Exception ex) {
        Log.error(ex.getMessage(), ex);
    } finally {
        DbConnectionManager.closeConnection(rs, pstmt, con);
    }
    return count;
}
Also used : Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Workgroup(org.jivesoftware.xmpp.workgroup.Workgroup) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) SQLException(java.sql.SQLException)

Aggregations

Workgroup (org.jivesoftware.xmpp.workgroup.Workgroup)25 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)19 JID (org.xmpp.packet.JID)15 SQLException (java.sql.SQLException)7 Connection (java.sql.Connection)6 PreparedStatement (java.sql.PreparedStatement)6 ResultSet (java.sql.ResultSet)6 WorkgroupManager (org.jivesoftware.xmpp.workgroup.WorkgroupManager)6 Element (org.dom4j.Element)4 AgentSession (org.jivesoftware.xmpp.workgroup.AgentSession)4 RequestQueue (org.jivesoftware.xmpp.workgroup.RequestQueue)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 NotFoundException (org.jivesoftware.util.NotFoundException)3 AgentNotFoundException (org.jivesoftware.xmpp.workgroup.AgentNotFoundException)3 UnauthorizedException (org.jivesoftware.xmpp.workgroup.UnauthorizedException)3 IQ (org.xmpp.packet.IQ)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 AdHocCommand (org.jivesoftware.openfire.commands.AdHocCommand)2 AgentSessionList (org.jivesoftware.xmpp.workgroup.AgentSessionList)2