The HTTP resource adaptor provides a generic HTTP interface for SLEE services, supporting the Hypertext Transfer Protocol (HTTP) as specified in RFC1945 and RFC2616.

The resource adaptor

  • is bidirectional; applications can receive incoming HTTP requests and also initiate outgoing HTTP requests

  • implements a subset of HTTP/1.1 (request methods GET, HEAD, POST, PUT and DELETE)

  • supports incoming and outgoing HTTPS.

  • Integrates with Metaswitch Service Assurance Server (SAS)

Topics

Configuring the resource adaptor

configure the resource adaptor using profiles and properties

Events and Activities

use event types, activities, ACI and SBB interfaces

SAS Tracing

Metaswitch Service Assurance Server integration

Running the example HTTP service

install and run the example service included with the HTTP Resource Adaptor

Other documentation for the HTTP Resource Adaptor can be found on the HTTP Resource Adaptor product page.

Notices

Copyright © 2022 Microsoft. All rights reserved

This manual is issued on a controlled basis to a specific person on the understanding that no part of the Metaswitch Networks product code or documentation (including this manual) will be copied or distributed without prior agreement in writing from Metaswitch Networks.

Metaswitch Networks reserves the right to, without notice, modify or revise all or part of this document and/or change product features or specifications and shall not be responsible for any loss, cost, or damage, including consequential damage, caused by reliance on these materials.

Metaswitch and the Metaswitch logo are trademarks of Metaswitch Networks. Other brands and products referenced herein are the trademarks or registered trademarks of their respective holders.

Configuring the HTTP Resource Adaptor

Below are properties for configuring the HTTP resource adaptor (from the HTTP API), including properties for secure configuration.

Name Type Default Description

ListenAddress

String

127.0.0.1

Local IP address that the HTTP resource adaptor will listen on for requests.

ListenPort

Integer

8000

Local TCP port that the HTTP resource adaptor will listen on for requests.

BindAddresses

String

Contains per-node configuration information regarding each node’s specified local IP address and local TCP port that the HTTP resource adaptor will listen on for requests. If BindAddresses is empty, ListenAddress and ListenPort will be employed. For syntax see Specifying bind addresses.

MaxOutgoingConnections

Integer

30

The maximum number of outgoing TCP connections the resource adaptor will open to a single host when sending requests to that host.

OutgoingRequestTimeout

Long

10000

The time (in ms) that the resource adaptor will wait for a response to an outgoing request before failing the request. The application will see a 500 Server Error response and in case of asynchronous request, activity will end.

OutgoingIdleTimeout

Long

60000

The time (in ms) that the resource adaptor will keep an outgoing TCP connection open for, with no activity on the connection.

MaxDepth

Integer

1

Controls how many HTTP requests may be queued up on a single connection without receiving a response from the server. This is known as "HTTP pipelining". A value of 1 is strongly recommended if the server does not support non-persistent connections. When the connection closes (which it always will if they are non-persistent) the other requests in the pipeline will have to be re-sent on another connection. A value of 1 is also recommended for slow or unreliable servers, to avoid head-of-line blocking.

QueueTimeout

Long

5000

The time (in ms) that a request can be held on the queue waiting for an outgoing connection before timing out and firing an event with response code 500 and reason "Timed out waiting for server connection".

NewConnectionDelay

Long

100

When a burst of (send) requests occurs, the resource adaptor queues them, and only creates new connections if they cannot be sent on existing connections. NewConnectionDelay is the time in milliseconds that the resource adaptor will wait for an outgoing connection to become available before creating a new one. If the server does not support persistent connections, it is strongly recommended that this value be set to 0.

IncomingRequestTimeout

Long

5000

The time (in ms) that the resource adaptor will wait for the SLEE to send a response to an incoming request before failing the request. The resource adaptor will automatically send an error response to the client and end the activity.

IncomingIdleTimeout

Long

60000

The time (in ms) that the resource adaptor will keep an incoming TCP connection open for, with no activity on the connection.

ServerName

String

Rhino-HTTP-Server/2.2

The default value of the Server header set in outgoing responses. Applications may override this by setting the Server header in the response manually.

UserAgent

String

Rhino-HTTP-Client/2.2

The default value of the User-Agent header set in outgoing requests. Applications may override this by setting the User-Agent header in the request manually.

AddressType

String

null

Defines how the resource adaptor generates the javax.slee.Address object for HTTP events. Default is to not use any address. Setting this to the value uripath will make the resource adaptor use a URI address with the value of the path in the request URL. For example, http://localhost/test/zzz?query=yyy will create an address with address plan AddressPlan.URI and value "/test/zzz". Responses have no address.

MaxContentLength

Integer

1048576

Maximum value in bytes for the Content-Length header of the HTTP messages which have a message body. If this value is exceeded, the application will see a 413 Client Error Response. MaxContentLength value update will apply to new connections.

WorkerCount

Integer

0

The number of workers used by the server and client worker executors. 0 means use Netty default: 2 * untime.availableProcessors()

AutomaticContentCompression

Boolean

false

If enabled, the HTTP resource adaptor will compress outgoing responses automatically, while respecting the Accept-Encoding header (see RFC 2616 - section 14.3 for details).

AutomaticContentDecompression

Boolean

true

If enabled, the HTTP resource adaptor will decompress incoming responses automatically, while respecting the Content-Encoding header (see RFC 2616 - section 14.11 for details).

CreateIncomingSasTrail

Boolean

false

If enabled, the HTTP resource adaptor will create SAS Trails for incoming requests, and report them automatically.

ServiceMeshAddress

String

Local IP address of the service mesh server, if present. If unset no service mesh will be used. If a service mesh is used, the message sent from the RA will be modified to be sent to the ServiceMesh address, with the original destination stored in the 'Host' header. Proxy and Service Mesh are mutually exclusive

ServiceMeshPort

Integer

0

Local TCP port of the service mesh server, if present. If set to 0 no service mesh will be used. If a service mesh is used, the message sent from the RA will be modified to be sent to the ServiceMesh address, with the original destination stored in the 'Host' header. Proxy and Service Mesh are mutually exclusive.

ProxyAddress

String

Local IP address or FQDN of the proxy server, if present. If unset no proxy will be used. Proxy and Service Mesh are mutually exclusive.

ProxyPort

Integer

0

Local TCP port of the proxy server, if present. If set to 0 no proxy will be used. Proxy and Service Mesh are mutually exclusive.

RequestPathsToRedact

String

(empty)

Comma-separated list of regular expressions that will be matched against request URI paths when reporting incoming requests to SAS. Requests with matching URIs will have their content redacted in traces sent to SAS, to avoid sensitive information leaking via SAS. If empty then no redaction is performed. Partial matches are accepted, e.g. the pattern ^/abc/ matches paths /abc/123, /abc/999?x=y etc.

Note ThreadPoolSize, MaxChannelMemorySize and MaxTotalMemorySize are not currently used. In future, they will support configuration of the Netty OrderedMemoryAwareThreadPoolExecutor.

Secure configuration

Name Type Default Description

SecureListenPort

Integer

0

Local TCP port that the HTTP resource adaptor will listen on for HTTPS requests. If set to a value greater than 0, then a KeyStore must be provided that contains the private key for the server.

SecureBindAddresses

String

Contains per-node configuration information regarding each node’s specified local IP address and local TCP port that the HTTP resource adaptor will listen on for requests. If SecureBindAddresses is empty, ListenAddress and SecureListenPort will be employed. If a SecureBindAddress is specified then a KeyStore must be provided that contains the private key for the server. For syntax see Specifying bind addresses.

KeyStore

String

(empty)

Path to JKS keystore file. System properties (such as ${rhino.dir.home}) may be used.

KeyStorePassword

String

(empty)

Keystore password for file specified by KeyStore.

TrustStore

String

${java.home}/lib/security/cacerts

Path to JKS keystore for trust certificates.

TrustStorePassword

String

changeit

Keystore password for file specified by TrustStore.

CipherSuites

String

(empty)

List of cipher suites to pass to SSLEngine.setEnabledCipherSuites(). An empty value means the method won’t be called and all cipher suites are enabled.

SSLSessionTimeout

Integer

0

Value to pass to SSLContext.setSessionTimeout() after the context is created. A value of 0 means the method won’t be called.

NeedClientAuth

Boolean

false

When set to true, this will set the same flag on the SSL Engine for incoming HTTPS connections, meaning a valid client certificate is required to connect. The client certificates can be retrieved from the HttpRequest event using the getClientDetails() method.

Specifying bind addresses

BindAddresses and SecureBindAddresses are specified as a comma-separated list of {node}host:port elements.

This allows entities running on two nodes on the same host to use different ports, for example:

{101}0.0.0.0:8000,{102}0.0.0.0:8001

It also allows entities running on different hosts to specify an interface to listen on that is specific to each host, for example:

{101}192.168.1.100:8000,{102}192.168.1.101:8000

Events and Activities

Below are details of events, activities, and the ACI and SBB interfaces for the resource adaptor.

Events

The resource adaptor emits the following event types:

Note All listed classes are in the com.opencloud.slee.resources.http package.

Event ID

name=com.opencloud.slee.resources.http.HttpRequest.GET,vendor=OpenCloud,version=2.2

Event Object

HttpRequest

Activity Object

IncomingHttpRequestActivity

Description

The resource adaptor received an HTTP GET request.

Event ID

name=com.opencloud.slee.resources.http.HttpRequest.POST,vendor=OpenCloud,version=2.2

Event Object

HttpRequest

Activity Object

IncomingHttpRequestActivity

Description

The resource adaptor received an HTTP POST request.

Event ID

name=com.opencloud.slee.resources.http.HttpRequest.HEAD,vendor=OpenCloud,version=2.2

Event Object

HttpRequest

Activity Object

IncomingHttpRequestActivity

Description

The resource adaptor received an HTTP HEAD request.

Event ID

name=com.opencloud.slee.resources.http.HttpRequest.PUT,vendor=OpenCloud,version=2.2

Event Object

HttpRequest

Activity Object

IncomingHttpRequestActivity

Description

The resource adaptor received an HTTP PUT request.

Event ID

name=com.opencloud.slee.resources.http.HttpRequest.DELETE,vendor=OpenCloud,version=2.2

Event Object

HttpRequest

Activity Object

IncomingHttpRequestActivity

Description

The resource adaptor received an HTTP DELETE request.

Event ID

name=com.opencloud.slee.resources.http.HttpResponse,vendor=OpenCloud,version=2.2

Event Object

HttpResponse

Activity Object

OutgoingHttpRequestActivity

Description

The resource adaptor received a response or generated an error response to an earlier outgoing HTTP request. Only one response event type is defined (instead of separate events 2xx, 3xx and so on), because the resource adaptor assumes that applications will always want to see the HTTP response, regardless of the status-code value.

Activities

The resource adaptor creates two types of activities:

Activity Object Description

IncomingHttpRequestActivity

This activity is created when the resource adaptor receives a HTTP request. The activity object has methods for creating and sending a response to the request. The activity ends when the response is sent. In addition, if for some reason a SBB does not send a response in time, the resource adaptor will automatically send an error response back to the client, ending the activity. The timeout is specified by the IncomingRequestTimeout configuration property.

OutgoingHttpRequestActivity

This activity is created when a SBB sends an outgoing HTTP request. There is nothing that can be done with the activity, it is only there so that the SBB may attach to it in order to receive the response asynchronously.

Activity Context Interface Factory

The ACI Factory interface is HttpActivityContextInterfaceFactory.

SBB Interface

The SBB Interface is HttpProvider. This interface must be used for creating and sending outgoing requests. If the service only deals with incoming requests, then this interface does not need to be used.

Error Response Codes

This page describes HTTP response codes sent by the resource adaptor in server mode, and response codes used in artificial response events generated in client mode.

Acting as a server

The resource adaptor sends the following response codes to clients when there are event processing errors:

Code Message Reason

500

"Server Too Busy"

Activity could not be started due to non system-level issues such as an input rate limiting policy.

500

"Internal Server Error"

Activity could not be started due to non system-level or any other issues.

500

"Server Error"

Resource adaptor event processing failed.

501

"Not Implemented"

Event filtered by an EventFilter or no SBB found to process it.

The resource adaptor also sends the following response codes to clients in the cases described:

Code Message Reason

400

"Missing Host Header"

Host header not set for HTTP v1.1 request.

404

"Not found"

Host and URI constitute a malformed URL.

Acting as a client

In certain scenarios when operating in client mode, the resource adaptor will fire response events when no response has been received from the server.

Note The HttpResponse.isServerResponse() method allows a service to distinguish between responses received from the remote server and responses generated by the resource adaptor.
Code Message Reason

500

"Server closed connection"

Connection closed by a remote server.

500

"Read error: <cause>"

Failure on receiving response in client.

500

"Write error: <cause>"

Failure on sending request from client.

500

"Timed out waiting for server connection"

Queue timeout met before a connection was available and the request could be sent.

500

"RA deactivation while waiting for server connection"

The resource adaptor reactivated before a connection was available and the request could be sent.

Service Assurance Server (SAS) Tracing

The HTTP resource adaptor contains code for integration with Metaswitch Service Assurance Server (SAS), which is a platform for recording and viewing detailed call handling information.

Note

Rhino TAS 2.6 or later supports SAS tracing.

You can use the HTTP resource adaptor with earlier Rhino versions if the Rhino API Compatibility SLEE library is deployed. The script that deploys the HTTP Ping service included in the resource adaptor package has an example of how to deploy the library.

For details about SAS tracing in Rhino TAS, see the SAS Facility section in the Rhino extended API document. For details about developing applications with the SAS tracing functionality, see the Rhino SAS API Development Guide.

The HTTP resource adaptor has two models for managing SAS trails, depending on whether it is handling incoming or outgoing requests.

Incoming requests

The resource adaptor creates a new SAS trail for every incoming request if it is configured to do so. After that, it logs the HTTP request with this trail.

The CreateIncomingSasTrail configuration property controls this trail creation behavior. For details, see Configuring the HTTP Resource Adaptor.

Outgoing requests

For outgoing HTTP requests, if there is a SAS trail attached to the OutgoingHttpRequestActivity, the resource adaptor uses it to log the HTTP request. It will never create a SAS trail. Therefore, if there is no trail attached to the outgoing HTTP request activity, the resource adaptor does not log the request to SAS.

Rhino TAS has a feature that automatically sets the trail for activities created within event handlers for activities that have a trail attached. To disable the tracing of outgoing HTTP requests in this scenario, set the SAS trail on the OutgoingHttpRequestActivity to null.

For details about automatic trail handling, see the Rhino SAS API Development Guide.

SAS events

The mini-bundle that the HTTP resource adaptor uses is as follows. As shown in the code, the following SAS events are defined:

  • INCOMING_MESSAGE

  • OUTGOING_MESSAGE

  • SENDING_MESSAGE

  • SENDING_MESSAGE_VIA_MESH

---
version: 1.0
events:
  INCOMING_MESSAGE:
    summary: 'Received HTTP {{ var_data[3] }} from {{ var_data[2] }}'
    details: |
      Received HTTP message from {{ var_data[2] }}:{{ static_data[1] }} on {{ var_data[1] }}:{{ static_data[0] }}

      <sas:fixed-width-font>{{ var_data[0] }}</sas:fixed-width-font>
    level: 60
    call_flow:
      caption: '{{ var_data[3] }}'
      data: '{{ var_data[0] }}'
      protocol: HTTP
      direction: in
      local_address: '{{ var_data[1] }}:{{ static_data[0] }}'
      remote_address: '{{ var_data[2] }}:{{ static_data[1] }}'
      message_id: '{{ var_data[4] }}'
      call_info_id: '{{ var_data[5] }}'
  OUTGOING_MESSAGE:
    summary: 'Sent HTTP {{ var_data[3] }} to {{ var_data[2] }}'
    details: |
      Sent HTTP message to {{ var_data[2] }}:{{ static_data[1] }} from {{ var_data[1] }}:{{ static_data[0] }}

      <sas:fixed-width-font>{{ var_data[0] }}</sas:fixed-width-font>
    level: 60
    call_flow:
      caption: '{{ var_data[3] }}'
      data: '{{ var_data[0] }}'
      protocol: HTTP
      direction: out
      local_address: '{{ var_data[1] }}:{{ static_data[0] }}'
      remote_address: '{{ var_data[2] }}:{{ static_data[1] }}'
      message_id: '{{ var_data[4] }}'
      call_info_id: '{{ var_data[5] }}'
  SENDING_MESSAGE:
    summary: 'Sending HTTP {{ var_data[0] }} to {{ var_data[1] }}:{{ var_data[2] }}'
    details: |
      Attempting connection to {{ var_data[1] }}:{{ var_data[2] }}
    level: 40
  SENDING_MESSAGE_VIA_MESH:
    summary: 'Sending HTTP {{ var_data[0] }} to {{ var_data[1] }} via service mesh at {{ var_data[2] }}:{{ var_data[3] }}'
    details: |
      Attempting connection to {{ var_data[1] }} via service mesh at {{ var_data[2] }}:{{ var_data[3] }}
    level: 40

For details about the mini-bundle or the event fields, see the Rhino SAS API Development Guide.

Note

If SAS tracing is configured and enabled, when the resource adaptor logs a request or a response message, it also raises a GENERIC_CORRELATOR_MARKER SAS marker that contains the X-Span-ID HTTP header for trail correlation with other SAS-enabled products.

SAS example

For an example of how to log SAS events, see the HTTP example service source code.

Running the Example HTTP Service

HTTP resource adaptor package includes an example "Ping" service. This service simply responds with a page displaying the request contents.

Install and run the service

Below are basic instructions for deploying and testing the HTTP example service in your SLEE, followed by an excerpt of SBB code showing how a client sends and a server processes HTTP requests.

1

Install the service:

$ cd examples
$ ant

2

Navigate to http://localhost:8000/ in a web browser.

HTTPS

To enable HTTPS:

1

Generate a keystore for the server:

$ keytool -keystore http-ra.ks -storepass changeit -genkeypair
Warning The http-ra.ks file should be placed in the Rhino home directory. The resource adaptor has a default FilePermission allowing it to read ${rhino.dir.home}/http-ra.ks. If you put the file elsewhere or give it a different name, you will need to update the security permissions for the resource adaptor entity.

2

Configure the resource adaptor entity and restart it:

rhino$ client/bin/rhino-console
[Rhino@localhost (#0)] updateraentityconfigproperties httpra SecureListenPort 8002 KeyStore "${rhino.dir.home}/http-ra.ks" KeyStorePassword changeit
[Rhino@localhost (#1)] deactivateraentity httpra
[Rhino@localhost (#2)] activateraentity httpra

3

The URL https://localhost:8002/ should now display the same page as before, using HTTPS.

Sample code

Below are excerpts of SBB code showing how servers can process HTTP requests, and clients can send them.

Server

Below is an excerpt of SBB code showing how incoming HTTP requests can be processed.

import com.opencloud.slee.resources.http.*;

...

// SBB event handler
public void onGET(HttpRequest event, ActivityContextInterface aci) {
    IncomingHttpRequestActivity activity = (IncomingHttpRequestActivity) aci.getActivity();
    // Send a redirect response...
    HttpResponse response = activity.createResponse(302, "Moved Temporarily");
    response.setHeader("Location", "http://anotherserver/index.html");
    try {
        // send the response
        InvokingTrailAccessor.getInvokingTrail().event(SasEvent.SENDING_MESSAGE).varParam(request.getMethod()).report();
        activity.sendResponse(response);
    } catch (IOException e) {
        warning("unable to generate response", e);
        InvokingTrailAccessor.getInvokingTrail().event(SasEvent.UNABLE_TO_GENERATE_RESPONSE).report();
    }
}

Client

Below is an excerpt of SBB code showing how outgoing HTTP requests can be made.

import com.opencloud.slee.resources.http.*;

...

public void setSbbContext(SbbContext sbbContext) {
    this.sbbContext = sbbContext;
    Context sbbEnv = (Context) new InitialContext().lookup("java:comp/env");
    provider = (HttpProvider) sbbEnv.lookup("slee/resources/http/2.2/provider");
    acif = (HttpActivityContextInterfaceFactory) sbbEnv.lookup("slee/resources/http/2.2/acifactory");
    ...
}

public void onSomeEvent(SomeEvent event, ActivityContextInterface aci) {
    ...
    HttpRequest newRequest = provider.createRequest(HttpRequest.POST, new URL("http://someserver/service.jsp"));
    newRequest.setContentAsString("text/plain; charset=\"utf-8\"", "test message");

    OutgoingHttpRequestActivity activity = provider.createRequestActivity(newRequest);
    ActivityContextInterface newACI = acif.getActivityContextInterface(activity);
    // attach so we will receive response...
    newACI.attach(sbbContext.getSbbLocalObject());
    //Set the SAS trail to one we have on hand.
    sasFacility.setActivityTrail(newACI, trail);
    activity.sendRequest();
}

public void onHttpResponse(HttpResponse event, ActivityContextInterface aci) {
    trace("Received " + event.getStatusCode() + " response");
    byte[] data = event.getContent();   // Or getContentAsString() if appropriate
    // process response content...
}

// instance vars
private SbbContext sbbContext;
private HttpProvider provider;
private HttpActivityContextInterfaceFactory acif;