HTTP Gateway

(Document Under Construction)

 

 

As it's name suggests, this gateway allows you to expose Message-Unaware HTTP endpoints on JBoss ESB.

 

This gateway uses the JBoss ESB/App Server HTTP Container for exposing HTTP endpoints, so many of the configurations are managed at the container level e.g. bind/port address, SSL etc.

 

Configuration Namespace

This new <http-gateway> configuration is only available through the following config namespace:

 

http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.2.0.xsd

 

Basic Configuration

 

The easiest way to configure the <http-gateway> on a Service is as follows (no provider configuration required):

 

<?xml version="1.0" encoding="UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.2.0.xsd" 
          parameterReloadSecs="5">

    <services>
        <service category="Vehicles" name="Cars" description="" invmScope="GLOBAL">
            <listeners>
                <http-gateway name="Http"/>
            </listeners>
            <actions mep="RequestResponse">
                <!-- Service Aactions.... -->
            </actions>
        </service>
    </services>

</jbossesb>

 

The above configuration uses the “default” HTTP Bus provider since it doesn't define a busrefid attribute.  It uses the Service name to construct the HTTP endpoint address as follows:

 

http://<host>:<port>/<.esbname>/http/Vehicles/Cars

 

The <.esbname> token being the name of the .esb deployment, without the “.esb” extension.  Note also the “http” token in the address.  This is a hardcoded namespace prefix used for all <http-gateway> endpoints.

URL Patterns

The <http-gateway> also supports a urlPattern as follows:

<service category="Vehicles" name="Cars" description="" invmScope="GLOBAL">
    <listeners>
        <http-gateway name="Http" urlPattern="esb-cars/*" />
    </listeners>
    <actions mep="RequestResponse">
        <!-- Service Aactions.... -->
    </actions>
</service>

 

This would expose a HTTP endpoint for the service, capturing all HTTP requests under the following address:

http://<host>:<port>/<.esbname>/http/esb-cars/*

 

Request Handling

This sections contains details regarding how the gateway handles HTTP requests.

 

This gateway receives a HTTP request and from it:

 

  1. Creates a new ESB Message instance.
  2. Decodes the request payload and sets it on the ESB Message using the MessagePayloadProxy class.
  3. Creates a HttpRequest class to store additional request information and sets it on the ESB Message.
  4. Dispatches the ESB Message to the associated Service using the ServiceInvoker class.  See the section on Response Handling for sync/asyn behavior.

 

Payload Decoding

 

The <http-gateway> is typically able to decode a HTTP Request payload based on the request MIME type.  It uses the “core:org.jboss.soa.esb.mime.text.types” configuration property from the jbossesb-properties.xml file to decide whether or not the payload is to be decoded (for the Service) as a String, or simply remain as a Byte array, with the Service handling the decoding itself through an Action.


The “core:org.jboss.soa.esb.mime.text.types” configuration property is a semi-colon separated list of “text” (character) MIME types, with the default set being (note wildcard support):

  • text/*

  • application/xml

  • application/*-xml

 

The <http-gateway> uses the character encoding from the request when decoding text payloads.

 

The <http-gateway> also supports the payloadAs attribute, which can be used as an override for the default MIME type based behavior described above.  With this attribute, you can explicitly tell the gateway to treat the payload as “BYTES” or “STRING”.

 

Request Information

The HTTP Request obviously contains a lot of information (aside from a data payload) that may be required by the Service i.e. not just a request payload (e.g. in the case of  POST).  This information is stored, by the gateway, in a HttpRequest object instance on the Message.  Actions can access it as follows:

 

HttpRequest requestInfo = HttpRequest.getRequest(message);

 

HttpRequest exposes the following set of properties (via getter methods):

 

Property

Description

queryParamsA java.util.Map<String, String[]> containing the query parameters.  Note the values are String[] so as to support multi valued parameters.
headersA java.util.List<HttpHeader> containing the request headers.

authType

The name of the authentication scheme used to protect the endpoint, or null if not authenticated.

Same as the value of the CGI variable AUTH_TYPE.

characterEncoding

The name of the character encoding used in the body of this request, or null if the request does not specify a character encoding.

contentType

Content Type (MIME Type) of the body of the request, or null if the type is not known.  Same as the value of the CGI variable CONTENT_TYPE.

contextPath

The portion of the request URI that indicates the context of the request.  The context path always comes first in a request URI.  The path starts with a "/" character but does not end with a "/" character.  For endpoints in the default (root) context, this returns "".  The container does not decode this string.  (See Servlet Spec)

pathInfo

Any extra path information associated with the URL the client sent when it made this request. The extra path information follows the endpoint path but precedes the query string and will start with a "/" character.

This method returns null if there was no extra path information.

Same as the value of the CGI variable PATH_INFO. (See Servlet Spec)

pathInfoTokens

A List<String> containing the tokens of the pathInfo.

queryString

Query String (See Servlet Spec)

requestURI

The part of this request URL from the protocol name up to the query string. The web container does not decode this String. (See Servlet Spec)

requestPath

The part of this request URL that calls the endpoint. Does not include any additional path information or a query string. Same as the value of the CGI variable SCRIPT_NAME.

This method will return just "http") if the urlPattern was "/*". (See Servlet Spec)

localAddr

The IP address of the interface on which the request  was received.

localName

The host name of the IP interface on which the request was received.

method

HTTP Method

protocol

Name and version of the HTTP protocol

remoteAddr

The IP address of the client or last proxy that sent the request.  Same as the value of the CGI variable REMOTE_ADDR.

remoteHost

The fully qualified name of the client or the last proxy that sent the request. If the engine cannot or chooses not to resolve the hostname (to improve performance), this will be the dotted-string form of the IP address. Same as the value of the CGI variable REMOTE_HOST.

remoteUser

The login of the user making his request, if the user has been authenticated, or null if the user has not been authenticated.  Whether the user name is sent with each subsequent request depends on the client and type of authentication. Same as the value of the CGI variable REMOTE_USER.

contentLength

The length, in bytes, of the request body and made available by the input stream, or -1 if the length is not known. For HTTP servlets, same as the value of the CGI variable CONTENT_LENGTH.

requestSessionId

The session ID specified by the client, or null if non specified.

scheme

Scheme i.e. “http” or “https”.

serverName

The host name of the server to which the request was sent.  It is the value of the part before ":" in the “Host” header value, if any, or the resolved server name, or the server IP address.

 

 

Response Handling

This section contains detail on how the gateway handles HTTP responses.

 

Asynchronous Responses

This gateway always returns a synchronous response to a synchronous HTTP client, so it is never asynchrous in the absolute sense of the word.  By default, this gateway will synchronously invoke the service pipeline, returning the synchronous service response as the HTTP response from the gateway.

 

Asynchronous response behavior, from the point of view of this Gateway, simply means that the gateway returns a synchronous HTTP response after an asynchronous invocation of the action pipeline (i.e. not a synchronous service invocation).  Because it invokes the service asynchronously, it cannot return a service response as part of it's synchronous HTTP response.  Therefore, you need to configure the gateway, telling it how to make the asynchronous response.

 

Asynchronous behavior is configured by adding an <asyncResponse> element to the <http-gateway>, as follows:

 

<listeners>
    <http-gateway name="Http" urlPattern="esb-cars/*">
        <asyncResponse />
    </http-gateway>
</listeners>

 

If configured as above, the gateway will return a zero length HTTP response payload, with a HTTP status of 200 (OK).

 

The asynchronous response HTTP status code can be configured (away from the default of 200) by simply setting the "statusCode" attribute on the <asyncResponse> element:

 

<listeners>
    <http-gateway name="Http" urlPattern="esb-cars/*">
        <asyncResponse statusCode="202" />
    </http-gateway>
</listeners>

 

As stated above, a zero length payload is returned (by default) for asynchronous responses.  This can be overridden by specifying a <payload> element on the <asyncResponse> element:

 

<listeners>
    <http-gateway name="Http" urlPattern="esb-cars/*">
        <asyncResponse statusCode="202">
            <payload classpathResource="/202-static-response.xml"
                     content-type="text/xml"
                     characterEncoding="UTF-8" />
        <asyncResponse>
    </http-gateway>
</listeners>

 

  • classpathResource:  Specifies the path to a file on the classpath that contains the response payload.  Required.
  • contentType:  Specifies the content/mime type of the payload data specified by the classpathResource attribute.  Required.
  • characterEncoding:  The character encoding of the data specified by the classpathResource attribute.  Optional.

Synchronous Responses

By default, this gateway synchronously invokes the associated service and returns the service response payload as the HTTP response.

Response Information

Consistent with how the gateway creates a HttpRequest object instance for the associated Service, the associated Service can create a HttpResponse object for the gateway on a synchronous HTTP gateway invocation.

 

Services (Actions) can create and set a HttpResponse instance on their response message as follows:

 

HttpResponse responseInfo = new HttpResponse(HttpServletResponse.SC_OK);

responseInfo.setContentType("text/xml");
// Set other response info ...

// Set the HttpResponse instance on the ESB response Message instance
responseInfo.setResponse(responseMessage);

 

The HttpResponse object can contain the following properties, which get mapped onto the outgoing HTTP gateway response:

 

Property

Description

responseCodeThe HTTP Response/Status Code to be set on the gateway response.
contentTypeThe response payload MIME Type.

encoding

The response payload content encoding.
lengthThe response payload content length.
headersA java.util.List<HttpHeader> containing the request headers.

 

Using the HttpResponse class works nicely since this class is also used by internal actions such as the HttpRouter, making it easy to perform proxying operations using this gateway.

 

Payload Encoding

The response payload content encoding can be set through the HttpResponse instance (see above).

 

Response Status

The HTTP response status code is set through the HttpResponse instance (see above).

 

Exception to HTTP Status Code Mapping

Service exceptions (Action pipeline exceptions) can be mapped to specific HTTP response codes through the ESB configuration.

 

The mappings can be specified in the top level <http-provider> and can also be specified directly on the <http-gateway>, allowing per-listener override of the exception mappings defined "globally" on the <http-provider>.  The following is an example of an exception mapping made directly on a <http-gateway> configuration:

 

<http-gateway name="http-gateway">
    <exception>
        <mapping class="com.acme.AcmeException" status="503" />
    </exception>
</http-gateway>

 

Configuring exception mappings at the <http-provider> level is exactly the same.

 

You can also configure a mapping file, which is a simple .properties format file containing "{exception-class}={http-status-code}" mappings.  The file is looked up on the classpath, so should be bundled inside your .esb deployment.  It is configured as follows (this time on the <http-provider>):

 

<http-provider name="http">

    <!-- Global exception mappings file... -->
    <exception mappingsFile="/http-exception-mappings.properties" />
</http-provider>

 

Response Timeout

By default, this gateway will wait for 30,000 ms (30 s) for the synchronous service invocation to complete, before raising a ResponseTimeoutException.  To override the default timeout, you need to confgure the "synchronousTimeout" property:

 

<listeners>
    <http-gateway name="Http" urlPattern="esb-cars/*">
        <property name="synchronousTimeout" value="120000"/>
    </http-gateway>
</listeners>

 

Security

To configure security constraints, one must add configurations to the <http-provider> section of the ESB configuration i.e. this can not be done directly on the <http-gateway> configuration.

 

So the process of securing a <http-gateway> is as follows:

 

  1. Specify a <http-bus> in the <http-provider> section of the ESB configuration.
  2. Specify the constraints on the <http-bus>.
  3. Refence the <http-bus> from the <http-listener> using the "busrefid" attribute.

 

(See the "http-gateway" Quickstart for a full config example)

 

Protected Methods & Allowed User Roles

Logins can be enforced for an endpoint using the <protected-methods> and <allowed-roles> sections of a <http-bus> configuration as follows:

 

<http-bus busid="secureSalesDeletes">
    <allowed-roles>
        <role name="friend" />
    </allowed-roles>
    <protected-methods>
        <method name="DELETE" />
    </protected-methods>
</http-bus>

 

The above configuration stipulates that a valid "friend" login is required for DELETE requests made on the "secureSalesDeletes" bus.  The following login matrix tries to illustrate which configurations will enforce a login, and when.

 

Methods

Specified

Roles

Specified

Login

Required

NoNo  No
NoYes

  For All Methods

YesYes

  For Specified Methods Only

YesNo

  No - Specified Methods blocked to all

 

Authentication Method and Security Domain

The authentication method and security domain can be configured on the <http-provider> configuration as follows (i.e. cannot be configured on a per <http-bus> basis):

 

<http-provider name="http">
    <http-bus busid="secureFriends">
        <allowed-roles>
            <role name="friend" />
        </allowed-roles>
        <protected-methods>
            <method name="DELETE" />
        </protected-methods>
    </http-bus>

    <auth method="BASIC" domain="java:/jaas/JBossWS" />
</http-provider>

 

The method attribute can be one of "BASIC" (default), "CLIENT-CERT" and "DIGEST".

 

The security domain is configured within your AS/ESB Server in the normal way.

Transport Guarantee

HTTP Transport Guarantee can be configured on a per <http-bus> basis by simply specifying it on the bus using the "transportGuarantee" attribute.

 

<http-bus busid="secureFriends" transportGuarantee="CONFIDENTIAL">
    <!-- etc etc -->
</http-bus>

 

Allowed values for transportGuarantee are "CONFIDENTIAL", "INTEGRAL" and "NONE".

 

Integration with ESB Security

TODO!!

 

SSL/HTTPS

As per JBoss AS Container.