Version 7

    If you tried JBRGatewayListener in JBossESB, you may find you cannot configure two ESB services to share the same http port . When there are multiple services which need to be configured with JBRGatewayLister to support access through http protocol, it will occupy many port numbers. I wrote a new HttpGatewayListener based  on tomcat(JBossWeb) to support multiple services on one port (so far it is in esb branch http://anonsvn.jboss.org/repos/labs/labs/jbossesb/workspace/mlittle/legstar/) . It also provides more configuration to support HTTP OPTIONS and TRACE method, BASIC http authentication and definition of allowed http methods type .  Here I described how to configure and enable these functions :

    1.multiple services share one port

    This function enable multiple services to share one port, accepting ESB service request through http . Each HttpGatewayListener is configured with a different context name. This context name, along with host name and port number, identifies the ESB service.

    This is a sample configuration file to demonstrate the two services sharing the same port number :

    <?xml version = "1.0" encoding = "UTF-8"?> 
    <jbossesb
    xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
    parameterReloadSecs="5"> 
        <providers> 
              <jms-provider name="JBossMQ" connection-factory="ConnectionFactory"> 
                  <jms-bus busid="quickstartEsbChannel"> 
                      <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_httpgateway_Request_esb" /> 
                  </jms-bus> 
                  <jms-bus busid="quickstartEsbChannel1"> 
                      <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_httpgateway_Request_esb1" /> 
                  </jms-bus> 
              </jms-provider>   
              
             <http-provider name="HTTP" host="localhost" port="8765"> 
                <http-bus busid="HTTP-1" context="/jbossesb/httpgateway/serviceA"/> 
                <http-bus busid="HTTP-2" context="/jbossesb/httpgateway/serviceB"/> 
             </http-provider> 
          </providers> 
                          
          <services> 
            <service category="httpgateway" name="serviceA" description="Hello WorldA"> 
                <listeners>                
                    <http-listener name="A1-HTTP" busidref="HTTP-1" maxThreads="100"  is-gateway="true"/>      
                    <jms-listener name="JMS-Gateway" busidref="quickstartEsbChannel" />    
                </listeners> 
                <actions mep="RequestResponse"> 
                      
    <action name="action1"
    class="org.jboss.soa.esb.samples.quickstart.httpgateway.MyAction"
    process="displayMessage" />                       
                </actions> 
            </service> 
    
            <service category="httpgateway" name="serviceB" description="Hello WorldB"> 
                <listeners>                
                    <http-listener name="A2-HTTP"  busidref="HTTP-2" maxThreads="10" is-gateway="true"/> 
                    <jms-listener name="JMS-Gateway1" busidref="quickstartEsbChannel1" />    
                </listeners> 
                <actions mep="RequestResponse"> 
                      
    <action name="action1"
    class="org.jboss.soa.esb.samples.quickstart.httpgateway.MyAction2"
    process="displayMessage" />                       
                </actions> 
            </service>
          </services> 
    </jbossesb>
    

    In this sample “serviceA” can be accessed through “ http://localhost:8765/jbossesb/httpgateway/serviceA/” and “ServiceB” can be accessed through  “ http://localhost:8765/jbossesb/httpgateway/serviceB/” .   Please note that the request url for each service ends with a slash . This is because the context attribute configured in <http-bus> element equates to a J2EE web context . You need to use “http://localhost:8080/context/” to request the default servlet under that context. The request for “http://localhost:8080/context” will be automatically redirected to “http://localhost:8080/context/” by  tomcat engine.

    After this sample is deployed,  a new Tomcat Engine and other related artifacts are created and  registered into JMX server. You can open “http://localhost:8080/jmx-console” to check out.

    jboss.esb.tomcat

    2.Support POST, GET, PUT ,DELETE ,  OPTIONS and TRACE Http methods

    Tomcat/JBoss Web supports http methods PUT,GET,POST,DELETE, OPTIONS and TRACE well. Since the HttpGatewayListener is based on Tomcat, It inherits these features  and easily supports all these http  methods.  That means all these http method requests can be handled by HttpGatewayListener.  Except for TRACE method which is enabled by configuration, other methods are enabled by default :

    <http-provider name="HTTP" host="localhost" port="8765"> 
      <property name="allowTrace" value="true"/> 
    </http-provider>
    

    Sometimes we need to restrict PUT or DELETE request access like the normal Servlet does : reply with unsupported error message in doDelete or doGet methods.  There is also a property to configure specific http methods you want to allow:

    <http-provider name="HTTP" host="localhost" port="8765">
      <http-bus busid="HTTP-1" context="/jbossesb/httpgateway/serviceA">
        <property name=”allowHttpMethod” value=”POST, GET, PUT,DELETE”/>
      </http-bus >
    </http-provider> 
    

    If “allowHttpMethod” property is not defined, HttpGatewayListener  will allow GET and POST request by default.

    3.Provides more configurations to  enable SSL , Proxy , Http1.1/1.0 support and performance tuning

    There are many attributes that can be configured to Tomcat Connector to enable SSL, Proxy,  Http1.1/1.0 support and set thread number. HttpGatewayListener inherits these attributes too .  HttpGatewayListener converts these attributes to properties and uses them to customize the http transport.  Here is an example showing how to enable the SSL for a HttpGatewayListener:

    <http-provider name="HTTP" host="localhost" port="8765">
          <property name="scheme" value="https"/>
          <property name="secure" value="true"/>
          <property name="SSLEnabled" value="true"/>
          <property name="Keystore" value="./key/.keystore"/>
          <property name="Keypass" value="changeit"/>
    </http-provider>
    


    Configure maxSpareThreads, minSpaceTherad, maxTherads properties  to get better performance:

    <http-provider name="HTTP" host="localhost" port="8765"> 
       <property name="maxThreads" value="50"/> 
        <property name="maxSpareThreads" value="10"/> 
       <property name="minSpareThreads" value="2"/> 
    </http-provider>
    


    All the attributes listed on this  page http://tomcat.apache.org/tomcat-5.5-doc/config/http.html  to configure the Tomcat connector can be used as property names to  configure  <http-provider>  for customizing your HttpGatewayListener.   

    4. Pass query string into ESB service

    HttpGatewayListener is able to pass the query string into ESB service. When we use Get request to access an ESB service “http://localhost:8080/context/?a=3&b=4” , the query string “a=3&b=4” will be parsed and put in parameter maps , it can be retrieved with the following codes :

            Object obj = message.getProperties().getProperty("RequestParameterMap"); 
            if (obj != null) { 
                Map<String, Object> paraMap = (Map<String, Object>)obj; 
                for(Map.Entry<String, Object> entry : paraMap.entrySet()) { 
                  System.out.println(entry.getKey() + " : " + entry.getValue()); 
               } 
            }    
    

    The http request header and other request information will be combined into a RequestInfoMap and put into ESB message properties. With these codes :

    Map<String, Object> requestInfo = (Map<String, Object>)message.getProperties().getProperty("RequestInfoMap");
    for(Map.Entry<String, Object> entry : requestInfo.entrySet()) {
      System.out.println(entry.getKey() + " : " + entry.getValue());
    } 
    

    The  GET request for “https://localhost:8765/jbossesb/httpgateway/serviceA/?a=3&b=4”.  information will be traced as shown in the following snapshot:

    htt-request-info.jpg

    As you see, HttpGatewayListener will parse the http request and compose RequestInfoMap and RequestParameterMap. Http request body payload will be put into ESB message body.

    5.Basic http authentication

    Http Basic authentication can also be applied to HttpGatewayListener and it is  integrated with JBossSX extension framework. That means HttpGatewayListener can be configured with security domain defined in ${JBossAS_HOME} /server/default/conf/login-config.xml like the security-domain  configured in jboss-web.xml for web content security. The following is the configuration example to enable http basic authentication:

    <http-provider name="HTTP" host="localhost" port="8765">
       <http-bus busid="HTTP-2" context="/jbossesb/httpgateway/serviceB">
           <property name="authMethod" value="BASIC"/>
           <property name="securityDomain" value="java:/jaas/messaging"/>
           <property name="securityRole" value="esbrole"/>
       </http-bus>
    </http-provider>   
    

    The authMethod property is  to define which http access authentication method to use. So far it only supports BASIC authentication.  The “securityDomain” is to define the policy name defined in login-config.xml to authenticate user . Property “securityRole” is to define the role  name to access this ESB service through HttpGatewayListene