Package jade.mtp.http

Source Code of jade.mtp.http.MessageTransportProtocol

/*****************************************************************
* JADE - Java Agent DEvelopment Framework is a framework to develop
* multi-agent systems in compliance with the FIPA specifications.
* Copyright (C) 2000 CSELT S.p.A.
*
* The updating of this file to JADE 2.0 has been partially supported by the
* IST-1999-10211 LEAP Project
*
* This file refers to parts of the FIPA 99/00 Agent Message Transport
* Implementation Copyright (C) 2000, Laboratoire d'Intelligence
* Artificielle, Ecole Polytechnique Federale de Lausanne
*
* GNU Lesser General Public License
*
* This library is free software; you can redistribute it sand/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation,
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA  02111-1307, USA.
*****************************************************************/

/**
* MessageTransportProtocol.java
*
*
* @author Jose Antonio Exposito
* @author MARISM-A Development group ( marisma-info@ccd.uab.es )
* @version 0.1
* @author Nicolas Lhuillier (Motorola Labs)
* @version 1.0
*/


package jade.mtp.http;

import java.net.*;
import java.io.*;
import java.util.Hashtable;
import java.util.Enumeration;

import jade.mtp.InChannel;
import jade.mtp.MTP;
import jade.mtp.MTPException;
import jade.mtp.TransportAddress;
import jade.domain.FIPAAgentManagement.Envelope;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.util.ExtendedProperties;

public class MessageTransportProtocol implements MTP {
 
  // DEFAULT VALUES
  private static final int    IN_PORT    = 7778;
  private static final String OUT_PORT   = "-1";
  private static final String PROXY_PORT = "1080";
  private static final String MAX_KA     = "10";
  private static final String POLICY     = "conservative"; //conservative or aggressive
  private static final String PREFIX     = "jade_mtp_http_";
  private static final String TIMEOUT    = "60000"; // 60 seconds
 
  private int    numKA;
  private String proxyHost;
  private int    proxyPort;
  private int    timeout;
  //private int    proxyKATimeout;
  private boolean policy;
  private boolean keepAlive  = false;
  private boolean useProxy   = false;
 
  private String[] protocols = {};
  private String FIPA_NAME = "fipa.mts.mtp.http.std";
  private Hashtable addr2srv = new Hashtable();
 
  //Object Keep-Alive connections
  private KeepAlive ka;
 
 
  /** MTP Interface Methods */
  public TransportAddress strToAddr(String rep) throws MTPException {
    try {
      return new HTTPAddress(rep);
    } catch(MalformedURLException mue) {
      throw new MTPException("Address mismatch: this is not a valid HTTP address.");
    }
  }
 
  public String addrToStr(TransportAddress ta) throws MTPException {
    try {
      return ((HTTPAddress) ta).toString();
    } catch(Exception e) {
      throw new MTPException(e.toString());
    }
  }
 
  public String getName() {
    return FIPA_NAME;
  }
 
  public String[] getSupportedProtocols() {
    return protocols;
  }
 
  /********************************
   *   InChannel Interface Methods *
   *********************************/
 
  /**
   * Old method, only for compliance with former versions (prior 3.0)
   */
  public TransportAddress activate(InChannel.Dispatcher disp)
  throws MTPException {
    try {
      return activate(disp,new ProfileImpl(new ExtendedProperties()));
    } catch(Exception e) {
      throw new MTPException(e.getMessage());
    }
  }
 
  public void activate(InChannel.Dispatcher disp, TransportAddress ta)
  throws MTPException {
    try {
      activate(disp,ta,new ProfileImpl(new ExtendedProperties()));
    } catch(Exception e) {
      throw new MTPException(e.getMessage());
    }
  }
 
  public TransportAddress activate(InChannel.Dispatcher disp, Profile p)
  throws MTPException {
    //Active the new HTTPAddress
    return activateServer(disp,null,p);
  }
 
  /**
   * Actual method to activate the HTTP MTP.
   *
   * Customizable parameters read from profile:<UL>
   * <LI><B>port</B>: the port this HTTP server listens to.</LI>
   * <LI><B>numKeepAlive</B>: Maximum number of keep-alive connections.
   * Default value is 10. Set to 0 to disable keep-alive coonections (possible performance impact).</LI>
   * <LI><B>proxyHost</B>: Proxy host name or IP-address. No default value.</LI>
   * <LI><B>proxyPort</B>: Default value is 1080.</LI>
   * <LI><B>outPort</B>: Fix port to be used by HTTP client (for firewall configuration).
   * Default value is freely chosen by Java</LI>
   * <LI><B>parser</B>: XML SAX2 parser implementation to use.
   * Default value is JDK 1.4 default parser.</LI>
   * <LI><B>policy</B>: "conservative" (default value) or "aggressive".
   * (see documentation for details).</LI>
   * <LI><B>timeout</B>: Timeout for keep-alive connections. Default value is 1 min.
   * 0 means infinite.</LI>
   * </UL>
   * Note that all these parameters must be prefixed with "jade_mtp_http_".
   */
  public void activate(InChannel.Dispatcher disp, TransportAddress ta, Profile p) throws MTPException {
    activateServer(disp, ta, p);
  }
 
  private TransportAddress activateServer(InChannel.Dispatcher disp, TransportAddress ta, Profile p) throws MTPException {
    //Comprobation of correct HTTPAddress
    int port = -1;
    boolean changePortIfBusy = false;
    String saxClass = null;
    HTTPAddress hta = null;
    try {
      if (ta != null) {
        hta = (HTTPAddress)ta;
      } else {
        try {
          // Create default HTTPAddress
          String tmp;
          if ((tmp = p.getParameter(PREFIX+"port",null)) != null) {
            port = Integer.parseInt(tmp);
          } else {
            // Use default port
            port = IN_PORT;
            changePortIfBusy = true;
          }
          //#DOTNET_EXCLUDE_BEGIN
          hta = new HTTPAddress(InetAddress.getLocalHost().getCanonicalHostName(),port, false);
          //#DOTNET_EXCLUDE_END
          /*#DOTNET_INCLUDE_BEGIN
          hta = new HTTPAddress(InetAddress.getLocalHost().getHostName(),port, false);
          #DOTNET_INCLUDE_END*/
        } catch( UnknownHostException ukhexc ) {
          throw new MTPException("Cannot activate MTP on default address: Unknown Host");
        } catch( MalformedURLException mexc ) {
          throw new MTPException("Cannot activate MTP on default address: Malformed URL");
        } catch( NumberFormatException nfexc ) {
          throw new MTPException("Cannot activate MTP on default address: Invalid port");
        }
      }
      port = hta.getPortNo();
      if((port <= 0) || (port > 65535)) {
        throw new MTPException("Invalid port number "+ta.getPort());
      }
     
      // Parse other profile parameters
      numKA     = Integer.parseInt(p.getParameter(PREFIX+"numKeepAlive",MAX_KA));
      policy    = (p.getParameter(PREFIX+"policy",POLICY).equals("aggressive"))?true:false;
      int outPort   = Integer.parseInt(p.getParameter(PREFIX+"outPort",OUT_PORT));
      ka = new KeepAlive(numKA, outPort, policy);
      keepAlive = numKA > 0;
      proxyHost = p.getParameter(PREFIX+"proxyHost",null);
      if (proxyHost != null) {
        useProxy = true;
        proxyPort = Integer.parseInt(p.getParameter(PREFIX+"proxyPort",PROXY_PORT));
      }
      saxClass = p.getParameter(PREFIX+"parser",null);
     
      timeout = Integer.parseInt(p.getParameter(PREFIX+"timeout",TIMEOUT));
     
      //#PJAVA_EXCLUDE_BEGIN
      try{
        HTTPSocketFactory.getInstance().configure(p, hta);
      } catch(Exception e){
        throw new MTPException("Error configuring Socket Factory", e);
      }
      //#PJAVA_EXCLUDE_END
      // System.out.println("Parameters set:");
      // System.out.println("- KA "+numKA);
      // System.out.println("- Policy "+policy);
      // System.out.println("- Out port "+outPort);
      // System.out.println("- Proxy host "+proxyHost);
      // System.out.println("- Proxy port "+proxyPort);
      // System.out.println("- Parser "+saxClass);
      // System.out.println("- Timeout "+timeout);
    } catch (ClassCastException cce) {
      throw new MTPException("User supplied transport address not supported.");
    } catch( NumberFormatException nexc ) {
      throw new MTPException(nexc.getMessage());
    }
   
    //Creation of the Server
    try {
      //Create object server
      HTTPServer srv = new HTTPServer(port,disp,numKA,saxClass,timeout, changePortIfBusy);
      int actualPort = srv.getLocalPort();
      if (actualPort != port) {
        // The selected port is busy and a new one was selected --> Update the transport address
        boolean useHttps = "https".equalsIgnoreCase(hta.getProto());
        //#DOTNET_EXCLUDE_BEGIN
        hta = new HTTPAddress(InetAddress.getLocalHost().getCanonicalHostName(),actualPort, useHttps);
        //#DOTNET_EXCLUDE_END
        /*#DOTNET_INCLUDE_BEGIN
        hta = new HTTPAddress(InetAddress.getLocalHost().getHostName(),actualPort, useHttps);
        #DOTNET_INCLUDE_END*/
      }
      //Save the reference to HTTPServer
      addr2srv.put(hta.toString(),srv);
      //Execute server
      srv.start();
      protocols = new String[]{hta.getProto()};
      return hta;
    } catch( Exception e ) {
      throw new MTPException("While activating MTP got exception "+e);
    }
  }
 
  public void deactivate(TransportAddress ta) throws MTPException {
    // Shutdown HTTP Server
    HTTPServer srv = (HTTPServer)addr2srv.get(ta.toString());
    if( srv != null ) {
      addr2srv.remove(ta.toString());
      srv.desactivate();
      //srv.interrupt();
    } else
      throw new MTPException("No server on address "+ta);
  }
 
  public void deactivate() throws MTPException {
    for(Enumeration it=addr2srv.keys(); it.hasMoreElements() ; ) {
      TransportAddress ta=(TransportAddress)it.nextElement();
      deactivate(ta);
    }
   
  }
 
 
  /********************************
   *  OutChannel Interface Methods *
   *********************************/
 
  public void deliver(String addr, Envelope env, byte[] payload) throws MTPException {
    HTTPAddress url;
    byte[] request;
   
    try {
     
      HTTPAddress host = new HTTPAddress(addr);
      if (useProxy) {
        url = new HTTPAddress(proxyHost,proxyPort,false); //false=>do_not_use HTTPS with the proxy
      } else {
        url = host;
      }
      String connPol = (keepAlive)?HTTPIO.KA:HTTPIO.CLOSE;
     
      // Prepare the HTTP request
      // ------------------------
      //Calculate the value of boundary
      StringBuffer boundary = new StringBuffer();
      for( int i=0 ; i < 31 ; i++ ) {
        boundary.append(Integer.toString((int)Math.round(Math.random()*15),16));
      }
     
      //Request body
      //String body = HTTPIO.createHTTPBody(env,boundary.toString(),new String(payload));
      byte[] boundaryBytes = boundary.toString().getBytes("ISO-8859-1");
      byte[] body = HTTPIO.createHTTPBody(env,boundaryBytes,payload);
     
      //HTTP header
      //StringBuffer req = HTTPIO.createHTTPHeader(host,body.length(),connPol,boundary.toString(),useProxy);
      byte[] header = HTTPIO.createHTTPHeader(host,body.length,connPol,boundaryBytes,useProxy);
      // Concatenate header + body
      //req.append(body);
      ByteArrayOutputStream requestStream = new ByteArrayOutputStream(header.length + body.length);
      requestStream.write(header);
      requestStream.write(body);
      requestStream.flush();
      requestStream.close();
      request = requestStream.toByteArray();
     
    } catch (Exception e) {
      throw new MTPException(e.getMessage());
    }
    ka.send(url, request);
  }
 
 
} // End of MessageTransportProtocol class
TOP

Related Classes of jade.mtp.http.MessageTransportProtocol

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.