PingGateway 2024.11

ClientHandler

Sends requests to third-party services that are accessible through HTTP, and reconstructs the response from the received bytes. A third-party service is one that PingGateway calls for data, such as an HTTP API or AM, or one to which PingGateway submits data. When PingGateway relays a request to a third-party service, PingGateway is acting as a client of the service. PingGateway is client-side.

Consider the following comparison of the ClientHandler and ReverseProxyHandler:

ClientHandler ReverseProxyHandler

Use this handler to …​

Send requests to third-party services accessed within a route. The service can be AM or an HTTP API. The service can be an HTTP endpoint, such as AM, IDM, PingOne Advanced Identity Cloud, or any custom HTTP API.

Send requests to the final service accessed by a route. The service can be the final downstream application.

If the service doesn’t respond in time, this handler …​

Propagates the error through the Promise flow.

If the error is not handled within the route, for example, by a FailureHandler, the handler returns a 500 Internal Server Error response.

Stops processing the request, and returns a 502 Bad Gateway response.

When uploading or downloading large files, prevent timeout issues by increasing the value of soTimeout, and using a streaming mode, as follows:

Configure the streamingEnabled property of AdminHttpApplication.

Usage

{
  "name": string,
  "type": "ClientHandler",
  "config": {
    "vertx": object,
    "connections": configuration expression<number>,
    "waitQueueSize": configuration expression<number>,
    "soTimeout": configuration expression<duration>,
    "connectionTimeout": configuration expression<duration>,
    "protocolVersion": configuration expression<enumeration>,
    "http2PriorKnowledge": configuration expression<boolean>,
    "proxyOptions": ProxyOptions reference,
    "propagateDisconnection": configuration expression<boolean>,
    "temporaryStorage": TemporaryStorage reference,
    "tls": ClientTlsOptions reference,
    "retries": {
      "enabled": configuration expression<boolean>,
      "condition": runtime expression<boolean>,
      "executor": ScheduledExecutorService reference,
      "count": configuration expression<number>,
      "delay": configuration expression<duration>,
      "runtimeExceptionCondition": runtime expression<boolean>
    },
    "circuitBreaker": {
      "enabled": configuration expression<boolean>,
      "maxFailures":  configuration expression<integer>,
      "slidingCounter": {
        "size": configuration expression<number>
      },
      "openDuration": configuration expression<duration>,
      "openHandler": Handler reference,
      "executor":  ScheduledExecutorService reference
    },
    "hostnameVerifier": configuration expression<enumeration>, //deprecated
    "proxy": Server reference, //deprecated
    "systemProxy": boolean //deprecated
  }
}

Properties

vertx

"vertx": object, optional

Vert.x-specific configuration for the handler when PingGateway is client-side. When PingGateway is acting server-side, configure the connectors.vertx property of admin.json.

When PingGateway sends requests to a proxied application or requests services from a third-party application, PingGateway is client-side. PingGateway is acting as a client of the application. The application is acting as a server.

Learn more about Vert.x options in HttpClientOptions.

The vertx object is read as a map, and values are evaluated as configuration expressions.

For properties where PingGateway provides its own first-class configuration, Vert.x configuration options are disallowed. The PingGateway configuration option takes precedence over Vert.x options configured in vertx. The following Vert.x configuration options are disallowed client-side:

  • alpnVersions

  • connectTimeout

  • enabledCipherSuites

  • enabledSecureTransportProtocols

  • http2ClearTextUpgrade

  • idleTimeout

  • idleTimeoutUnit

  • keyCertOptions

  • keyStoreOptions

  • maxWaitQueueSize

  • pemKeyCertOptions

  • pemTrustOptions

  • pfxKeyCertOptions

  • pfxTrustOptions

  • port

  • protocolVersion

  • proxyOptions

  • ssl

  • trustOptions

  • trustStoreOptions

  • useAlpn

  • verifyHost

The following example configures the Vert.x configuration when PingGateway is acting client-side:

{
  "vertx": {
    "maxWebSocketFrameSize": 128000,
    "maxWebSocketMessageSize": 256000,
    "compressionLevel": 4,
    "maxHeaderSize": 16384
  }
}

The following example configures HTTP/2 connections when PingGateway is acting client-side. The configuration allows PingGateway to make HTTP/2 requests with large headers:

{
  "vertx": {
    "initialSettings": {
      "maxHeaderListSize": 16384
    }
  }
}

connections

"connections": configuration expression<number>, optional

The maximum number of concurrent HTTP connections in the client connection pool.

Default: 64

waitQueueSize

“waitQueueSize”: configuration expression<number>, optional

The maximum number of outbound requests allowed to queue when no downstream connections are available. Outbound requests received when the queue is full are rejected.

Use this property to limit memory use when there is a backlog of outbound requests, for example, when the protected application or third-party service is slow.

Configure waitQueueSize as follows:

  • Not set (default): The wait queue is calculated as the square of connections.

    • If connections isn’t configured, then its default of 64 is used, giving the waitQueueSize of 4096.

    • If the square of connections exceeds the maximum integer value for the Java JVM, the maximum integer value for the Java JVM is used.

  • -1: The wait queue is unlimited. Requests received when there are no available connections are queued without limit.

  • 0: There is no wait queue. Requests received when there are no available connections are rejected.

  • A value that is less than the square of connections:

    When the configuration is loaded, the configured value is used. PingGateway generates a warning that the waitQueueSize is too small for the connections size and recommends a different value.

  • A value where waitQueueSize plus connections exceeds the maximum integer value for the Java JVM:

    When the configuration is loaded, the waitQueueSize is reduced to the maximum integer value for the Java JVM minus the value of connections. PingGateway logs a warning.

Consider the following example configuration of connections and waitQueueSize:

{
  "handler" : {
    "name" : "proxy-handler",
    "type" : "ReverseProxyHandler",
    "MyCapture" : "all",
    "config": {
      "soTimeout": "10 seconds",
      "connectionTimeout": "10 seconds",
      "connections": 64,
      "waitQueueSize": 100
    }
  },
  "baseURI" : "https://app.example.com:8444",
  "condition" : "${find(request.uri.path, '/')}"
}

PingGateway can propagate the request to the sample application using 64 connections. When the connections are consumed, up to 100 requests are queued until a connection is freed. Effectively PingGateway can accommodate 164 requests, although user concurrency delay means more may be handled. Requests received when the waitQueue is full are rejected.

Default: Not set

connectionTimeout

"connectionTimeout": configuration expression<duration>, optional

Time to wait to establish a connection, expressed as a duration.

Default: 10 seconds

protocolVersion

"protocolVersion": configuration expression<enumeration>, optional

The version of HTTP protocol to use when processing requests:

  • HTTP/2:

    • For HTTP, process requests using HTTP/1.1.

    • For HTTPS, process requests using HTTP/2.

  • HTTP/1.1:

    • For HTTP and HTTPS, process requests using HTTP/1.1.

  • Not set (default):

    • For HTTP, process requests using HTTP/1.1.

    • For HTTPS with alpn enabled in ClientTlsOptions, process requests using HTTP/1.1 with an HTTP/2 upgrade request. If the targeted server can use HTTP/2, the client uses HTTP/2.

      For HTTPS with alpn disabled in ClientTlsOptions, process requests using HTTP/1.1 without an HTTP/2 upgrade request.

      By default, alpn is enabled in ClientTlsOptions.

Default: Not set

In HTTP/1.1 request messages, a Host header is required to specify the host and port number of the requested resource. In HTTP/2 request messages, the Host header isn’t available.

In scripts or custom extensions that use HTTP/2, use UriRouterContext.originalUri.host or UriRouterContext.originalUri.port in requests.

http2PriorKnowledge

"http2PriorKnowledge": configuration expression<boolean>, optional

A flag for whether the client should have prior knowledge that the server supports HTTP/2. This property is for cleartext (non-TLS requests) only and is used only when protocolVersion is HTTP/2.

  • false: The client checks whether the server supports HTTP/2 by sending an HTTP/1.1 request to upgrade the connection to HTTP/2:

    • If the server supports HTTP/2, the server upgrades the connection to HTTP/2 and later requests are processed over HTTP/2.

    • If the server doesn’t support HTTP/2, the connection isn’t upgraded and later requests are processed over HTTP/1.

  • true: The client doesn’t check that the server supports HTTP/2. The client sends HTTP/2 requests to the server, assuming that the server supports HTTP/2.

Default: false

proxyOptions

"proxyOptions": ProxyOptions reference, optional

A proxy server to which requests can be submitted. Use this property to relay requests to other parts of the network. For example, use it to submit requests from an internal network to the internet.

Provide the name of a ProxyOptions object defined in the heap or an inline configuration.

Default: A heap object named ProxyOptions.

propagateDisconnection

"propagateDisconnection": configuration expression<boolean>, optional

Use this setting to stop streaming content to a browser that disconnects.

When "propagateDisconnection": true, PingGateway disconnects from the remote application when:

  • The user-agent disconnects from PingGateway.

  • Streaming is enabled for PingGateway.

  • The response includes the header Transfer-Encoding: chunked.

When changing this setting, also consider reducing logging when propagating disconnections.

Default: false

soTimeout

"soTimeout": configuration expression<duration>, optional

Socket timeout, after which stalled connections are destroyed, expressed as a duration.

If PingGateway logs SocketTimeoutException errors when you try to upload or download large files, increase soTimeout.

Default: 10 seconds

temporaryStorage

"temporaryStorage": TemporaryStorage reference, optional

The TemporaryStorage object to buffer the request and response when the streamingEnabled property of admin.json is false.

Default: A heap object named TemporaryStorage.

tls

tls: ClientTlsOptions reference, optional

Configure options for connections to TLS-protected endpoints with a ClientTlsOptions configuration. Define the object inline or in the heap.

Default: Connections to TLS-protected endpoints aren’t configured.

retries

"retries": object, optional

Enable and configure retry for requests.

During the execution of a request to a remote server, if a condition is met, a runtime exception occurs, or a matching runtime exception condition is met, PingGateway waits for a delay, then schedules a new execution of the request. PingGateway tries until the allowed number of retries is reached or the execution succeeds.

A warning-level entry is logged if all retry attempts fail; a debug-level entry is logged if a retry succeeds.

The following example configures a retry when a downstream component returns a 502 Bad Gateway response code:

{
  "retries": {
    "enabled": true,
    "condition": "${response.status.code == 502}"
  }
}

The following example configures the handler to retry the request only once, after a 1-minute delay:

{
  "retries": {
    "count": 1,
    "delay": "1 minute"
  }
}

The following example configures the handler to retry the request at most 20 times per second:

{
  "retries": {
    "count": 20,
    "delay": "1 second"
  }
}

The following example retries the request only when a runtime expression for an HTTP/2 GOAWAY error occurs:

{
    "retries": {
        "enabled": true,
        "runtimeExceptionCondition": "${exception.message.contains(\"GOAWAY\")}"
    }
}

The following example configures the handler to retry the request 5 times every 10 seconds (default values) with a dedicated executor:

{
  "retries": {
    "executor": {
      "type": "ScheduledExecutorService",
      "config": {
        "corePoolSize": 20
      }
    }
  }
}
"enabled": configuration expression<boolean>, optional

Enable retries.

Default: true

"condition": runtine expression<boolean>, optional

An inline PingGateway expression to define a condition based on the response, such as an error code.

The condition is evaluated as follows:

  • If true, PingGateway retries the request until the count is reached.

  • If false, PingGateway retries the request only if a runtime exception occurs until the count is reached.

Default: ${false}

"executor": ScheduledExecutorService reference, optional

The ScheduledExecutorService to use for scheduling delayed execution of the request.

Default: ScheduledExecutorService

"count": configuration expression<number>, optional

The maximum number of retries to perform. After this threshold is passed and if the request is still not successful, the ClientHandler propagates the failure.

Retries caused by any runtime exception or triggered condition are included in the count.

Default: 5

"delay": configuration expression<duration>, optional

The time to wait before retrying the request.

After a failure to send the request, if the number of retries is below the threshold, a new attempt is scheduled with the executor service after this delay.

Default: 10 seconds

"runtimeExceptionCondition": runtine expression<boolean>, optional

An inline expression to define a condition when a runtime exception occurs. The context, request, and exception are available in the expression.

  • If true, PingGateway retries the request until the value in count is reached.

  • If false, PingGateway doesn’t retry the request.

Default: When this isn’t set, retry when any runtime exception occurs.

circuitBreaker

"circuitBreaker": object, optional

Enable and configure a circuit breaker to trip when the number of failures exceeds a configured threshold. Calls to downstream services are stopped and a runtime exception is returned. The circuit breaker is reset after the configured delay.

"enabled": configuration expression<boolean>, optional

A flag to enable the circuit breaker.

Default: true

"maxFailures": configuration expression<number>, required

The maximum number of failed requests allowed in the window given by size, before the circuit breaker trips. The value must be greater than zero.

When retries is set, the circuit breaker doesn’t count retried requests as failures. Keep this in mind when you set maxFailures.

In the following example, a request can fail and then be retried three times. If it fails the third retry, the request has failed four times, but the circuit breaker counts only one failure.

{
  "retries": {
    "count": 3,
    "delay": "1 second"
  }
}
"openDuration": configuration expression<duration>, required

The duration for which the circuit stays open after the circuit breaker trips. The executor schedules the circuit to be closed after this duration.

"slidingCounter": object, required

A sliding window error counter. The circuit breaker trips when the number of failed requests in the number of requests given by size reaches maxFailures.

The following image illustrates how the sliding window counts failed requests:

Example sliding window error counter.
"size": configuration expression<number>, required

The size of the sliding window in which to count errors.

The value of size must be greater than zero and greater than the value of maxFailures, otherwise PingGateway throws an exception.

"openHandler": Handler reference, optional

The Handler to call when the circuit is open.

Default: A handler that throws a RuntimeException with a "circuit-breaker open" message.

"executor": ScheduledExecutorService reference, optional

A ScheduledExecutorService to schedule closure of the circuit after the duration given by openDuration.

Default: The default ScheduledExecutorService in the heap

hostnameVerifier (deprecated)

"hostnameVerifier": configuration expression<enumeration>, optional

This property is deprecated. Use the tls property instead to configure ClientTlsOptions. Learn more in the Deprecated section of the Release Notes.

The way to handle hostname verification for outgoing SSL connections. Use one of the following values:

  • ALLOW_ALL: Allow a certificate issued by a trusted CA for any hostname or domain to be accepted for a connection to any domain.

    This setting allows a certificate issued for one company to be accepted as a valid certificate for another company. To prevent the compromise of TLS connections, use this setting in development mode only. In production, use STRICT.

  • STRICT: Match the hostname either as the value of the first CN or any of the subject-alt names.

    A wildcard can occur in the CN, and in any of the subject-alt names. Wildcards match one domain level, so *.example.com matches www.example.com but not some.host.example.com.

Default: STRICT

proxy (deprecated)

"proxy": Server reference, optional

This property is deprecated. Use proxyOptions instead. Learn more in the Deprecated section of the Release Notes.

A proxy server to which requests can be submitted. Use this property to relay requests to other parts of the network. For example, use it to submit requests from an internal network to the internet.

If both proxy and systemProxy are defined, proxy takes precedence.

"uri": configuration expression<uri string>, required

URI of a server to use as a proxy for outgoing requests.

The result of the expression must be a string that represents a valid URI but isn’t a real java.net.URI object.

"username": configuration expression<string>, required if the proxy requires authentication

Username to access the proxy server.

"passwordSecretId": configuration expression<secret-id>, required if the proxy requires authentication

The secret ID of the password to access the proxy server.

This secret ID must point to a GenericSecret.

"secretsProvider": SecretsProvider reference, required

The SecretsProvider to query for the proxy’s password.

systemProxy (deprecated)

"systemProxy": boolean, optional

This property is deprecated. Use proxyOptions instead. Learn more in the Deprecated section of the Release Notes.

Submit outgoing requests to a system-defined proxy, set by the following system properties or their HTTPS equivalents:

  • http.proxyHost, the host name of the proxy server.

  • http.proxyPort, the port number of the proxy server. The default is 80.

  • http.nonProxyHosts, a list of hosts that should be reached directly, bypassing the proxy.

This property can’t be used with a proxy that requires a username and password.

If both proxy and systemProxy are defined, proxy takes precedence.

Default: false