Search in sources :

Example 1 with UserRequest

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

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

the class Chatbot method handleCommand.

/**
     * Returns true if the message sent by the user requested to run a command. Depending on the
     * stage of the conversation different commands may be executed.
     *
     * @param message the message.
     * @param session the session.
     * @return true if the message sent by the user requested to run a command.
     */
private boolean handleCommand(Message message, ChatbotSession session) {
    String command = message.getBody().trim();
    if (getHelpCommand().equalsIgnoreCase(command)) {
        sendHelpMessage(message);
        return true;
    } else if (getByeCommand().equalsIgnoreCase(command)) {
        userDepartQueue(message);
        return true;
    }
    if (session.getCurrentStep() == 1) {
        if (getRepeatCommand().equalsIgnoreCase(command)) {
            // Send the join question
            sendJoinQuestion(message, session);
            return true;
        } else if (getPositionCommand().equalsIgnoreCase(command)) {
            // Tell the user that he is not waiting in the queue
            sendReply(message, getNotInQueueMessage());
            return true;
        }
    } else if (session.getCurrentStep() == 2) {
        if (getBackCommand().equalsIgnoreCase(command)) {
            sendPreviousQuestion(message, session);
            return true;
        } else if (getRepeatCommand().equalsIgnoreCase(command)) {
            // Resend the last question
            repeatQuestion(message, session);
            return true;
        } else if (getPositionCommand().equalsIgnoreCase(command)) {
            // Tell the user that he is not waiting in the queue
            sendReply(message, getNotInQueueMessage());
            return true;
        }
    } else if (session.getCurrentStep() == 3) {
        if (getPositionCommand().equalsIgnoreCase(command)) {
            try {
                UserRequest request = UserRequest.getRequest(workgroup, message.getFrom());
                request.updateQueueStatus(true);
            } catch (NotFoundException e) {
                // Tell the user that he is not waiting in the queue
                sendReply(message, getNotInQueueMessage());
            }
            return true;
        }
    } else if (session.getCurrentStep() == 6) {
        if (getRepeatCommand().equalsIgnoreCase(command)) {
            // Resend the last question
            sendEmailQuestion(message.getFrom(), session);
            return true;
        }
    } else if (session.getCurrentStep() == 7) {
        if (getRepeatCommand().equalsIgnoreCase(command)) {
            // Resend the last question
            sendGetEmailQuestion(message, session);
            return true;
        }
    }
    return false;
}
Also used : NotFoundException(org.jivesoftware.util.NotFoundException) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest)

Example 3 with UserRequest

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

the class Chatbot method userJoinQueue.

private void userJoinQueue(Message message, ChatbotSession session) {
    InterceptorManager interceptorManager = QueueInterceptorManager.getInstance();
    try {
        interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), message, true, false);
        if (getRoutingMessage() != null && getRoutingMessage().length() > 0) {
            sendReply(message, getRoutingMessage());
        }
        // Set that we are currently joining a waiting queue
        session.setCurrentStep(3);
        // Received a Join Queue request from a visitor, create a new request.
        UserRequest request = new UserRequest(session, workgroup);
        // Let the workgroup process the new request
        if (!workgroup.queueRequest(request)) {
            // It was not possible to add the request to a queue so send message saying that
            // the workgroup is not accepting new join requests
            sendReply(message, getCannotJoinMessage());
            // Send the goodbye message and close the session
            closeSession(message);
        } else {
            session.setRequest(request);
        }
        interceptorManager.invokeInterceptors(workgroup.getJID().toBareJID(), message, true, true);
    } catch (PacketRejectedException e) {
        workgroup.rejectPacket(message, e);
    }
}
Also used : InterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager) QueueInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.QueueInterceptorManager) ChatbotInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.ChatbotInterceptorManager) PacketRejectedException(org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest)

Example 4 with UserRequest

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

the class Workgroup method roomActivity.

// ###############################################################################
// MUC related packets
// ###############################################################################
/**
     * Notification message indicating that there has been new activity in a room. This implies
     * that we need to update the conversation transcript of the group chat room and possibly
     * update the number of occupants within the room.<p>
     * <p/>
     * If only the workgroup is present in the room then leave the room (i.e. destroying room) and
     * proceed to save the room conversation transcript to the database.<p>
     *
     * @param packet the packet that was sent to the group chat room.
     */
private void roomActivity(Packet packet) {
    // Skip packet sent from this workgroup in the room
    if (packet.getFrom().toBareJID().equals(getGroupChatRoomName())) {
        return;
    }
    RoomInterceptorManager interceptorManager = RoomInterceptorManager.getInstance();
    String roomID = packet.getFrom().getNode();
    // Get the sessionID
    String sessionID = packet.getFrom().getNode();
    synchronized (sessionID.intern()) {
        if (packet instanceof Presence) {
            Presence presence = (Presence) packet;
            if (Presence.Type.error == presence.getType()) {
                // A configuration must be wrong (eg. workgroup is not allowed to create rooms).
                // Log the error presence
                String warnMessage = "Possible server misconfiguration. Received error " + "presence:" + presence.toXML();
                Log.warn(warnMessage);
                return;
            }
            // Get the JID of the presence's user
            Element mucUser = presence.getChildElement("x", "http://jabber.org/protocol/muc#user");
            // Skip this presence if no extended info was included in the presence
            if (mucUser == null) {
                return;
            }
            Element item = mucUser.element("item");
            // Skip this presence if no item was included in the presence
            if (item == null) {
                return;
            }
            // Skip this presence if it's the presence of this workgroup in the room
            if (workgroupName.equals(packet.getFrom().getResource())) {
                return;
            }
            JID presenceFullJID = new JID(item.attributeValue("jid"));
            String presenceJID = presenceFullJID.toBareJID();
            // Invoke the room interceptor before processing the presence
            interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, false);
            // Get the userID associated to this sessionID
            UserRequest initialRequest = requests.get(sessionID);
            // Add the new presence to the list of sent packets
            Map<Packet, java.util.Date> messageList = transcripts.get(roomID);
            if (messageList == null) {
                messageList = new LinkedHashMap<Packet, java.util.Date>();
                transcripts.put(roomID, messageList);
                // Trigger the event that a chat support has started
                WorkgroupEventDispatcher.chatSupportStarted(this, sessionID);
            }
            messageList.put(packet.createCopy(), new java.util.Date());
            // Update the number of occupants in the room.
            boolean occupantAdded = false;
            Set<String> set = occupantsCounter.get(roomID);
            if (set == null) {
                set = new HashSet<String>();
                occupantsCounter.put(roomID, set);
            }
            if (presence.isAvailable()) {
                occupantAdded = set.add(presenceJID);
            } else {
                String xpath = "/presence/*[name()='x']/*[name()='status']";
                Element status = (Element) presence.getElement().selectSingleNode(xpath);
                if (status == null || !"303".equals(status.attributeValue("code"))) {
                    // Remove the occupant unless the occupant is changing his nickname
                    set.remove(presenceJID);
                }
            }
            // If the presence belongs to an Agent then create/update a track
            // Look for an agent whose JID matches the presence's JID
            String agentJID = null;
            for (Agent agent : getAgents()) {
                if (agent.getAgentJID().toBareJID().equals(presenceJID)) {
                    agentJID = agent.getAgentJID().toBareJID();
                }
            }
            if (agentJID != null) {
                AgentSession agentSession;
                // Update the current chats that the agent is having
                try {
                    agentSession = agentManager.getAgentSession(presenceFullJID);
                    if (agentSession != null) {
                        if (presence.isAvailable()) {
                            if (occupantAdded) {
                                agentSession.addChatInfo(this, sessionID, initialRequest, new java.util.Date());
                                // Trigger the event that an agent has joined a chat session
                                WorkgroupEventDispatcher.agentJoinedChatSupport(this, sessionID, agentSession);
                            }
                        } else {
                            agentSession.removeChatInfo(this, sessionID);
                            // Trigger the event that an agent has left a chat session
                            WorkgroupEventDispatcher.agentLeftChatSupport(this, sessionID, agentSession);
                        }
                    }
                } catch (AgentNotFoundException e) {
                // Do nothing since the AgentSession was not found
                }
                if (presence.isAvailable()) {
                    if (occupantAdded) {
                        // Store in the DB that an agent has joined a room
                        DbWorkgroup.updateJoinedSession(sessionID, agentJID, true);
                    }
                } else {
                    // Store in the DB that an agent has left a room
                    DbWorkgroup.updateJoinedSession(sessionID, agentJID, false);
                }
            } else {
                if (occupantAdded) {
                    // Notify the request that the user has joined a support session
                    initialRequest.supportStarted(roomID);
                }
            }
            if (occupantAdded) {
                initialRequest.userJoinedRoom(new JID(packet.getFrom().toBareJID()), presenceFullJID);
            }
            // If just the user has left the room, just persist the transcript
            boolean isAgent = false;
            try {
                isAgent = agentManager.getAgentSession(presenceFullJID) != null;
            } catch (AgentNotFoundException e) {
            // Ignore.
            }
            if (!((Presence) packet).isAvailable() && !isAgent) {
                // Build the XML for the transcript
                Map<Packet, java.util.Date> map = transcripts.get(roomID);
                StringBuilder buf = new StringBuilder();
                buf.append("<transcript>");
                for (Packet p : map.keySet()) {
                    java.util.Date date = map.get(p);
                    // Add the delay information
                    if (p instanceof Message) {
                        Message storedMessage = (Message) p;
                        Element delay = storedMessage.addChildElement("x", "jabber:x:delay");
                        delay.addAttribute("stamp", UTC_FORMAT.format(date));
                        if (ModelUtil.hasLength(storedMessage.getBody())) {
                            buf.append(p.toXML());
                        }
                    } else {
                        Presence storedPresence = (Presence) p;
                        Element delay = storedPresence.addChildElement("x", "jabber:x:delay");
                        delay.addAttribute("stamp", UTC_FORMAT.format(date));
                        buf.append(p.toXML());
                    }
                // Append an XML representation of the packet to the string buffer
                }
                buf.append("</transcript>");
                // Save the transcript (in XML) to the DB
                DbWorkgroup.updateTranscript(sessionID, buf.toString(), new java.util.Date());
            }
            // the DB and destroy the room
            if (!((Presence) packet).isAvailable() && set.isEmpty()) {
                // Delete the counter of occupants for this room
                occupantsCounter.remove(roomID);
                initialRequest = requests.remove(sessionID);
                if (initialRequest != null && initialRequest.hasJoinedRoom()) {
                    // Notify the request that the support session has finished
                    initialRequest.supportEnded();
                }
                // Build the XML for the transcript
                Map<Packet, java.util.Date> map = transcripts.get(roomID);
                StringBuilder buf = new StringBuilder();
                buf.append("<transcript>");
                for (Packet p : map.keySet()) {
                    java.util.Date date = map.get(p);
                    // Add the delay information
                    if (p instanceof Message) {
                        Message storedMessage = (Message) p;
                        Element delay = storedMessage.addChildElement("x", "jabber:x:delay");
                        delay.addAttribute("stamp", UTC_FORMAT.format(date));
                        if (ModelUtil.hasLength(storedMessage.getBody())) {
                            buf.append(p.toXML());
                        }
                    } else {
                        Presence storedPresence = (Presence) p;
                        Element delay = storedPresence.addChildElement("x", "jabber:x:delay");
                        delay.addAttribute("stamp", UTC_FORMAT.format(date));
                        buf.append(p.toXML());
                    }
                // Append an XML representation of the packet to the string buffer
                }
                buf.append("</transcript>");
                // Save the transcript (in XML) to the DB
                //DbWorkgroup.updateTranscript(sessionID, buf.toString(), new java.util.Date());
                // Leave Chat Room (the room will be destroyed)
                String roomJID = packet.getFrom().toString() + "/" + getJID().getNode();
                LeaveRoom leaveRoom = new LeaveRoom(getFullJID().toString(), roomJID);
                send(leaveRoom);
                // Remove the transcript information of this room since the room no
                // longer exists
                transcripts.remove(roomID);
                // Trigger the event that a chat support has finished
                WorkgroupEventDispatcher.chatSupportFinished(this, sessionID);
            }
            // Invoke the room interceptor after the presence has been processed
            interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, true);
        } else if (packet instanceof Message) {
            // transcript to include things like "room locked"
            if (packet.getFrom().getResource() != null) {
                // Invoke the room interceptor before processing the presence
                interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, false);
                // Add the new message to the list of sent packets
                Map<Packet, java.util.Date> messageList = transcripts.get(roomID);
                if (messageList == null) {
                    messageList = new LinkedHashMap<Packet, java.util.Date>();
                    transcripts.put(roomID, messageList);
                }
                messageList.put(packet.createCopy(), new java.util.Date());
                // Invoke the room interceptor after the presence has been processed
                interceptorManager.invokeInterceptors(getJID().toBareJID(), packet, false, true);
            }
        }
    }
}
Also used : Packet(org.xmpp.packet.Packet) JID(org.xmpp.packet.JID) Message(org.xmpp.packet.Message) LeaveRoom(org.xmpp.muc.LeaveRoom) Element(org.dom4j.Element) RoomInterceptorManager(org.jivesoftware.xmpp.workgroup.interceptor.RoomInterceptorManager) Date(java.sql.Date) LinkedHashMap(java.util.LinkedHashMap) Presence(org.xmpp.packet.Presence) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest)

Example 5 with UserRequest

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

the class RequestQueue method getDetailedStatusPresence.

public Presence getDetailedStatusPresence() {
    Presence queueStatus = new Presence();
    queueStatus.setFrom(address);
    if (workgroup.getStatus() == Workgroup.Status.OPEN && presenceAvailable) {
        queueStatus.setType(null);
    } else {
        queueStatus.setType(Presence.Type.unavailable);
    }
    Element details = queueStatus.addChildElement("notify-queue-details", "http://jabber.org/protocol/workgroup");
    int i = 0;
    for (UserRequest request : getRequests()) {
        Element user = details.addElement("user", "http://jabber.org/protocol/workgroup");
        try {
            user.addAttribute("jid", request.getUserJID().toString());
            // Add Sub-Elements
            Element position = user.addElement("position");
            position.setText(Integer.toString(i));
            Element time = user.addElement("time");
            time.setText(Integer.toString(request.getTimeStatus()));
            Element joinTime = user.addElement("join-time");
            joinTime.setText(UTC_FORMAT.format(request.getCreationTime()));
            i++;
        } catch (Exception e) {
            // Since we are not locking the list of requests while doing this operation (for
            // performance reasons) it is possible that the request got accepted or cancelled
            // thus generating a NPE
            // Remove the request that generated the exception
            details.remove(user);
            // Log an error if the request still belongs to this queue
            if (this.equals(request.getRequestQueue())) {
                Log.error(e.getMessage(), e);
            }
        }
    }
    return queueStatus;
}
Also used : Element(org.dom4j.Element) Presence(org.xmpp.packet.Presence) UserRequest(org.jivesoftware.xmpp.workgroup.request.UserRequest) SQLException(java.sql.SQLException) NotFoundException(org.jivesoftware.util.NotFoundException) GroupNotFoundException(org.jivesoftware.openfire.group.GroupNotFoundException)

Aggregations

UserRequest (org.jivesoftware.xmpp.workgroup.request.UserRequest)9 NotFoundException (org.jivesoftware.util.NotFoundException)5 Element (org.dom4j.Element)4 InterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.InterceptorManager)2 PacketRejectedException (org.jivesoftware.xmpp.workgroup.interceptor.PacketRejectedException)2 QueueInterceptorManager (org.jivesoftware.xmpp.workgroup.interceptor.QueueInterceptorManager)2 Request (org.jivesoftware.xmpp.workgroup.request.Request)2 IQ (org.xmpp.packet.IQ)2 JID (org.xmpp.packet.JID)2 PacketError (org.xmpp.packet.PacketError)2 Presence (org.xmpp.packet.Presence)2 Date (java.sql.Date)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1