(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:
- Creates a new ESB Message instance.
- Decodes the request payload and sets it on the ESB Message using the MessagePayloadProxy class.
- Creates a HttpRequest class to store additional request information and sets it on the ESB Message.
- 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 |
queryParams | A java.util.Map<String, String[]> containing the query parameters. Note the values are String[] so as to support multi valued parameters. |
headers | A 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 |
responseCode | The HTTP Response/Status Code to be set on the gateway response. |
contentType | The response payload MIME Type. |
encoding | The response payload content encoding. |
length | The response payload content length. |
headers | A 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:
- Specify a <http-bus> in the <http-provider> section of the ESB configuration.
- Specify the constraints on the <http-bus>.
- 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 |
No | No | No |
No | Yes | For All Methods |
Yes | Yes | For Specified Methods Only |
Yes | No | 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.
Comments