One of the components generated by the Rhino REST API Framework is a resource adaptor type. This component contains all the service visible classes and interfaces you need to write Rhino TAS - Telecom Application Server based services.

rest framework service api
  • A resource adaptor Provider interface for your RA type

  • An ACI Factory object

  • A Client interface for your REST API

  • An API interface for each tag used in your API specification

  • Request and Response Events

  • Model classes and Enums

The following diagram explains the relation between the RA Provider, REST API Client and API interfaces.

rest framework service api model

Each RA Type defines one provider interface. The resource adaptor is responsible for implementing this interface. The provider defines a factory operation for fetching a Client interface. The Client defines a factory operation per API that the REST API defines.

Tip Learn more about Resource Adaptors from JAIN SLEE (JSR 240).

The following sections explain how to use the classes and interfaces in the REST API resource adaptor type.

Getting a provider and ACI factory

Rhino implements the SBB component environment, and provides it to the instances of the SBB component classes through the JNDI interfaces. You access a resource adaptor provider object using a JNDI lookup.

For example the PingPongApiServerSbbPart constructor:

PingPongApiServerSbbPart sbb-part constructor
Unresolved directive in <stdin> - include::/mnt/volume-01/jenkins/workspace/product/ra/rest-api-framework/release-2.1.x/Docs/rest-api-framework-docs/rest-api-framework-public-docs/rhino-rest-api-framework-users-guide/include/PingPongApiServerSbbPart.java[tag=sbbpart-constructor]
Tip Review the generated sbb-part superclass as it contains the required annotations and code for obtaining a provider object.

Getting an API object

The RA provider allows you to create a Client object. For example, the PetstoreApiServerProvider interface is:

public interface PetstoreApiServerProvider {
    /**
     * Return an API Client instance.
     * @param configuration the configuration to use for the instance of the API.
     * @return an PetstoreApiServerApiClient instance.
     */
PetstoreApiServerApiClient getApiClient(ApiConfiguration configuration);
}

You get a Client interface by calling getApiClient(), passing an ApiConfiguration object as a parameter. The ApiConfiguration object defines the configuration to be used with a generated REST API such as the preferred body type to be used when you create outgoing requests and responses.

Tip You may call getApiClient() more than once, with different ApiConfiguration objects.

The PetstoreApiServerApiClient interface is:

public interface PetstoreApiServerApiClient {

    /**
     * Return an api object related to the PetsApi API.
     * @return an PetsApi instance.
     */
    PetsApi getPetsApi();
}

The client interface has one accessor method per tag/API in your OpenAPI Specification.

Deriving API interfaces from an openapi spec

Each API operation may have an associated list of tags. For example, the List Pets request in the Pet Store API has a tag of Pets. The OpenAPI SLEE Generator uses tags to:

  • group operations into API interfaces

  • generate an accessor operation per API interface, in the Client interface.

Use tags in your openapi specifications to group related operations together in the generated API.

Model types

The OpenAPI SLEE Generator generates Java classes and Enums from the schemas subsection of the components section of your openapi specification.

Tip See: Components.

For example the Pet Store schema defines Pet and Pets, from which OpenAPI SLEE Generator will generate a Pet class.

The generated model types implement Serializable, so can be stored in CMP fields.

Tip In the future these will also be FastSerializable, for more efficient storage in CMP.

Creating and Sending requests

Create and send requests by using an API object. For example, the following NotificationsApi interface, from a call notification REST API, would be used to create and send CallDirectionNotification and CallEventNotification requests.

public interface NotificationApi {
    // ...

    // Create a RestRequestBuilder for request: CallDirectionNotification
    RestRequestBuilder createCallDirectionNotificationRequest(
          CallEventNotification callEventNotification);

    // Create a RestRequestBuilder for request: CallEventNotification
    RestRequestBuilder createCallEventNotificationRequest(
          CallEventNotification callEventNotification);

    // Send a request
    OutgoingRestActivity sendRequest(
          RestRequestBuilder requestBuilder) throws IOException;
}

The content-type used is defined in your openapi specification. For example the callDirectionNotification operation is:

/calldirection/notification:
post:
  summary: A new Call Direction notification
  operationId: callDirectionNotification
  tags:
    - notification
  requestBody:
    required: true
    description: call direction notification
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/CallEventNotification"

If an operation supports JSON or XML encoding, the configured preferredBodyType (from the ApiConfiguration) dictates which encoding to use. If no preferredBodyType is specified, then the first JSON-compatible media type, from the list of supported types, is used.

Once the new outgoing request is created, it is sent using the API object’s sendRequest method. This method returns an OutgoingRestActivity to which the application should attach, so it will receive the associated response.

Creating and Sending responses

There are two methods for creating and sending responses:

  1. Create the response by using an API object

  2. Create the response from a Request event

Create the response by using an API object

Create and send responses by using an API object. For example, the Pet Store API PetsApi interface includes the following operations to create responses related to a ShowPetById request:

ShowPetById responses in PetsApi interface
    /**
     * Create a {@link RestResponseBuilder} for a _200_Success response, related to a ShowPetById request.
     * @param contentTypeStr the desired Content-Type, as a string. If null, the default Content-Type
     *        will be selected from application/json
     *        based on the value of {@link com.opencloud.slee.rest.common.ApiOptions#preferredBodyType}
     *        in the {@link com.opencloud.slee.rest.common.ApiConfiguration}
     * @param responseBody a Pet, may be null
     */
    RestResponseBuilder createShowPetById_200_SuccessResponse(String contentTypeStr,
                                                              Pet responseBody);

    /**
     * Create a {@link RestResponseBuilder} for a Default response, related to a ShowPetById request.
     * @param contentTypeStr the desired Content-Type, as a string. If null, the default Content-Type
     *        will be selected from application/json
     *        based on the value of {@link com.opencloud.slee.rest.common.ApiOptions#preferredBodyType}
     *        in the {@link com.opencloud.slee.rest.common.ApiConfiguration}
     * @param responseBody a Error, may be null
     */
    RestResponseBuilder createShowPetByIdDefaultResponse(int statusCode,
                                                         String contentTypeStr,
                                                         Error responseBody);

Once the new outgoing response is created, it is sent using the API object’s sendResponse method.

PetsApi sendResponse operation
    /**
     * Send a response.
     * @param responseBuilder the response to be sent.
     * @throws IOException if the response could not be built or sent.
     */
    void sendResponse(RestResponseBuilder responseBuilder, ActivityContextInterface aci)
            throws IOException;

Create the response from a Request event

The generated request event objects include methods for creating the associated responses. For example, the ShowPetByIdRequest event class includes these methods.

    /**
     * Create a {@link RestResponseBuilder} for a 200 Success response.
     * @param contentTypeStr the desired Content-Type, as a string. If null, the default Content-Type
     *        will be selected from application/json
     *        based on the value of {@link com.opencloud.slee.rest.common.ApiOptions#preferredBodyType}
     *        in the {@link com.opencloud.slee.rest.common.ApiConfiguration}
     * @param responseBody a Pet, may be null
     */
    public RestResponseBuilder create_200_SuccessResponse(String contentTypeStr,
                                                          Pet responseBody)
    {
        // method implementation not shown
    }

    /**
     * Create a {@link RestResponseBuilder} for a Default response.
     * @param contentTypeStr the desired Content-Type, as a string. If null, the default Content-Type
     *        will be selected from application/json
     *        based on the value of {@link com.opencloud.slee.rest.common.ApiOptions#preferredBodyType}
     *        in the {@link com.opencloud.slee.rest.common.ApiConfiguration}
     * @param responseBody a Error, may be null
     */
    public RestResponseBuilder createDefaultResponse(int statusCode,
                                                     String contentTypeStr,
                                                     Error responseBody)
    {
        // method implementation not shown
    }

In the following example, process a ShowPetById by querying the Pets DB. If there exists a Pet corresponding to PetId then create a 200 success response (create_200_SuccessResponse("application/json", toShow)). Otherwise create a 501 error response.

MockPetstoreSbb handling a ShowPetById request
    private void handleShowPetByIdRequest(ShowPetByIdRequest request,
                                          ActivityContextInterface aci) throws IOException
    {
        final Pet toShow = getPet(request.getPetId());
        if (null == toShow) {
            tracer.finest("Show pet with id: {} = {}", request.getPetId(), toShow);
            final RestResponseBuilder errorResponse = request.createDefaultResponse(
                    501,"application/json",
                    new Error().code(501).message("There is no pet with id: " + request.getPetId()));
            sendResponse(errorResponse, aci);
        }
        else {
            sendResponse(request.create_200_SuccessResponse("application/json", toShow), aci);
        }
    }

Once the new outgoing response is created, it is sent using the API object’s sendResponse method.

MockPetstoreSbb sending responses
    private void sendResponse(RestResponseBuilder response, ActivityContextInterface aci) {
        try { petsApi.sendResponse(response, aci); }
        catch (IOException e) {
            tracer.finest("Failed to send  response. Api = {} , OperationId = {}",
                    response.getApi(), response.getOperationId(), e);
        }
    }
Previous page Next page