Package com.almende.eve.transport.xmpp

Source Code of com.almende.eve.transport.xmpp.AgentConnection$JSONRPCListener

/*
* Copyright: Almende B.V. (2014), Rotterdam, The Netherlands
* License: The Apache Software License, Version 2.0
*/
package com.almende.eve.transport.xmpp;

import java.io.IOException;
import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;

import com.almende.eve.agent.AgentHost;

/**
* @author Almende
*
*/
/**
* The Class AgentConnection.
*/
public class AgentConnection {
 
  private static final Logger  LOG      = Logger.getLogger(AgentConnection.class
                          .getCanonicalName());
  private AgentHost      agentHost  = null;
  private String        agentId    = null;
  private String        username  = null;
  private String        host    = null;
  private String        resource  = null;
  private String        password  = null;
  private String        serviceName  = null;
  private Integer        port    = 5222;
  private XMPPConnection    conn    = null;
 
  /**
   * Instantiates a new agent connection.
   *
   * @param agentHost
   *            the agent host
   */
  public AgentConnection(final AgentHost agentHost) {
    this.agentHost = agentHost;
  }
 
  /**
   * Get the id of the agent linked to this connection.
   *
   * @return agentId
   */
  public String getAgentId() {
    return agentId;
  }
 
  /**
   * Get the username of the connection (without host).
   *
   * @return username
   */
  public String getUsername() {
    return username;
  }
 
  /**
   * Get the resource of the connection. Returns null if no resource is set
   *
   * @return resource
   */
  public String getResource() {
    return resource;
  }
 
  /**
   * Connect.
   *
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
  public void connect() throws IOException {
    connect(agentId, host, port, serviceName, username, password, resource);
  }
 
  /**
   * Login and connect the agent to the messaging service.
   *
   * @param agentId
   *            the agent id
   * @param host
   *            the host
   * @param port
   *            the port
   * @param serviceName
   *            the service name
   * @param username
   *            the username
   * @param password
   *            the password
   * @param resource
   *            optional
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
  public void connect(final String agentId, final String host,
      final Integer port, final String serviceName,
      final String username, final String password, final String resource)
      throws IOException {
   
    if (isConnected()) {
      // this is a reconnect.
      disconnect();
    }
    this.agentId = agentId;
    this.username = username;
    this.resource = resource;
    this.host = host;
    this.port = port;
    this.serviceName = serviceName;
    this.password = password;
   
    try {
      // configure and connect
      final ConnectionConfiguration connConfig = new ConnectionConfiguration(
          host, port, serviceName);
     
      connConfig.setSASLAuthenticationEnabled(true);
      connConfig.setReconnectionAllowed(true);
      connConfig.setCompressionEnabled(true);
      connConfig.setRosterLoadedAtLogin(false);
      conn = new XMPPConnection(connConfig);
      conn.connect();
     
      // login
      if (resource == null) {
        conn.login(username, password);
      } else {
        conn.login(username, password, resource);
      }
     
      // set presence to available
      final Presence presence = new Presence(Presence.Type.available);
      conn.sendPacket(presence);
     
      // set acceptance to all
      conn.getRoster().setSubscriptionMode(
          Roster.SubscriptionMode.accept_all);
     
      // instantiate a packet listener
      conn.addPacketListener(new JSONRPCListener(agentHost, agentId,
          resource), null);
     
    } catch (final XMPPException e) {
      LOG.log(Level.WARNING, "", e);
      throw new IOException("Failed to connect to messenger", e);
    }
  }
 
  /**
   * Disconnect the agent from the messaging service.
   */
  public void disconnect() {
    if (isConnected()) {
      conn.disconnect();
      conn = null;
    }
  }
 
  /**
   * Check whether the agent is connected to the messaging service.
   *
   * @return connected
   */
  public boolean isConnected() {
    return (conn != null) ? conn.isConnected() : false;
  }
 
  /**
   * Send a message to an other agent.
   *
   * @param username
   *            the username
   * @param message
   *            the message
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
  public void send(final String username, final String message)
      throws IOException {
    if (!isConnected()) {
      disconnect();
      connect();
    }
    if (isConnected()) {
     
      // send the message
      final Message reply = new Message();
      reply.setTo(username);
      reply.setBody(message);
      conn.sendPacket(reply);
    } else {
      throw new IOException("Cannot send request, not connected");
    }
  }
 
  /**
   * A class to listen for incoming JSON-RPC messages.
   * The listener will invoke the JSON-RPC message on the agent and
   * reply the result.
   *
   * @see JSONRPCEvent
   */
  private static class JSONRPCListener implements PacketListener {
    private AgentHost  host    = null;
    private String    agentId    = null;
    private String    resource  = null;
   
    /**
     * Instantiates a new jSONRPC listener.
     *
     * @param agentHost
     *            the agent host
     * @param agentId
     *            the agent id
     * @param resource
     *            the resource
     */
    public JSONRPCListener(final AgentHost agentHost, final String agentId,
        final String resource) {
      host = agentHost;
      this.agentId = agentId;
      this.resource = resource;
    }
   
    /**
     * process an incoming xmpp message.
     * If the message contains a valid JSON-RPC request or response,
     * the message will be processed.
     *
     * @param packet
     *            the packet
     */
    @Override
    public void processPacket(final Packet packet) {
      final Message message = (Message) packet;
     
      // Check if resource is given and matches local resource. If not
      // equal, silently drop packet.
      final String to = message.getTo();
      if (resource != null && to != null) {
        final int index = to.indexOf('/');
        if (index > 0) {
          final String res = to.substring(index + 1);
          if (!resource.equals(res)) {
            LOG.warning("Received stanza meant for another agent, disregarding. "
                + res);
            return;
          }
        }
      }
      final String body = message.getBody();
      final URI senderUrl = URI.create("xmpp:" + message.getFrom());
     
      if (body != null) {
        try {
          host.receive(agentId, body, senderUrl, null);
        } catch (final IOException e) {
          LOG.log(Level.WARNING,
              "Host threw an IOException, probably agent '"
                  + agentId + "' doesn't exist? ", e);
          return;
        }
      }
    }
  }
 
  /**
   * Checks if is available.
   *
   * @param receiver
   *            the receiver
   * @return true, if is available
   */
  public boolean isAvailable(String receiver) {
    // split url (xmpp:user/resource) into parts
    if (receiver.startsWith("xmpp:")) {
      receiver = receiver.substring(5, receiver.length());
    }
    final int slash = receiver.indexOf('/');
    if (slash <= 0) {
      return false;
    }
    final String res = receiver.substring(slash + 1, receiver.length());
    final String user = receiver.substring(0, slash);
   
    final Roster roster = conn.getRoster();
   
    final org.jivesoftware.smack.RosterEntry re = roster.getEntry(user);
    if (re == null) {
      LOG.info("subscribing to " + receiver);
      final Presence subscribe = new Presence(Presence.Type.subscribe);
      subscribe.setTo(receiver);
      conn.sendPacket(subscribe);
    }
   
    final Presence p = roster.getPresenceResource(user + "/" + res);
    LOG.info("Presence for " + user + "/" + res + " : " + p.getType());
    if (p.isAvailable()) {
      return true;
    }
    return false;
  }
}
TOP

Related Classes of com.almende.eve.transport.xmpp.AgentConnection$JSONRPCListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.