ru.itx.ccm.beans.EventListener.java Source code

Java tutorial

Introduction

Here is the source code for ru.itx.ccm.beans.EventListener.java

Source

/*
 * Copyright (c) 2010 Eugene Prokopiev <enp@itx.ru>
 *
 * 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 ru.itx.ccm.beans;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.freeswitch.esl.client.IEslEventListener;
import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.transport.event.EslEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EventListener {

    private Logger logger = LoggerFactory.getLogger(getClass());
    private EventManager eventManager;
    private Client client = new Client();
    private Map<String, String> users = new HashMap<String, String>();

    private String host;
    private int port;
    private String password;
    private String domain;
    private String profile;
    private String jobsDirectory;
    private String fifoDirectory;

    public void setHost(String host) {
        this.host = host;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public void setProfile(String profile) {
        this.profile = profile;
    }

    public void setJobsDirectory(String jobsDirectory) {
        this.jobsDirectory = jobsDirectory;
        createDirectory(jobsDirectory);
    }

    public void setFifoDirectory(String fifoDirectory) {
        this.fifoDirectory = fifoDirectory;
        createDirectory(fifoDirectory);
    }

    private void createDirectory(String jobsDirectory) {
        if (jobsDirectory != null && !jobsDirectory.isEmpty())
            new File(jobsDirectory).mkdir();
    }

    public void setEventManager(EventManager eventManager) {
        this.eventManager = eventManager;
    }

    public void init() throws Exception {
        logger.debug("init");
        client.addEventListener(new IEslEventListener() {
            public void eventReceived(EslEvent event) {
                if (event.getEventName().equals("CUSTOM")) {
                    Map<String, String> headers = event.getEventHeaders();
                    String subclass = headers.get("Event-Subclass");
                    if (subclass.equals("sofia::register")) {
                        eventManager.connectSession(headers.get("call-id"), headers.get("from-user"),
                                headers.get("user-agent"), headers.get("network-ip"));
                        client.sendAsyncApiCommand("sofia", "xmlstatus profile " + profile);
                    } else if (subclass.equals("sofia::unregister")) {
                        eventManager.disconnectSession(headers.get("call-id"));
                        client.sendAsyncApiCommand("sofia", "xmlstatus profile " + profile);
                    } else if (subclass.contains("fifo::")) {
                        String action = event.getEventHeaders().get("FIFO-Action");
                        if (action.equals("push")) {
                            eventManager.connectCall(headers.get("Unique-ID"),
                                    headers.get("Caller-Caller-ID-Number"), headers.get("Caller-RDNIS"),
                                    headers.get("FIFO-Name"));
                            client.sendAsyncApiCommand("fifo", "list_verbose " + headers.get("FIFO-Name"));
                        } else if (action.equals("bridge-caller-start")) {
                            eventManager.answerCall(headers.get("Unique-ID"),
                                    headers.get("Other-Leg-Caller-ID-Number"));
                            client.sendAsyncApiCommand("fifo", "list_verbose " + headers.get("FIFO-Name"));
                        } else if (action.equals("bridge-caller-stop")) {
                            eventManager.hangupCall(headers.get("Unique-ID"));
                            client.sendAsyncApiCommand("fifo", "list_verbose " + headers.get("FIFO-Name"));
                        } else if (action.equals("abort")) {
                            eventManager.abortCall(headers.get("Unique-ID"));
                            client.sendAsyncApiCommand("fifo", "list_verbose " + headers.get("FIFO-Name"));
                        } else if (action.equals("post-dial") && !headers.get("result").equals("success")) {
                            eventManager.failCall(headers.get("caller-uuid"),
                                    headers.get("originate_string").split("/")[1].split("@")[0],
                                    headers.get("cause"));
                        }
                    }
                }
            }

            public void backgroundJobResultReceived(EslEvent event) {
                StringBuilder eventBody = new StringBuilder("");
                for (String eventBodyLine : event.getEventBodyLines())
                    eventBody.append(eventBodyLine);
                try {
                    Document document = DocumentHelper.parseText(eventBody.toString());
                    String command = event.getEventHeaders().get("Job-Command") + " "
                            + event.getEventHeaders().get("Job-Command-Arg");
                    if (jobsDirectory != null && !jobsDirectory.isEmpty()) {
                        new File(jobsDirectory + "/" + command).mkdir();
                        OutputFormat format = OutputFormat.createPrettyPrint();
                        Writer writer = new FileWriter(jobsDirectory + "/" + command + "/"
                                + event.getEventHeaders().get("Job-UUID") + ".xml");
                        XMLWriter xmlWriter = new XMLWriter(writer, format);
                        xmlWriter.write(document);
                        xmlWriter.close();
                    }
                    if (command.equals("sofia xmlstatus profile " + profile))
                        processPresence(document);
                    if (command.startsWith("fifo list_verbose"))
                        processFifo(document);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        client.connect(host, port, password, 2);
        client.sendAsyncApiCommand("sofia", "xmlstatus profile " + profile);
        client.setEventSubscriptions("plain", "all");
    }

    private void processPresence(Document document) {
        users.clear();
        for (Node node : (List<Node>) document.selectNodes("/profile/registrations/registration")) {
            String userName = node.valueOf("user").replace("@" + domain, "");
            String userStatus = node.valueOf("agent") + " " + node.valueOf("status").replace("(unknown)", "");
            users.put(userName, userStatus);
        }
    }

    private void processFifo(Document document) throws Exception {
        String fifo = document.selectSingleNode("/fifo_report/fifo").valueOf("@name");
        List<Node> members = document.selectNodes("/fifo_report/fifo/outbound/member");
        List<Node> callers = document.selectNodes("/fifo_report/fifo/callers/caller");
        List<Node> bridges = document.selectNodes("/fifo_report/fifo/bridges/bridge");
        List<String> activeMembers = new ArrayList<String>();
        List<String> connectedMembers = new ArrayList<String>();
        if (fifoDirectory != null && !fifoDirectory.isEmpty()) {
            FileWriter writer = new FileWriter(fifoDirectory + "/" + fifo + ".status");
            for (Node node : callers) {
                writer.append(node.valueOf("@timestamp") + " ");
                writer.append(String.format("%10s", node.valueOf("@caller_id_number")) + "\n");
            }
            for (Node node : bridges) {
                String agent[] = node.valueOf(
                        "consumer/cdr/callflow/caller_profile/originator/originator_caller_profile/chan_name")
                        .replace("sofia/" + profile + "/sip:", "").replace(":5060", "").split("@");
                writer.append(node.valueOf("@bridge_start") + " ");
                writer.append(String.format("%10s", node.valueOf("caller/@caller_id_number")) + " -> ");
                writer.append(
                        agent[0] + " " + ((users.get(agent[0]) == null) ? ("") : (users.get(agent[0]))) + "\n");
                connectedMembers.add(agent[0]);
            }
            for (Node node : members) {
                String member = node.getText().replace("user/", "").replace("@" + domain, "");
                if (!connectedMembers.contains(member)) {
                    writer.append("                                  ");
                    writer.append(member + " " + ((users.get(member) == null) ? ("") : (users.get(member))) + "\n");
                }
                if (users.containsKey(member))
                    activeMembers.add(member);
            }
            writer.append("\n");
            writer.close();
        }
        eventManager.count(fifo, members.size(), activeMembers.size(), callers.size(), bridges.size());
    }

    public void destroy() {
        client.close();
        logger.debug("destroy");
    }
}