Documentation for a newer release is available. View Latest

Connector Configuration

The configuration for a Connector can be set in IPF configuration files. This section explains the various configuration options available for the various types of connector, their default values, and the fallback mechanism which allows you to only supply a partial config and otherwise use the defaults documented below.

Configuration Options

Sending Connectors

The allowed configuration options for a sending connector (send connector & request-reply connectors) are:

Property Name

Description

Type

Default Value

manual-start

When set to false, the connector is started automatically after creation; otherwise, its start method must be invoked manually.

Boolean

false

queue-size

Size of a source queue which can be used to handle backpressure, for example fast producer situations.

Integer

50

call-timeout

Maximum duration to wait for an acknowledgement before completing the returned future exceptionally with a TimeoutException.

Duration

30s

correlation-stage-timeout

This setting prevents delayed responses from attempting to persist to the correlation store from being processed once the call-timeout has been elapsed, thereby causing a message to be sent despite a delivery failure indicating the contrary. NOTE: This should always be less than the call-timeout, an exception will be thrown if this is not the case and application startup will fail if the call-timeout is less than correlation-stage-timeout

Duration

5s

max-concurrent-offers

Maximum number of pending offers when buffer is full.

Integer

500

parallelism

Maximum number of parallel calls for send connector

Integer

500

parallelism-per-partition

Maximum number of parallel sends per UnitOfWorkId. Must be less than parallelism.

Integer

1

throttle-count

Limits the throughput to a specified number of consumed messages per time unit. When this value is set, throttle-duration must also be provided.

Integer

Not set

throttle-duration

Is used with 'throttle-count' to set the maximum rate for consuming messages. For more details, see the Message Throttling documentation.

Duration

Not set

resiliency-settings

The resiliency settings for this connector, please see Resiliency Settings

ResiliencyConfig

default resiliency config

Receiving Connectors

The allowed configuration for a receiving connector is:

Property Name Description Type Default Value

manual-start

When set to false, the connector is started automatically after creation; otherwise, its start method must be invoked manually.

Boolean

true

throttle-count

If the value is set, limits the throughput to a specified number of consumed messages per time unit. If it is set. If this value is set, throttle-duration also needs to be set.

Integer

Not set

throttle-duration

If set, it is used along with throttle-count to set the maximum rate for consuming messages. For more details, see doc.akka.io/japi/akka/2.6/akka/stream/javadsl/Flow.html#throttle(int,java.time.Duration)

Duration

Not set

mapping-parallelism

If set, limits the number of concurrent mapping operations executed on consumed messages.

Integer

number of available processors

receiver-parallelism-type

Defines the way messages are handled in parallel. Available options:

  • ORDERED - messages are consumed in parallel in the order they are received, and they are acknowledged in the same order

  • ORDERED_PARTITIONED - messages are consumed in parallel in the order they are received, and they are acknowledged in the same order, but the parallelism for messages sharing the UnitOfWorkId is capped to a configurable degree

  • UNORDERED - messages are consumed in parallel in the order they are received, and they are acknowledged in the their completion order, which may impact some transports (e.g. Kafka)

Enum

ORDERED_PARTITIONED

receiver-parallelism

If set, limits the number of mapped messages that are allowed to be processed concurrently.

Integer

number of available processors

receiver-parallelism-per-partition

Only applied if receiver-parallelism-type is set to ORDERED_PARTITIONED. If set, limits the number of mapped messages per UnitOfWorkId that are allowed to be processed concurrently. Must be less than receiver-parallelism.

Integer

1

resiliency-settings

The resiliency settings for this connector, please see Resiliency Settings

ResiliencyConfig

default resiliency config

Resiliency Settings

Both the sending and receiving connector config enable defining the resiliency config using a 'resiliency-settings' block. Most of the properties in this block are used to set the configuration values for the Resilience4j retry and circuit breaker configuration, which is utilised to wrap calls with circuit breaking, fallback or routing, and retries. Note that, as some Resilience4j configurations can conflict with one another, not all parameters from this library are exposed in this settings block. In addition, some of the Resilience4j default values have been overridden in this block to better align with the requirements of an IPF application.

Property Name Description Type Resilience4j equivalent Default Value Config

enabled

It allows resiliency to be toggled on / off

Boolean

n/a

true

yes

minimum-number-of-calls

Determines the minimum number of calls (within a sliding window period) that need to be made before the circuit breaker can calculate the error rate to determine the transport health.

Integer

minimumNumberOfCalls

1

yes

max-attempts

Determines the maximum number of retries to be made. Note that this includes the first failed attempt.

Integer

maxAttempts

1

yes

attempt-timeout

How long to wait for a single attempt to complete before failing it.

Duration

n/a

30s

yes

reset-timeout

How long to wait while in the OPEN state before transitioning to HALF_OPEN and attempting to close the circuit.

Duration

waitDurationInOpenState

1s

yes

initial-retry-wait-duration

How long to wait before retrying. This sets the initial duration and may increase on successive retry attempts due to the backoff multiplier.

Duration

One half of the intervalFunction.

1s

yes

backoff-multiplier

Each successive retry will wait the previous wait duration multiplied by the backoff multiplier.

Integer

Second half of the intervalFunction.

2

yes

retry-on-failure-when

Given an exception thrown by the decorated code, returns a boolean to determine whether to retry. This is to avoid retrying on exceptions where multiple attempts will not resolve the failure.

Boolean

n/a

true

yes

retry-on-result-when

Given a successful result, i.e. no exception was thrown, returns a boolean to determine whether to retry. This is used to trigger retries based on the object returned from the decorated code in a receiving connector.

Boolean

retryOnResult

false

yes

fail-after-max-attempts

A boolean to enable or disable throwing of MaxRetriesExceededException when the Retry has reached the configured maxAttempts, and the result is still not passing the retryOnResultPredicate

Boolean

failAfterMaxAttempts

false

yes

failure-rate-threshold

When the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls.

Double

failureRateThreshold

50

yes

slow-call-rate-threshold

The CircuitBreaker considers a call as slow when the call duration is greater than slowCallDurationThreshold. When the percentage of slow calls is equal or greater the threshold, the CircuitBreaker transitions to open and starts short-circuiting calls.

Double

slowCallRateThreshold

100

yes

slow-call-duration-threshold

Configures the duration threshold above which calls are considered as slow and increase the rate of slow calls.

Duration

slowCallDurationThreshold

60000ms

yes

max-wait-duration-in-half-open-state

When set to 0ms it is not actually being set any other timing will actually set the variable

Duration

maxWaitDurationInHalfOpenState.

0ms

yes

permitted-number-of-calls-in-half-open-state

Configures the number of permitted calls when the CircuitBreaker is half open.

Integer

permittedNumberOfCallsInHalfOpenState

10

yes

sliding-window-size

Configures the size of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed.

Integer

slidingWindowSize

100

yes

sliding-window-type

If the sliding window is COUNT_BASED, the last slidingWindowSize calls are recorded and aggregated. If the sliding window is TIME_BASED, the calls of the last slidingWindowSize seconds recorded and aggregated.

SlidingWindowType

slidingWindowType

COUNT_BASED

yes

automatic-transition-from-open-to-half-open

If set to true it means that the CircuitBreaker will automatically transition from open to half-open state and no call is needed to trigger the transition. A thread is created to monitor all the instances of CircuitBreakers to transition them to HALF_OPEN once waitDurationInOpenState passes. Whereas, if set to false the transition to HALF_OPEN only happens if a call is made, even after waitDurationInOpenState is passed. The advantage here is no thread monitors the state of all CircuitBreakers.

Boolean

automaticTransitionFromOpenToHalfOpenEnabled

true

yes

retry-scheduler-thread-pool-size

Determines how many threads the retry scheduler can use.

Integer

n/a

number of available processors

no

reroute-messages-on-failure

Given a failure result, returns a boolean to determine whether to re-submit messages into the queue

Boolean

n/a

Calls retryOnFailureWhen predicate or value of retry-on-failure-when

no

retryExceptions

You will need to specify the whole class path and the class name for it to work correctly for example, java.lang.String. It also has to be a class that extends java.lang.Throwable

List<String> in config. List<Class<Throwable>>

retryExceptions and recordExceptions.

null

no

ignoreExceptions

You will need to specify the whole class path and the class name for it to work correctly for example, java.lang.String. It also has to be a class that extends java.lang.Throwable

List<String> in config. List<Class<Throwable>>

ignoreExceptions

[]

no

retry-on-send-result-when

Given a successful result, i.e. no exception was thrown, returns a boolean to determine whether to retry. This is used to trigger retries based on the object returned from the decorated code in a sending connector. An example of where this may be useful is if a http server responds with a successful http response code to a request, but the response body contains error details that indicates a retry may be necessary.

Boolean

retryOnResult.

Returns true when the returned DeliveryOutcome is a failure and retryOnFailureWhen returns true for the exception that caused the failure

no

recordException

Configures a Predicate which evaluates if an exception should be recorded as a failure and thus increase the failure rate. The Predicate must return true if the exception should count as a failure. The Predicate must return false, if the exception should count as a success, unless the exception is explicitly ignored by ignoreExceptions(Class[]) or ignoreException(Predicate).

Predicate<Throwable>

recordException

null

no

ignoreException

Configures a Predicate which evaluates if an exception should be ignored and neither count as a failure nor success. The Predicate must return true if the exception should be ignored. The Predicate must return false, if the exception should count as a failure.

Predicate<Throwable>

ignoreException

null

no

Default Configuration

All connectors come with a pre-defined set of base configuration which will be used if not overridden at the point of construction of the connector.

The default configuration is provided below, and matches that defined in the previous section.

ipf.connector {
  default-receive-connector {
    manual-start = true
    receiver-parallelism-type = ORDERED_PARTITIONED
    receiver-parallelism-per-partition = 1
    resiliency-settings = ${ipf.connector.default-resiliency-settings}
  }

  default-send-connector {
    manual-start = false
    call-timeout = 30s
    queue-size = 50
    max-concurrent-offers = 500
    parallelism = 500
    parallelism-per-partition = 1
    send-message-association = true
    resiliency-settings = ${ipf.connector.default-resiliency-settings}
  }
}

ipf.connector {
  default-resiliency-settings {
    enabled = true
    minimum-number-of-calls = 1
    max-attempts = 1
    attempt-timeout = 30s
    attempt-timeout = ${?ipf.connector.default-send-connector.call-timeout}
    reset-timeout = 1s
    initial-retry-wait-duration = 1s
    backoff-multiplier = 2
    retry-on-failure-when = true
    retry-on-result-when = false
    fail-after-max-attempts = false
    failure-rate-threshold = 50
    slow-call-rate-threshold = 100
    slow-call-duration-threshold = 60000ms
    max-wait-duration-in-half-open-state = 0ms
    permitted-number-of-calls-in-half-open-state = 10
    sliding-window-size = 100
    sliding-window-type = COUNT_BASED
    automatic-transition-from-open-to-half-open = true
    retry-exceptions = []
    ignore-exceptions = []
  }
}

Using Configuration

When constructing a connector, it is possible to override these properties by providing a configRoot. When provided, the connector will use this configRoot as the base of the properties to use. So for example, if we construct a connector like:

var sendConnector = new SendConnector.Builder<String, String>("TestConnector")
    .withActorSystem(actorSystem) (1)
    .withConfigRoot("test-config") (2)
    .build();

Here we are supplying both:

1 the ActorSystem
2 the config root - a string value.

We are telling our connector that our config root here is test-config. What this means is that where in our default connector settings, the send connector defaults are at ipf.connector.default-send-connector, here we will use test-config as the primary config and then ipf.connector.default-send-connector as the fallback.

To illustrate this, suppose we were to set the config file like:

test-config {
    parallelism = 700
    manual-start = false
}

Here we are defining new configuration values for parallelism and manual-start. We could just as easily have provided the config values for the other properties. By only supplying these two, our connector will then have:

  1. A parallelism of 700

  2. A manual-start setting of false.

  3. All other properties inherited from the default config, so for example the queue-size will be set to 50.

We can also supply overrides to the configuration settings in the constructor through our java code. So for example, consider the following setup:

var sendConnector = new SendConnector.Builder<String, String>("TestConnector")
    .withActorSystem(actorSystem)
    .withParallelism(700)
    .withManualStart(false)
    .build();

This would lead to the same connector being built as per our configuration implementation.