Search in sources :

Example 1 with Request

use of org.jivesoftware.xmpp.workgroup.request.Request 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 2 with Request

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

the class Chatbot method userDepartQueue.

private void userDepartQueue(Message message) {
    // Remove the user from the queue if he was waiting in the queue
    try {
        Request request = UserRequest.getRequest(workgroup, message.getFrom());
        InterceptorManager interceptorManager = QueueInterceptorManager.getInstance();
        try {
            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), message, true, false);
            request.cancel(Request.CancelType.DEPART);
            // Remove the session (the goodbye message is sent when leaving the queue)
            removeSession(message.getFrom());
            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), message, true, true);
        } catch (PacketRejectedException e) {
            workgroup.rejectPacket(message, e);
        }
    } catch (NotFoundException e) {
        // Send the goodbye message and close the session
        closeSession(message);
    }
}
Also used : InterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager) QueueInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.QueueInterceptorManager) ChatbotInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.ChatbotInterceptorManager) Request(org.jivesoftware.xmpp.workgroup.request.Request) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest) PacketRejectedException(org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException) NotFoundException(org.jivesoftware.util.NotFoundException)

Example 3 with Request

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

the class WorkgroupIQHandler method handleIQSet.

private void handleIQSet(IQ packet) {
    IQ reply;
    // TODO: verify namespace and send error if wrong
    Element iq = packet.getChildElement();
    JID sender = packet.getFrom();
    reply = IQ.createResultIQ(packet);
    reply.setFrom(workgroup.getJID());
    String queryName = iq.getName();
    String queryNamespace = iq.getNamespace().toString();
    if ("join-queue".equals(queryName)) {
        InterceptorManager interceptorManager = QueueInterceptorManager.getInstance();
        try {
            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, false);
            // Received a Join Queue request from a visitor, create a new request.
            UserRequest request = new UserRequest(packet, workgroup);
            // Let the workgroup process the new request
            if (!workgroup.queueRequest(request)) {
                // It was not possible to add the request to a queue so answer that the
                // workgroup is not accepting new join-queue requests
                reply.setChildElement(packet.getChildElement().createCopy());
                reply.setError(new PacketError(PacketError.Condition.service_unavailable));
            }
            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, true);
        } catch (PacketRejectedException e) {
            workgroup.rejectPacket(packet, e);
            reply = null;
        }
    } else if ("depart-queue".equals(queryName)) {
        // Visitor is departing queue
        try {
            Request request = UserRequest.getRequest(workgroup, sender);
            InterceptorManager interceptorManager = QueueInterceptorManager.getInstance();
            try {
                interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, false);
                request.cancel(Request.CancelType.DEPART);
                iq.add(request.getSessionElement());
                interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, true);
            } catch (PacketRejectedException e) {
                workgroup.rejectPacket(packet, e);
                reply = null;
            }
        } catch (NotFoundException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
            Log.debug("Request not found" + " while departing queue:", e);
        }
    } else if ("offer-accept".equals(queryName)) {
        try {
            InterceptorManager interceptorManager = OfferInterceptorManager.getInstance();
            String id = iq.attributeValue("id");
            String jid = iq.attributeValue("jid");
            if (id != null || jid != null) {
                Request request;
                if (id != null) {
                    // Search request by its unique ID
                    request = Request.getRequest(id);
                } else {
                    // Old version of FP refers to requests by the user's jid. This old version
                    // implements transfers and invitations on the client and not the server side.
                    // Therefore, for each user's jid there is always a unique Request
                    request = UserRequest.getRequest(workgroup, new JID(jid));
                }
                Offer offer = request.getOffer();
                if (offer != null && offer.isOutstanding()) {
                    AgentSession agentSession = agentManager.getAgentSession(packet.getFrom());
                    if (agentSession == null) {
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(new PacketError(PacketError.Condition.item_not_found));
                        Log.debug("Agent not found while accepting offer");
                    } else {
                        try {
                            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, false);
                            offer.accept(agentSession);
                            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, true);
                        } catch (PacketRejectedException e) {
                            workgroup.rejectPacket(packet, e);
                            reply = null;
                        }
                    }
                } else {
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(new PacketError(PacketError.Condition.not_acceptable));
                }
            }
        } catch (NotFoundException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
            Log.debug("Request not found " + "while accepting offer: ", e);
        } catch (AgentNotFoundException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
            Log.debug("Agent not found " + "while accepting offer: ", e);
        }
    } else if ("offer-reject".equals(queryName)) {
        try {
            InterceptorManager interceptorManager = OfferInterceptorManager.getInstance();
            String id = iq.attributeValue("id");
            String jid = iq.attributeValue("jid");
            if (id != null || jid != null) {
                Request request;
                if (id != null) {
                    // Search request by its unique ID
                    request = Request.getRequest(id);
                } else {
                    // Old version of FP refers to requests by the user's jid. This old version
                    // implements transfers and invitations on the client and not the server side.
                    // Therefore, for each user's jid there is always a unique Request
                    request = UserRequest.getRequest(workgroup, new JID(jid));
                }
                Offer offer = request.getOffer();
                if (offer != null) {
                    AgentSession agentSession = agentManager.getAgentSession(packet.getFrom());
                    if (agentSession == null) {
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(new PacketError(PacketError.Condition.item_not_found));
                        Log.debug("Agent not found while accepting offer");
                    } else {
                        try {
                            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, false);
                            offer.reject(agentSession);
                            interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), packet, true, true);
                        } catch (PacketRejectedException e) {
                            workgroup.rejectPacket(packet, e);
                            reply = null;
                        }
                    }
                }
            }
        } catch (NotFoundException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
            Log.debug("Request not found " + "while rejecting offer: ", e);
        } catch (AgentNotFoundException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.item_not_found));
            Log.debug("Agent not found " + "while accepting offer: ", e);
        }
    } else if ("invite".equals(queryName)) {
        // Get the type of inviation (i.e. entity type is being invited)
        InvitationRequest request = new InvitationRequest(packet, workgroup);
        workgroup.processInvitation(request, packet);
        reply = null;
    } else if ("transfer".equals(queryName)) {
        // Get the type of transfer (i.e. entity type is going to get the transfer offer)
        TransferRequest request = new TransferRequest(packet, workgroup);
        workgroup.processTransfer(request, packet);
        reply = null;
    } else if ("jabber:iq:private".equals(queryNamespace)) {
        // IQ private for agents global macro storage
        setIQPrivate(packet);
    } else if ("agent-info".equals(queryName)) {
        if (!JiveGlobals.getBooleanProperty("xmpp.live.agent.change-properties", true)) {
            // Answer that agents are not allowed to change their properties (feature disabled)
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(new PacketError(PacketError.Condition.service_unavailable));
        } else {
            try {
                AgentSession agentSession = agentManager.getAgentSession(packet.getFrom());
                if (agentSession == null) {
                    reply = IQ.createResultIQ(packet);
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(new PacketError(PacketError.Condition.item_not_found));
                } else {
                    String allowsToChange = agentSession.getAgent().getProperties().getProperty("change-properties");
                    if (!"false".equals(allowsToChange)) {
                        // Set the new agent's info
                        agentSession.getAgent().updateAgentInfo(packet);
                    } else {
                        // Answer that this agent is not allowed to change his properties
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(new PacketError(PacketError.Condition.service_unavailable));
                    }
                }
            } catch (AgentNotFoundException e) {
                reply = IQ.createResultIQ(packet);
                reply.setChildElement(packet.getChildElement().createCopy());
                reply.setError(new PacketError(PacketError.Condition.item_not_found));
            }
        }
    } else {
        // none are found, send bad request error.
        for (WorkgroupProvider provider : providerManager.getWorkgroupProviders()) {
            // Handle packet?
            if (provider.handleSet(packet)) {
                // If provider accepts responsibility, hand off packet.
                provider.executeSet(packet, workgroup);
                return;
            }
        }
        dropPacket(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(new PacketError(PacketError.Condition.bad_request));
    }
    if (reply != null) {
        workgroup.send(reply);
    }
}
Also used : JID(org.xmpp.packet.JID) Element(org.dom4j.Element) OfferInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.OfferInterceptorManager) QueueInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.QueueInterceptorManager) InterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager) IQ(org.xmpp.packet.IQ) Request(org.jivesoftware.xmpp.workgroup.request.Request) TransferRequest(org.jivesoftware.xmpp.workgroup.request.TransferRequest) InvitationRequest(org.jivesoftware.xmpp.workgroup.request.InvitationRequest) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest) PacketError(org.xmpp.packet.PacketError) NotFoundException(org.jivesoftware.util.NotFoundException) InvitationRequest(org.jivesoftware.xmpp.workgroup.request.InvitationRequest) TransferRequest(org.jivesoftware.xmpp.workgroup.request.TransferRequest) PacketRejectedException(org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest)

Aggregations

NotFoundException (org.jivesoftware.util.NotFoundException)3 Request (org.jivesoftware.xmpp.workgroup.request.Request)3 UserRequest (org.jivesoftware.xmpp.workgroup.request.UserRequest)3 InterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager)2 PacketRejectedException (org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException)2 QueueInterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.QueueInterceptorManager)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Element (org.dom4j.Element)1 AgentSession (org.jivesoftware.xmpp.workgroup.AgentSession)1 AgentSessionList (org.jivesoftware.xmpp.workgroup.AgentSessionList)1 UnauthorizedException (org.jivesoftware.xmpp.workgroup.UnauthorizedException)1 Workgroup (org.jivesoftware.xmpp.workgroup.Workgroup)1 ChatbotInterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.ChatbotInterceptorManager)1 OfferInterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.OfferInterceptorManager)1 InvitationRequest (org.jivesoftware.xmpp.workgroup.request.InvitationRequest)1 TransferRequest (org.jivesoftware.xmpp.workgroup.request.TransferRequest)1 IQ (org.xmpp.packet.IQ)1 JID (org.xmpp.packet.JID)1