5 Using Actions to Manage and Manipulate API Traffic

This chapter explains how you use actions and action chains to manage Oracle Communications Services Gatekeeper API requests and responses, and change the information in those requests.

Configuring Actions Chains to Manage API Traffic

When your customers use your partner applications, the applications generate requests and responses that call upon one or more of the APIs created in Partner and API Management Portal.

You select and configure actions to filter and act on the request and response messages that contain calls to the APIs. You combine actions into request and response action chains (combinations of actions) that are processed in the order you arrange them. The sections in this chapter:

  • Introduces the actions and explains how to configure them.

  • Explains what the individual default actions do.

  • Provides information for some common action processing tasks.

  • Provides some troubleshooting information for action chains.

For information about creating you own custom actions, see ”Creating Custom Actions for Your APIs” in Services Gatekeeper Portal Developer's Guide.

About Action Chains

You implement actions on API request or response traffic using the Actions tab for each API. You drag and drop individual actions into the Request or Response action chain to make them take effect. When you drop an action, a pane appears with the action parameters for you to configure. Every action has at least one optional Instance ID parameter that you can use to create an informal alphanumeric version number to identify the action. Some of these parameters are optional and some required. If you get a fail message when you try to save your changes, the problem can be a missing parameter. See "Understanding the Default Actions" for details about the parameters for individual actions.

Note:

Actions only affect traffic for APIs that you create using the Partner and API Management Portal. Use interceptors to affect request and response messages for Services Gatekeeper communication services.

You can use the actions provided by Services Gatekeeper, or create your own actions to act on the request (or response) traffic for an API. You can set up actions chains to take a wide range of real-time effect on the request or response messages, such as identity management, mapping to support data formats and protocol changes, authorization, logging, monitoring, and statistics. Some action parameters are optional and others required. If you get a fail message when you try to save your changes, the problem can be a missing parameter.

The sequence of actions in the action chain depends on the direction of the message flow. It is either application-initiated and traveling to the network, or server-initiated and traveling to the application. Some actions (such as identity management) are valid only in the request flow and some only in the response flow. Other actions (such as supporting protocol changes, validations) are common in that they are applicable in either direction. Services Gatekeeper does not allow you add an invalid action to an action chain.

When you position an action incorrectly in a chain, Partner and API Management Portal prompts you to ensure that the sequence of actions is valid for that direction.

Note:

Actions only affect traffic for APIs that you create using the Partner and API Management Portal. Use interceptors to affect request and response messages for Services Gatekeeper communication services.

Actions in Application-Initiated Flows

When an application sends a request that contains a call to an API subscribed to by the application, Services Gatekeeper processes it using all actions configured for it in order. Services Gatekeeper can receive and handle incoming HTTP requests such as SOAP, REST, or XML-RPC. Services Gatekeeper checks the incoming request and performs preconfigured tasks such as enforcing policy (associated with the service level agreement), translates the message as necessary (such as from JSON to XML format), and so on. In addition, it processes the action with any custom tasks you added to suit your requirements. Finally, Services Gatekeeper forwards the outbound request message to the server.

Actions in Server-Initiated Flows

Server-initiated flows occur when, for example, an application sets up a notification for an event. The server listens for the event and sends a notification to the application. The notification comes in to Services Gatekeeper as a request from the server and contains a call to an API subscribed to by the application. Services Gatekeeper receives the request from the server and processes it according to the response action chain. The final step in the action chain would be to forward the outbound request message to the application in the format required by that application.

When the application responds to this notification, the API proxy processes that response according to the tasks preconfigured for that sequence of the action chain. Finally, the response for the server-initiated request is sent back to the server.

Understanding Front and Middle Actions

Actions for both chains are divided into front actions and middle actions. Use front actions as major filters on the incoming requests. For example, you can use Throttling to regulate the usage of the API and regulate traffic based on specific partner groups. (API management already provides throttling based on the application and based on the network service.)

Use middle actions to act on the content of the request or response in real time. For example, use Callout to perform an HTTP GET operation against the Request URL and store the response as required.

About Action Statuses

You only change the action statuses if you create your own actions using the instructions in ”Creating Custom Actions for Your APIs” in Services Gatekeeper Portal Developer's Guide.

An action can have one these statuses:

  • ACTIVE

    The Oracle-supplied actions, and any new actions you create in Partner and API Management Portal have a state of the ACTIVE.

    Any API can use an action the ACTIVE state.

  • DEPRECATED

    A deprecated action represents an older version of a current interface. When you update an existing action, the updated version becomes the active version and the previous version becomes deprecated. You can also deprecate an existing action in Partner and API Management Portal, by selecting the icon adjoining the trash can icon within the interface icon. Services Gatekeeper asks you to specify the date and time when the interface should be deprecated.

    Tip:

    Maintain backward compatibility when you update an active action.

    The data for a deprecated action cannot be modified, and deprecated actions are not available to new APIs.

    The service associated with a deprecated action is available to APIs that subscribed to the interface and only for a designated period. After that period, the network service supplier can remove the deprecated interface.

Setting Actions System Administration Settings

This section explains the administration settings specific to Actions. See Services Gatekeeper System Administrator's Guide for information about general Services Gatekeeper administration settings.

Setting Actions System Performance Settings

You use the Actions system performance settings to ensure that your actions do not inadvertently include code that adversely affects Services Gatekeeper performance. The Actions system performance settings are listed here with the default value in parenthesis:

  • KeepNorthSession Boolean (false) - If true, this setting keeps the session open after the request is complete

  • EnableSouthCookie Boolean (false) - If true, allows applications to communicate with backend servers using cookies. You must set this to true if your Actions use basic (text-based) authentication.

  • UseSession Boolean (false) - If true, allows an application to use a session when communicating with backend servers.

  • MaxTotalConnections Integer (4000) - Sets the maximum total allowed network connections. You can also set this option from the system WebLogic server start up script; see "Using the WebLogic Startup Script to Set Action System Performance Settings" for details.

  • SocketTimeoutMs Integer (30000) - The time, in milliseconds, that socket waits for activity before closing down. You can also set this option from the system WebLogic server start up script; see "Using the WebLogic Startup Script to Set Action System Performance Settings" for details.

  • ConnectTimeoutMs Integer (30000) - The time, in milliseconds, that a connection waits for activity before closing down. You can also set this option from the system WebLogic server start up script; see "Using the WebLogic Startup Script to Set Action System Performance Settings" for details.

  • ReuseAddress Boolean (true) - If true, directs Services Gatekeeper to ignore the TCP time_wait state. This improves performance by allowing Services Gatekeeper to close the socket immediately after the connection is closed, instead of continuing to wait for late packets.

You have these options to change these settings:

Using the Administration Console to Set Action System Performance Settings

To configure the Actions performance settings using the Administration Console:

  1. Start the Administration Console.

    See ”Starting and Using the Administration Console” in Services Gatekeeper System Administrator's Guide for details.

  2. Click Lock & Edit.

  3. Navigate to OCSG, then admin_server_name (Server1 by default), then Container Services, then DafGeneralInformation.

    The Configuration and Provisioning on server_name page appears with the performance settings.

  4. Change the settings as necessary.

  5. Click Release Configuration.

  6. Restart the administration sever to make your changes take effect.

Using the WebLogic Startup Script to Set Action System Performance Settings

You can change these Actions system performance settings as command line options:

  • oracle.sdp.daf.max_total_connections

  • oracle.sdp.daf.socket_timeout_ms

  • oracle.sdp.daf.connect_timeout_ms

This example sets the maximum total number of connections to 3000:

% startWebLogic.sh -Doracle.sdp.daf.max_total_connections=3000

Setting Actions White and Black Lists

You use these ”white” and ”black” lists to control the individual methods and packages that software developers are allowed to use in actions. These are the default lists:

  • Black list of methods: exit and setProperty.

  • Black list of packages:

    • java.lang.Thread;java.lang.Runnable

    • java.lang.ClassLoader

    • java.lang.Class

    • java.io

    • java.net

    • groovy.lang.GroovyShell

    • groovy.util.Eva

    • groovy.io

    • groovy.net

  • White list of methods: java.net.InetAddress.getLocalHost()

  • White list of packages: null

To view or change the white and black lists using the Administration Console:

  1. Start the Administration Console.

    See ”Starting and Using the Administration Console” in Services Gatekeeper System Administrator's Guide for details.

  2. Click Lock & Edit.

  3. Navigate to OCSG, then admin_server_name (Server1 by default), then Container Services, then DafGeneralInformation, then Operations.

    The Configuration and Provisioning on server_name page appears with the performance settings.

  4. Select an operation from the Select An Operation menu. The choices are:

    • loadBlackListMethod - Add Java/Groovy methods to the black list.

    • loadBlackListPackage - Add Java/Groovy packages to add to the black list.

    • loadWhiteListMethod - Add Java/Groovy methods to the white list.

    • loadWhiteListPackage - Add Java/Groovy packages to the white list.

    • retrieveBlackListMethod - Show the list of the Java/Groovy methods on the black list.

    • retrieveBlackListPackage - Show the list of Java/Groovy packages on the black list.

    • retrieveListAll - Show the contents of all white and black lists.

    • retrievePerformanceSets - Show the Actions performance settings (set using Attributes).

    • retrieveWhiteListMethod - Show the list of all items on the white lists.

    • retrieveWhiteListPackage - Show the list of all packages on the white lists.

Understanding the Default Actions

This section lists the default actions provided by Services Gatekeeper. You configure these actions in the Actions tab for each API in the Partner and API Management Portal, or by using MBeans. See the ”All Classes” of the Actions Java API Reference for the appropriate MBeans.

All actions have at least one parameter, Instance Id, which you can use to create an identifier, or version number for the action. The instance id is captured in EDR data for each action. This is useful, for example, if you create multiple custom actions and need to identify which EDR fields came from a specific action. Instance id values 0-7 are reserved for Oracle internal use. See ”Understanding EDR Fields for API Management” in Services Gatekeeper Administrator's Guide for details on the actions EDR fields.

Note:

Do not confuse the actions instance id with the instanceid field that Services Gatekeeper maps to clients to use SLA enforcement with OAuth.

You invoke these actions on requests passing between the application and the network service (backend service):

appKeyValidation

Authenticate an application and give it access to an API. Typically used when the application cannot identify itself by other means. Confirms that an application has permission to access a specific API using an application key. You identify the application key, and you can also test whether that key exists in a header, or in a query parameter inside the header.

This action probes the x-app-key parameter for the API key in the request/response (unless you specify a different parameter). Configure appKeyValidation with these parameters:

  • Headerkey - (String) Specifies the header to check for the application key.

  • QueryParameter - (String) Specifies the application key to check for.

  • UseHeader - (Boolean) True directs the action to confirm that the application key exists on the header. False does not use this test. Can be used with UseQueryParameter.

  • UseQueryParameter - (Boolean) True directs the action to confirm that the application key exists in the query parameter. False does not use this test. Can be used with UseHeader.

Callout

A REST Call-out. Performs an HTTP GET operation against the RequestUrl and puts the response into the value of the storeResponse field for use by another action. You can use Callout to change attributes of the incoming request. This feature is also available to use in a Groovy script or custom action.

Set up a proxy or business service callout by:

  1. For the Request URL parameter, enter the remote URL for the callout in the Value column.

  2. For the Store Response parameter, enter the name of variable on the context in which the response is stored in the Value column.

The content of the message is constructed using the values of variables in the message context. The message content for outbound messages is handled differently depending upon the type of the target service.

This example uses the createCallout method to obtain a value for myattribute at the myurl URI:

context.createCallout().withRequestUrl("http://myurl.com")
.withRequestMethod("GET").build().send("myattribute");

You can then use the value for myattribute in a consecutive action:

HttpResponse response = context.getAttribute("myattribute");
and response has getStatus(), getHeaders and getBodyAsType(...)

CORS

Web pages are free to imbed some resources, such as images, from outside their own domain. Exceptions to this are fonts and AJAX (XMLHttpRequest) requests, which are usually restricted to the same domain that the parent web page itself is in. The ”cross-domain” AJAX requests in particular are forbidden because they represent glaring security risks.

Note:

The CORS action allows you to configure cross-origin resource sharing (CORS) to safely access third-party resources for your APIs. The default settings are empty, so CORS messages are not processed.

At a minimum, you need allow Support Preflight Requests or Allow Simple Requests and the appropriate origin, header, and method parameters so that this action passes CORS traffic.

This is a security-based action, so put it as early in your middle action chain as you can. After you add this action to an action chain, configure it to process the CORS messages that your implementation uses.

Also, having this early in the action chain allows you to take advantage of the Allow Non Verified Requests option which cancels action chain processing if the action fails. This can prevent unnecessary processing if this action fails.

See the CORS specification at the W2C Cross-Origin Resource Sharing website:

https://www.w3.org/TR/2014/REC-cors-20140116/

The configuration parameters give you the options to:

  • Allow preflight requests, simple requests, or both.

  • Decide whether to require credentials when calling the API.

  • Allow or disallow all origin URIs, resource headers, or methods to call the API.

  • Create ”white lists” of origins URIs, resource headers, or methods that are allowed to call the API.

  • Decide whether to support credentials in the request.

  • Decide whether to continue action chain processing if the CORS action does not pass validation.

  • The maximum time a user agent is allowed to cache results.

Table 5-1 lists the CORS configuration options.

Table 5-1 CORS Configuration Options

Option XML Representation Data Type Description

Support Preflight Passthrough

<supportPreflightPassthrough>

Boolean

Allows (true) or disallows (false) the API to send reflight requests to the backend service.

Support Preflight Requests

<supportPreflightRequests>

Boolean

Allows (true) or disallows (false) preflight requests for resources. No default setting.

Support Simple Requests

<supportSimpleRequests>

Boolean

Allows (true) or disallows (false) the API to process CORS simple requests.

Supports Credentials

<supportsCredentials>

Boolean

Allows (true) or disallows (false) the use of credentials when calling this API.

Allowed Origins

<allowedOrigins>

List of Strings

A ”white list” of URIs that can act as origins for CORS requests for this API. Can be used with Return Wild Card Allowed Origins.

Allow Any Origins

<allowAnyOrigins>

Boolean

Allows (true) or disallows (false) any URI that can act as origins for requests to this API

Return Wildcard Allowed Origins

<returnWildCardAllowedOrigins>

Boolean

Allows (true) or disallows (false) the ability to use the "*" (star) wildcard character in a lists of origins, allowing requests from ANY origin. Use Carefully. This setting becomes invalid if Supported Credentials is true. See Allowed Origins.

This example allows all domains that end in us.mydomain.com to submit requests:

*.us.mydomain.com

Allowed Methods

<allowedMethods>

List of Strings

The list of methods allowed to call this API.

Allow Any Method

<allowAnyMethod>

Boolean

Allows (true) or disallows (false) any method to call this API.

Exposed Headers

<exposedHeaders>

List of Strings

The list of headers (other than simple response headers) that can be exposed to a resource.

Allowed Header

<allowedHeaders>

List of Strings

The list of headers allowed in a preflight request

Allow Any Header

<allowAnyHeader>

Boolean

Allows (true) or disallows (false) any header to be allowed in a preflight request.

Maximum Age

<maxAge>

Long

The time limit, in seconds, that a user agent is allowed to cache the result of the request.

Allow Non-Verified Requests

<allowNonVerifiedRequests>

Boolean

Allows (true) or disallows (false) action chain processing to continue if the request does not pass validation for the header, origin, or method validation.


This example CORS configuration allows all CORS features and responds to the origin with any requests it receives:

<corsActionConfig>
  <allowAnyHeader>true</allowAnyHeader>
  <allowAnyMethod>true</allowAnyMethod>
  <allowAnyOrigin>true</allowAnyOrigin>
  <supportPreflightRequests>true</supportPreflightRequests>
  <supportSimpleRequests>true</supportSimpleRequests>
</corsActionConfig>

This example allows any header or method, supports both simple and preflight requests, but limits CORS requests to only the yourdomain.com and mydomain.com domains:

<corsActionConfig>
  <allowAnyHeader>true</allowAnyHeader>
  <allowAnyMethod>true</allowAnyMethod>
  <allowedOrigins>yourdomain.com</allowedOrigins>
  <allowedOrigins>mydomain.com</allowedOrigins>
  <supportPreflightRequests>true</supportPreflightRequests>
  <supportSimpleRequests>true</supportSimpleRequests>
</corsActionConfig>

This example allows any header or method, but only from a derivative of mydomain*.com, and that supports only simple requests.

<corsActionConfig>
  <allowAnyHeader>true</allowAnyHeader>
  <allowAnyMethod>true</allowAnyMethod>
  <returnWildCardAllowedOrigins>
  <allowedOrigins>mydomain*.com</allowedOrigins>
  <supportPreflightRequests>false</supportPreflightRequests>
  <supportSimpleRequests>true</supportSimpleRequests>
</corsActionConfig>

Groovy

Use a Groovy language script to change any aspect of a request or response message. You can add Groovy code to change the message content, destination, status, and so on. The script can be as simple or complex as your implementation requires. This option requires knowledge of the Groovy programming language.

You use the Actions Java API to obtain content from the API request and response traffic to act on in the Groovy action. Start by looking through the HttpContext class for information about extracting elements from messages.That class uses the HttpMessage, HttpRequest, and HttpResponse classes and some of its own methods to retrieve elements from messages that you can then manipulate. These classes are available from the ”All Classes” section of the Actions Java API Reference.

See "Common Actions Programming Tasks" and ”Creating Custom Actions for Your APIs” in Services Gatekeeper Portal Developer's Guide for some Groovy code examples.

Prohibited Components in Groovy Actions

Your Groovy actions are validated to prevent security vulnerabilities. These Java and Groovy interfaces and methods, and any class that inherits them are prohibited in Groovy actions.

  • java.lang.Thread

  • java.lang.Runnable

  • java.lang.ClassLoader

  • java.lang.Class

  • java.io

  • java.net

  • groovy.lang.GroovyShell

  • groovy.util.Eval

  • groovy.io

  • groovy.net

  • exit

  • setProperty

Json2Xml

This action takes text formatted for the JSON protocol from the body of the incoming request or response body, and translates it into XML format in the body of the outgoing request or response. Table 5-2 lists the parameters for this action:

Table 5-2 Json2Xml Action Parameters

Parameter Name Description

Instance Id

(Optional) A value that you add that is included in the event EDR. It identifies the action for debugging.

Default Name Space

(Optional) An identifier (usually a URI). This value is added to the first XML tag as the default namespace.

Root Tag

(Optional) Encloses the translated XML in a tag named for the value of this parameter. Used to avoid multiple roots in the translated XML.


For example, this JSON formatted text:

{
  "SendSms": { 
    "message":"my message 2",
    "senderName” : "senderName",
    "addresses” : "tel:123456",
    "@myattribute” : "foo”  }
}

Is translated in this XML format:

<SendSms myattribute="foo">
  <addresses>tel:123456</addresses>
  <senderName>senderName</senderName>
  <message>my message 2</message>
</SendSms>

See the "Xml2Json" action to translate XML input to JSON.

RateLimit

Restricts access to a URL for HTTP-to-HTTP communication. You set the allowable number of accesses for a configurable time period for a specific URL.

You set rate and timePeriodInMs (time period in milliseconds) parameters. rate sets the number of request messages that can be sent to the URL in the time period set by timePeriodInMs. For example, a rate of 100 and a timePeriodInMs of 60000, allows 100 request messages per minute.

You can further refine access to the URL by using multiple RateLimit actions. For example you can set an overall rate limit of 1000 messages per day, and also ensure that the URL is protected during peak hour by adding another RateLimit of 1 per minute.

SchemaValidation

Services Gatekeeper validates an incoming request or outgoing response that accesses a web service API, based on the schema provided by you for the API.

Provide values for the first XSD in the fields under the unit numbered 0. The first in the list is the main XSD/WADL/WSDL. The other entries are referenced from the first entry in the list.

  1. For the Content parameter, enter the actual XML Schema XSD content. Paste in a Schema in the Value column.

  2. For the Name parameter, enter the reference to the entry in Content. Use this name from another action or Groovy action to retrieve the schema you entered for Content.

To add more units, click the - sign next to Un.... and repeat.

Note:

If you add the SchemaValidation action to a flow but you do not provide a schema definition for the web service API, Services Gatekeeper returns an error.

Throttling

Change a partner group name, rate (requests/second), quota period (days), and quota (requests per quota period) specified in the message. The data you are changing comes from the appropriate SLA.

Provide values for the first partner group under the fields for the unit numbered 0:

  1. For the Group Name parameter, enter the name of the partner group.

  2. For the Quota parameter, enter the number of requests per quota period allowed.

  3. For the Quota Period parameter, enter the number of days in the quota period allowed.

  4. For the Rate parameter, enter the number limit for the number of requests per second allowed.

To add more throttle units, right-click the - sign next to Un.... and repeat.

Xml2Json

This action takes text formatted for the XML protocol from the body of the incoming request or response body, and translates it into JSON format in the body of the outgoing request or response. Table 5-3 lists the parameters for this action.

Table 5-3 Xml2Json Action Parameters

Parameter Description

Instance ID

A value that you add that is included in the event EDR. It identifies the action for debugging.


For example, this XML formatted text:

<SendSms myattribute="foo">
  <addresses>tel:123456</addresses>
  <senderName>senderName</senderName>
  <message>my message 2</message>
</SendSms>

Is translated into this JSON formatted text:

{
  "SendSms": { 
    "message":"my message 2",
    "senderName” : "senderName",
    "addresses” : "tel:123456",
    "@myattribute” : "foo”  }
}

See the "Json2Xml" action to translate JSON input into XML format.

XSLT

Use an Extensible Stylesheet Language script to change the XML-formatted body of the message.

DAF Callout Callback

For asynchronous send() calls, two actions are generated for each ServiceCallOut, allowing the response to be accessed other than in the subsequent action. In addition to the current oracle.sdp.daf.Callout.Callback class, an additional DAF (Dynamo Application Framework) callback interface called oracle.sdp.daf.action.api.CalloutCallbackHandler is shown in the following example:

package oracle.sdp.daf.action.api;
 
/**
 * Used for in-action callouts' callback processing.
 */
public interface CalloutCallbackHandler {
  /**
   * Called on callout completion.
   * @param context Context.
   * @throws ActionProcessingError Exception during callback
   * @since 7.0.0.0
   */
  void process(HttpContext context) throws ActionProcessingError;
}

To use it, the oracle.sdp.daf.action.api.CalloutBuilder interface has been extended to have two more methods for callback handler setting and retrieval. The following example illustrates the extensions.

package oracle.sdp.daf.action.api;
...
/**
 * Callout builder. Used to build a callout HTTP request.
 */
public interface CalloutBuilder extends MessageBuilder {
  /**
   * Adds callback handler.
   * @param callbackHandler The callback for this builder
   * @return The builder
   * @since 7.0.0.0
   */
  default CalloutBuilder withCallback(CalloutBuilderCallbackHandler callbackHandler) {
    // return unmodified builder for those classes which don't implement this
    return this;
  }
 
  /**
   * Gets the callback handler associated with this builder.
   * @return The callback handler
   * @since 7.0.0.0
   */
  default CalloutBuilderCallbackHandler getCallbackHandler() {
    // return null for those classes which don't implement this
    return null;
  }
...

Limitation

The implementation of the DAF Callout Callback assumes that DAF Action could contain only one asynchronous callout or send call. The presence of multiple asynchronous callouts or send() calls within the same DAF action could lead to unknown results.

Example of Callback

The following example demonstrates how to implement the callback class and also how to retrieve the response from a context attribute that was previously set in an asynchronous call.

package example;
 
public class MyCallback implements CalloutCallbackHandler {
  @Override
  public void process(HttpContext context) {
    System.out.println("---MyCallback process call");
    System.out.println("---MyCallback context.getAttribute(): " + context.getAttribute("TOKENADMIN_GET_RESPONSE"));
  }
}

The following example shows how it would be added in Groovy code using extra .withCallback(callback) syntax:

final String groovyCode1 =
  "try {\n"
  + "example.MyCallback callback = new example.MyCallback();\n"
  + "    String queryString = context.clientRequest.getQueryString();\n"
  + "    String apics_appkey = (String)context.clientRequest.queryParameters.apics_appkey\n" + "\n"
  + "System.out.println(\"Calling TokenAdmin with apics_appkey = \" + apics_appkey);\n"
  + "      // Get existing data from TokenAdmin\n"
  + "      context.setAttribute(\"CALLOUT_STATUS\", \"TOKENADMIN_GET\");\n"
  + "      ((oracle.sdp.daf.action.api.ExternalCalloutBuilder)(context.createCallout().withRequestUrl('"
  + "http://localhost:" + getPort() + ROOT_CONTEXT_PATH + "/callout/callouturl')"
  + ".withQueryParameter(\"apics_appkey\", apics_appkey).withRequestMethod(\"GET\").withHeader(\"Content-Type\","
  + "\"text/plain\").withCallback(callback))).build().send(\"TOKENADMIN_GET_RESPONSE\");\n"
  + "\n"
  + "}\n" + "catch (Exception e) {\n"
  + "    e.printStackTrace();\n"
  + "    throw e;\n" + "}";

Exception Handling

The following are exception handling considerations:

  • The DAF Action interface provides the following entry point method

    void process(HttpContext context) throws ActionProcessingError;

    The method throws ActionProcessingError to indicate that the processing flow should be cancelled.

  • CalloutCallback code, which is available to HTTP AsyncClient and implements FutureCallback<HttpResponse>), on request failure, at least for the case java.net.ConnectException:Connection refused, invokes public void failed(Exception e) method and through it a sendErrorResponseToApp(errorCode) call.

    The Javadoc output for sendErrorResponseToApp(errorCode)further illustrates:

    package oracle.sdp.daf;
    ...
    public final class CalloutCallback implements FutureCallback<HttpResponse> {
    ...
      /**
       * Send an error to the app - something went wrong. If this is within an
       * action, keep going, otherwise set the error flag on the utilcontext so   
       * that no actions will be processed.
       *
       * @param statusCode
       *          HTTP status code to return in the response
       */
      private void sendErrorResponseToApp(int statusCode) {
       ...
          internalHttpContext.getClientResponse().withStatus(statusCode);
          if (callback != null) {
            // this is the southbound call
            internalHttpContext.setInternalError(true);
          }
          internalSystemContext.getActionChainManager().continueActionChain(
              internalHttpContext.getSouthboundResponse(), internalHttpContext);
       ...
    

    In the case of a southbound call, the call above to internalHttpContext.setInternalError(true) is analyzed inside oracle.sdp.daf.ActionChainManager and it's doResponseChain(...) method, which are shown here:

    package oracle.sdp.daf;
    ...
    public final class ActionChainManager {
    ...
      private void doResponseChain(HttpResponse response,
          InternalHttpContext internalHttpContext) {
    ...
            if (!internalHttpContext.isInternalError()) {
    ...
    
  • When doing an asynchronous send() and a long invocation on the south side leads to a timeout, an HTTP asynchronous client will potentially throw java.net.SocketTimeoutException. An example of a java.net.SocketTimeoutException stack trace for an HTTP asynchronous client is shown here:

    java.net.SocketTimeoutException
        at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:376)
        at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:92)
        at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:39)
        at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:175)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:263)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:492)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:213)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
        at java.lang.Thread.run(Thread.java:745)
    

    Some oracle.sdp.daf.CustomHttpRequestRetryHandler logic will attempt to retry:

    [INFO ] pRequestRetryHandler  The maximum number of retry times is 1, current execution count is 1
    [INFO ] pRequestRetryHandler  isRquestSent is false
    

    If it fails again, logic will route through the public void failed(Exception e) method mentioned above.

  • As previously mentioned, the Callout callback handler interface has the same ability as DAF Action to throw ActionProcessingError and, in that case, action chain processing will be cancelled.

DAF Support of HTTP Methods

The following HTTP methods provide support of DAF (Dynamo Application Framework) features:

  • PATCH

  • HEA

  • TRACE

  • CONNECT

  • OPTION

PATCH Method

You can use the PATCH method to update partial resources. For example, you might want to update only one field of a resource. Using PUT to update the complete representation of a resource could be cumbersome.

Supporting the PATCH method allows a PATCH request to pass through DAF. The Portal is updated with the new PATCH method in the resource table.

DAF treats the PATCH method the same as other HTTP methods like POST and PUT, meaning that the PATCH method is transparent to DAF. DAF treats a PATCH request as follows:

  1. Transfers the request from the client to the backend service.

  2. Transfers the response from the backend service to the client.

HEAD Method

The HTTP HEAD method corresponds to a GET request but without the response body. The HEAD method use cases are:

  • Provides a faster way to check the headers

  • Provides a LastModified / ContentLength check to decide whether to re-download a given resource

  • Provides ability to log JavaScript-based content appearances

DAF treats the HEAD method the same as other HTTP methods like POST and PUT, meaning that the HEAD method is transparent to DAF. DAF treats a HEAD request as follows:

  1. Transfers the request from the client to the backend service.

  2. Transfers the response from the backend service to the client.

TRACE Method

The TRACE method, which is used for debugging, echoes input back to the user.

You must do the following to set up TRACE in your environment:

  1. Enable TRACE support in WebLogic to avoid error 501. You can enable TRACE support in the following ways:

    1. To enable TRACE manually, in the WebLogic console, select your domain -> Configuration -> WebApplication, click the Http Trace Support Enabled box and select Save.

    2. To enable TRACE in Java, set the HttpTraceSupportEnabled flag in the WebAppContainerMBean.

    DAF treats the TRACE method the same as other HTTP methods like POST and PUT, meaning that the TRACE method is transparent to DAF. DAF treats a TRACE request as follows:

    1. Transfers the request from the client to the backend service.

    2. Transfers the response from the backend service to the client.

CONNECT Method

Use the CONNECT method to create an HTTP tunnel.

In this mechanism, the client sends an HTTP CONNECT request to the OCSG server to forward the TCP connection to the desired destination. The server proceeds to make the connection on behalf of the client. Once the server establishes the connection, an HTTP 200 response is sent to the client. The OCSG server continues to proxy the TCP stream by other HTTP methods to and from the client. Note that only the initial connection request is HTTP. After that, the server simply proxies the established TCP connection.

DAF treats the CONNECT method the same as other HTTP methods like POST and PUT, meaning that the CONNECT method is transparent to DAF. DAF treats a CONNECT request as follows:

  1. Transfers the request from the client to the backend service.

  2. Transfers the response from the backend service to the client.

OPTION Method

Use the OPTION method to list available interfaces.

You can make three types of OPTION requests:

  1. Preflight request for CORS action. The CORS action responds directly. No change needed.

  2. Request to list available interfaces for an API. You must add a ListResourcesAction object to the request to handle this.

  3. Other types of requests are passed through DAF to the backend service.

Configure CORS parameters as shown in Table 5-4:

Table 5-4 CORS Parameters

CORS Parameter Value

Allow Any Origin

False

Allowed Methods

OPTION

Allowed Origins

www.google.com

Support Preflight Request

true


HTTP Header Filter

Some headers in an incoming (northbound) client request cannot be transferred to the back-end service, and the corresponding response headers cannot be sent back to the client. The following list of headers are filtered from a client request when transferring the request to the back-end service, and from the back-end response when the reply is returned to the client.

Note:

This filter list does not apply to a Groovy or dynamic action with the following APIs when sending to a back end or client:
oracle.sdp.daf.action.api.MessageBuilder#withHeader(String, String)
addHeader(String, String)
withHeaders(Map)
  • proxy-authorization

  • authorization

  • content-length

  • transfer-encoding

  • cookie

  • connection

  • set-cookie

  • host

  • ocsgoauthbearer

  • ocsgoauthmac

  • anonymous

  • ocsgproxy-authorization

  • ocsgsoapheader

  • ocsgappkeyheader

Common Actions Programming Tasks

This section provides more detailed information about tasks that you will probably perform on the request and response messages that action chains.

Also see ”Creating Custom Actions for Your APIs” in Services Gatekeeper Portal Developer's Guide for some Groovy code examples.

Printing and Changing Message Content

To print the contents of a message in the request action chain, you use the getClientRequest operation to the httpContext class, with the getBodyAsType operation to messageBuilder class. For example:

println httpContext.getClientRequest().getBodyAsType(String.class)

Assume that a RESTful request message contains:

{
  "test" : {
    "bob" : "123"
  }
}

You could use this Groovy script to return the value 123:

def body = context.clientRequest.getBodyAsType(org.codehaus.jackson.JsonNode.class);println body.get("test").get("bob").getTextValue()

To print the contents of a message in the response action chain, you use the getSouthBoundResponse operation to the httpContext class, with the getBodyAsType operation to the messageBuilder operation. For example:

println httpContext.getSouthboundResponse().getBodyAsType(String.class)

In a Groovy script you could use:

HttpResponse httpResponse = (HttpResponse) context.getAttribute("myattribute");

And then:

def responseBody = httpResponse.getBodyAsType(org.codehaus.jackson.JsonNode.class);

To change a request action chain message value, you use:

  • The withBodyAsObject(Object) operation. Once changed, you then read only the changed value using the getBodyAsObject(Object) operation. Both are in the messageBuilder class.

  • The withBodyAsStream(input stream) operation. Once changed, you then read only the changed value with the getBodyAsStream operation. Both are in the messageBuilder class.

See the "All Classes" section of the Actions Java API Reference for details on all of these operations and classes.

Using Actions to Manipulate HTTP Query Parameters

During processing by Services Gatekeeper, you can set encoded HTTP query parameters for a request message using any of these components. The components are processed in this order so the last in order makes the final changes:

  1. The URL in the original request message.

  2. The API Service URL that you specify when you create or update the API.

  3. The API resource Path that you set in the Resources table when you create or update the API

  4. An action. You can use either the default Groovy action, or a custom action that you create for this purpose. There are several purpose-built methods in the Actions Java API Reference for this purpose. See "Using a Groovy or Custom Action to Manipulate Query Parameters" for details on these methods. Also see ”Creating Custom Actions for Your APIs” in Services Gatekeeper Portal Developer's Guide for information on how to create a custom action.

Note:

Services Gatekeeper requires encoded query parameters. If you add or change any query parameters, ensure that they are encoded, using no blank spaces or "&" characters. REST-based URLs are encoded by default, but if you add or change any values be sure they are encoded.

Using a Groovy or Custom Action to Manipulate Query Parameters

The Groovy action within an API is the logical place to make changes to request query parameters, because it is the last processing performed for the message. You can use these operations from the CalloutBuilder class for the Actions Java API to manipulate query parameters:

  • Return all query parameters by using getQueryParameters.

  • Return a query string of parameters by using getQueryString.

  • Return a single parameter for a key by using getQueryParameter.

  • Add or overwrite a query parameters using withQueryParameter.

  • Add or overwrite a query parameter string by using the withQueryString.

  • Send a response message without a specific query parameters by using withoutQueryParameter.

  • Ignore all query parameters in the original request message using the ignoreAllRequestQueryParameter flag.

For details on these methods, see the CalloutBuilder class in the "All Classes" section of Actions Java API Reference.

Groovy Query Manipulation Code Examples

These examples use these values for query parameters listed in Table 5-5.

Table 5-5 Example HTTP Query Parameters (Key=Value Pairs)

Request Message API Service URL API Resource Service Path

reqQueryStr1=reqV1

NA

NA

NA

suQueryStr2=suV2

NA

NA

NA

pathQueryStr3=spV3

reqQueryStr4=reqV4

reqQueryStr4=suV4

reqQueryStr4=spV4

NA

suQueryStr5=suV5

suQueryStr5=spV5

reqQueryStr6=reqV6

NA

reqQueryStr6=spV6


Example 5-1 changes the pathQueryStr3 parameter value set by the API Service Path in Table 5-5 to actionV3_1. The full list of query parameters after processing are listed in Table 5-6.

Example 5-1 Using withQueryString to Change a Parameter

context.getSouthboundCallout().withQueryString("pathQueryStr=actionV3_1");

Table 5-6 HTTP Query Parameters After the QueryString Operation

Key Value

reqQueryStr1

reqV1

suQueryStr2

suV2

pathQueryStr3

actionV3_1

reqQueryStr4

spV4

suQueryStr5

spV5

reqQueryStr6

spV6


Example 5-2 shows how to change a string of HTTP query parameters using withoutQueryParameter. Table 5-7 shows the new values after the withoutQueryParameter operation. The reqQueryStr4 key/value pair has been removed. Notice that because withoutQueryParameter (pathQueryStr3) is processed before withQueryParameters, pathQueryStr3 maintains its value.

Example 5-2 withoutQueryParameter Operation

context.getSouthboundCallout().withoutQueryParameter("pathQueryStr3");
context.getSouthboundCallout().withQueryString("pathQueryStr3=actionV3_1");
context.getSouthboundCallout().withQueryParameter("reqQueryStr4=actionV4_2");
context.getSouthboundCallout().withoutQueryParameter("reqQueryStr4");

Table 5-7 HTTP Query Parameters After the withoutQueryParameter Operation

Key Value

reqQueryStr1

reqV1

suQueryStr2

suV2

pathQueryStr3

actionV3_1

suQueryStr5

spV5

reqQueryStr6

reqV1


Example 5-3 shows how ignoreAllRequestQueryParameters affects the list of query parameters. As Table 5-8 shows, it removed all of the query parameters set by the original request message (all reqQueryStrn key/values from Table 5-5).

Example 5-3 ignoreAllRequestQueryParameters Operation

context.getSouthboundCallout().ignoreAllRequestQueryParametersb(true);

Table 5-8 HTTP Query Parameters after ignoreAllRequestQueryParameters Operation

Key Value

suQueryStr2

suV2

pathQueryStr3

spV3

reqQueryStr4

spV4

suQueryStr5

spV5

reqQueryStr6

spV6


Using Actions to Translate Between REST and SOAP

This section explains how to map between SOAP and REST communication using the tools in an actions chain.

REST to SOAP Translation

You use these general steps to translate a REST message to a SOAP message through an actions chain:

  1. Use the Json2Xml action to translate data into the JSON format.

  2. Use the SchemaValidation action to verify the data. You must create your own schema file for this action.

  3. Use the XSLT action to complete the transition to a SOAP format. You create this script.

These actions translate the data to the appropriate formats, but they cannot compensate for the fundamental difference between SOAP and REST communication. REST is resources-based, and depends on methods (GET, POST, PUT, DELETE) to act on resources. SOAP is a much more flexible standard, and not limited to methods. You must convert the REST tasks to tasks that your SOAP components can use by creating an XSLT script for the XSLT action.

During the translation you must think about how to translate the three main components of a REST message into a format that a SOAP-based program can use:

  • The request URI

  • The HTTP method (GET, POST, PUT, DELETE)

  • The message body

Example 5-4 shows code snippets for a simple REST to SOAP translation example. It shows the actions used to translate the x-1 and y-2 key-value pairs from REST format to XML format that SOAP can use.

Example 5-4 A Simple REST to SOAP Translation Using Actions

Original REST Input:
{
  "envelope": {
      "x":1,
      "y":2
  }
}
 
After Json2Xml action:
<envelope>
   <y>2</y>
   <x>1</x>
</envelope>

After XSLT action (final XML output):
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
<soapenv:Header/>
<soapenv:Body>
<cal:add>
<cal:x>1</cal:x>
<cal:y>2</cal:y>
</cal:add>
</soapenv:Body>
</soapenv:Envelope>

This the XSLT action script used in Example 5-4 to translate the JSON data to XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
 
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
 
  <xsl:output method="xml" indent="yes"/>
 
  <xsl:template match="/">
 
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.parasoft.com/wsdl/calculator/">
      <soapenv:Header/>
      <soapenv:Body>
        <cal:add>
          <cal:x><xsl:value-of select="envelope/x"/></cal:x>
          <cal:y><xsl:value-of select="envelope/y"/></cal:y>
        </cal:add>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
 
</xsl:stylesheet>

SOAP to REST Translation

This task is a reverse of the "REST to SOAP Translation" procedure, but it can be significantly harder because of the nature of REST and SOAP communication. REST communication is based on a small number of methods (such as GET, POST, PUT, and DELETE). SOAP is a much more flexible standard. In order to make SOAP communication work for REST, you must translate all SOAP actions into one of the REST methods in the XSLT action. This translation depends entirely upon your implementation.

You use these general steps to translate a SOAP message to the REST format in an actions chain:

  1. Use the XSLT action to translate data into XML format.

  2. Use the SchemaValidation action to verify the data. You must create your own schema file for this action.

  3. Use the Xml2Json action to complete the transition to a format that a REST program can use.

During the translation you need to think about how to translate the three main components of a REST message into a format that a SOAP-based program can use:

  • The request URI

  • The HTTP method (GET, POST, PUT, DELETE)

  • The message body

Transfering Data from Request Chain to Response Chain

The following example shows you how you can transfer data from a request to a response, using a Request and a Response Groovy action (serializable is required on multi-tier):

Request:
Object obj = new Object();context.setAttribute("key", obj)

Response:
Object obj = (Object) context.sgetAttribute("key")

Converting JSON and XML

The Xml2Json action converts incoming XML body content to JSON body content. The following example illustrates:

XML Body Content In:
<SendSms myattribute="foo">
 <addresses>tel:123456</addresses>
 <senderName>senderName</senderName>
 <message>my message 2</message>
</SendSms>

JSON Body Content Out:
{
"SendSms": {
 "message":"my message 2",
 "senderName" : "senderName",
 "addresses" : "tel:123456",
 "@myattribute" : "foo"
 }
}

The Json2XML action transforms JSON to XML. The following example illustrates:

JSON Body Content In:
{
"SendSms": {
 "message":"my message 2",
 "senderName" : "senderName",
 "addresses" : "tel:123456",
 "@myattribute" : "foo"
 }
}

XML Body Content Out:
<SendSms myattribute="foo">
 <addresses>tel:123456</addresses>
 <senderName>senderName</senderName>
 <message>my message 2</message>
</SendSms>

Table 5-9 describes the three Json2XML optional configuration attributes:

Table 5-9 Json2XML Optional Configuration Attributes

Attribute Description Data Type

Instance ID

ID of this action instance

String

Default Name Space

A URI that is added to the first XML tag as the default namespace. The URI format is not enforced.

String

Root Tag

A value that is used to create an enclosing tag to hold the converted XML. Used to avoid multiple roots in the transformed XML

String


Accessing the Customized Data Store

OCSG provides the ability to read and delete data from the customized data store, the database table PRM2_CUSTOMIZEDDATA shown in Figure 5-1:

Figure 5-1 PRM2_CUSTOMIZEDDATA Table

Surrounding text describes Figure 5-1 .

Currently, only a key that is a simple string and a value that is a string are supported.

The class oracle.ocsg.daf.store.CustomizedDataHelper enables you to easily perform create, retrieve, update, and delete (CRUD) operations on the data store. This class is contained in wlng.jar, which is under the directory {OCSG_INSTALL}/ocsg/server/lib/wlng.

This class includes the following Java APIs:

  • public CustomizedDataHelper getInstance()

    Gets the singleton CustomizedDataHelper instance.

    Returns the singleton instance.

  • public CustomizedData storeCustomizedData(CustomizedData data) throws StorageException

    Stores the CustomizedData instance.

    Parameters:

    • data The CustomizedData record to store.

    Returns:

    The previous value associated with theKey element. or null if there was no mapping for theKey.

    Throws:

    StorageException when storing the data fails

  • public CustomizedData retrieveCustomizedData(final String key) throws StorageException

    Retrieves the CustomizedData specified by key.

    Parameters:

    • key A string to match theKey element of the CustomizedData record to be retrieved.

    Returns:

    The matched CustomizedData record, if found; otherwise, null.

    Throws:

    StorageException when retrieval fails

  • public CustomizedData deleteCustomizedData(final String key) throws StorageException

    Deletes the CustomizedData record specified by key.

    Parameters:

    • key A string to match theKey element of the CustomizedData record to be deleted.

    Returns:

    The deleted CustomizedData instance, if found; otherwise null.

    Throws:

    StorageException - When failing to delete the record.

  • public CustomizedData updateCustomizedData( String key, CustomizedData data) throws StorageException

    Updates the CustomizedData record specified by key.

    Parameters:

    • key A string to match theKey element of the CustomizedData record to be updated.

    • data The data to update.

    Returns:

    The old CustomizedData record.

    Throws:

    StorageException - When failing to update the record.

  • public List<CustomizedData> retrieveCustomizedDataItems(String keySearchString, SearchStringOperation operation) throws StorageException

    Gets a list of stored CustomizedData items whose theKey element matches the search string.

    Parameters:

    keySearchString The search string to match theKey of CustomizedData records.

    SearchStringOperation One of the following enumerators that specify how the value of keySearchString should be evaluated:

    • SearchStringOperation.STARTSWITH: The key starts with the search string. Null or empty ("") matches all records.

    • SearchStringOperation.ENDSWITH: the key ends with the search string. Null or empty ("") matches all records.

    • SearchStringOperation.CONTAINS: the key contains the search string. Null or empty ("") matches all records.

    • SearchStringOperation.LIKES: the key likes the search string.

    Returns:

    A list of CustomizedData instances that match the search criteria. If no records match the search string, the list will be empty.

    Throws:

    StorageException - When an error occurs executing the query.

  • public int deleteCustomizedDataItems(String keySearchString, SearchStringOperation operation) throws StorageException

    Deletes the list of stored CustomizedData items whose theKey element matches the search string.

    Parameters:

    keySearchString The search string to match theKey element of CustomizedData records.

    SearchStringOperation One of the following enumerators that specify how the value of keySearchString should be evaluated:

    • SearchStringOperation.STARTSWITH: The key starts with the search string. Null or empty ("") matches all records.

    • SearchStringOperation.ENDSWITH: the key ends with the search string. Null or empty ("") matches all records.

    • SearchStringOperation.CONTAINS: the key contains the search string. Null or empty ("") matches all records.

    • SearchStringOperation.LIKES: the key likes the search string.

    Returns:

    The list of CustomizedData instances that match the search criteria. If no records match the search string, the list will be empty.

    Throws:

    StorageException - When error occurs executing the query.

Examples

Assume that Table 5-10 contains the data that we have in our PRM2_CUSTOMIZEDDATA table:

Table 5-10 Sample Data in PRM2_CUSTOMIZEDDATA Table

theKey Data Stored_TS

search1String1

value1

1,492,756,468,312

search2String2

value2

1,492,756,468,313

searchString3

value3

1,492,756,468,314

searchString4

value4

1,492,756,468,315


The following examples illustrate how this data is affected by various operations.

The first example gets the rows in which the key starts with the specified prefix:

List<CustomizedData> dataList = CustomizedDataHelper.getInstance().retrieveCustomizedDatas("searchString", SearchStringOperation.STARTSWITH);

Result: Returns the third and fourth rows.

The second example deletes the rows in which the key ends with the specified post-fix.

int deletedRowNum = CustomizedDataHelper.getInstance().deleteCustomizedDatas("String4", SearchStringOperation.ENDWITH);

Result: deletedRowNum = 1 and the fourth row is removed.

The third example retrieves the rows in which the key contains the specified string:

List<CustomizedData> dataList = CustomizedDataHelper.getInstance().retrieveCustomizedDatas("String", SearchStringOperation.CONTAINS);

Result: Retrieves all four rows.

The fourth example deletes the rows in which the key likes the specified string.

int deletedRowNum1 = CustomizedDataHelper.getInstance().deleteCustomizedDatas("searchString", SearchStringOperation.LIKES);

Result: deletedRowNum1= 0 and no rows are deleted.

The fifth example gets rows when the search string is null or empty.

List<CustomizedData> allDataList1 = CustomizedDataHelper.getInstance().retrieveCustomizedDatas(null, SearchStringOperation.STARTSWITH);

Result: Retrieves all four rows

The sixth example deletes rows when the search string is null or empty.

int deletedRowNum1 = CustomizedDataHelper.getInstance().deleteCustomizedDatas("", SearchStringOperation.ENDSWITH);

Result: deletedRowNum1 equals 4, and all four rows are deleted

Configuring Chunking for Back-end Services

You can control the chunked setting for southbound callout in Transfer-Encoding, regardless of the incoming request. You can configure the setting globally and also at the request or API level.

Note:

The maximum southbound chunked callout size is 4097 bytes.

Global Configuration

You can set the SouthBoundChunkedSetting item in the DafGeneralInformation MBean to globally configure the chunked handling method once for all. It accepts the following three values, which are case insensitive:

  • PassThrough, which is the default. In this case, the southbound callout will be chunked, or not, in accordance with the incoming request.

  • ForceChunk, which forces Services Gatekeeper to choose chunked when sending southbound callout.

  • ForceNoChunk, which forces Services Gatekeeper to not chunk when sending southbound callout.

Per Request or Per API Configuration

You can also configure chunking on a per request or per API basis to obtain more granularity. You can set chunked either with a special header, ocsg-chunked-setting, in the incoming request or use a Groovy action to add a special header, also called ocsg-chunked-setting, for a specified API. In both cases, post-processing uses this header to override the global setting.

The order of precedence is the Groovy action, followed by the traffic request, and then the global MBean setting.

The ocsg-chunked-setting header takes the same three values as the SouthBoundChunkedSetting item in the DafGeneralInformation MBean: PassThrough, ForceChunk, and ForceNoChunk.

In Figure 5-2, the Groovy script uses the addHeader() method to add the header. You can also use the withHeader() method.

Figure 5-2 Groovy Script Adding Chunking Header

Surrounding text describes Figure 5-2 .

For the Groovy action, instead of using a String to set the special header, you can use the following predefined constant or enums in class oracle.sdp.daf.configurations.SouthBoundChunkedSetting:

  • public static final String CHUNKED_HEADER = "ocsg-chunked-setting"

  • enum

    • PassThrough

    • ForceChunk

    • ForceNoChunk

The following example illustrates a Groovy setting:

context.getSouthboundCallout().withHeader(oracle.sdp.daf.configurations.SouthBoundChunkedSetting.CHUNKED_HEADER, oracle.sdp.daf.configurations.SouthBoundChunkedSetting.ForceChunk.toString())

Understanding the Troubleshooting Action Information in EDRs

Event Data Records (EDRs) contain information to specific to the action chain that you specify. See the ReqAction (Request Action) and RspAction (Response Action) EDR fields in ”Understanding EDR Fields for API Management” in Services Gatekeeper Administrator's Guide for details.