Client Library
Client module which invokes Dynamic Processing Settings should import dynamic-processing-settings-client-port and use ClientPort provided interfaces to invoke DPS logic.
Following Maven dependency should be added into pom.xml:
<dependency>
<groupId>com.iconsolutions.ipf.core.dynamicsettings.v2</groupId>
<artifactId>dynamic-processing-settings-client-port</artifactId>
<version>${dynamic-processing-settings-api.version}</version>
</dependency>
Dynamic processing Settings currently supports connector and direct implementation of client port interfaces.
Connector Implementation
Following Maven dependency should be added into pom.xml:
<dependency>
<groupId>com.iconsolutions.ipf.core.dynamicsettings.v2</groupId>
<artifactId>dynamic-processing-settings-client-connector</artifactId>
<version>${dynamic-processing-settings-api.version}</version>
</dependency>
Direct Implementation
Following Maven dependency should be added into pom.xml:
<dependency>
<groupId>com.iconsolutions.ipf.core.dynamicsettings.v2</groupId>
<artifactId>dynamic-processing-settings-client-direct</artifactId>
<version>${dynamic-processing-settings-api.version}</version>
</dependency>
How to use client library with Connector Implementation
An example how client port can be used:
package com.iconsolutions.ipf.dynamicsettings.v2.client.connector;
import com.iconsolutions.ipf.core.connector.api.Response;
import com.iconsolutions.ipf.core.connector.api.SendingConnector;
import com.iconsolutions.ipf.core.shared.domain.context.ProcessingContext;
import com.iconsolutions.ipf.core.shared.domain.context.SupportingContext;
import com.iconsolutions.ipf.dynamicsettings.v2.client.connector.request.approvals.ApproveSettingRequest;
import com.iconsolutions.ipf.dynamicsettings.v2.client.connector.request.approvals.GetApprovalsRequest;
import com.iconsolutions.ipf.dynamicsettings.v2.client.connector.request.approvals.RejectSettingRequest;
import com.iconsolutions.ipf.dynamicsettings.v2.client.port.DpsApprovalClientPort;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.ApprovalSettingsDTO;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.ApproveSetting;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.RejectSetting;
import com.iconsolutions.ipf.dynamicsettings.v2.domain.SettingId;
import com.iconsolutions.ipf.dynamicsettings.v2.domain.SettingType;
import lombok.RequiredArgsConstructor;
import java.util.concurrent.CompletionStage;
//tag::approvalsClientConnector[]
@RequiredArgsConstructor
public class DpsApprovalClientConnector implements DpsApprovalClientPort {
private final SendingConnector<ApproveSettingRequest, Response<String>> approveSettingConnector;
private final SendingConnector<GetApprovalsRequest, Response<ApprovalSettingsDTO<Object>>> getApprovalsSettingConnector;
private final SendingConnector<RejectSettingRequest, Response<String>> rejectSettingsConnector;
@Override
public CompletionStage<Response<ApprovalSettingsDTO<Object>>> getApprovalsSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, SettingId settingId) {
return getApprovalsSettingConnector.send(processingContext,
GetApprovalsRequest.builder()
.settingId(settingId)
.settingType(settingType)
.build(),
supportingContext);
}
@Override
public CompletionStage<Response<String>> approveSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, ApproveSetting approveSetting, SettingId settingId) {
return approveSettingConnector.send(processingContext,
ApproveSettingRequest.builder()
.settingType(settingType)
.approveSetting(approveSetting)
.settingId(settingId)
.build(),
supportingContext);
}
@Override
public CompletionStage<Response<String>> rejectSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, SettingId settingId, RejectSetting rejectSetting) {
return rejectSettingsConnector.send(processingContext,
RejectSettingRequest.builder()
.settingType(settingType)
.rejectSetting(rejectSetting)
.settingId(settingId)
.build(),
supportingContext);
}
}
//end::approvalsClientConnector[]
How to use client library with Direct Implementation
An example how client port can be used:
package com.iconsolutions.ipf.dynamicsettings.v2.client.direct;
import com.iconsolutions.ipf.core.connector.api.Response;
import com.iconsolutions.ipf.core.shared.domain.context.ProcessingContext;
import com.iconsolutions.ipf.core.shared.domain.context.SupportingContext;
import com.iconsolutions.ipf.dynamicsettings.v2.api.DpsApprovalService;
import com.iconsolutions.ipf.dynamicsettings.v2.client.port.DpsApprovalClientPort;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.ApprovalSettingsDTO;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.ApproveSetting;
import com.iconsolutions.ipf.dynamicsettings.v2.dto.RejectSetting;
import com.iconsolutions.ipf.dynamicsettings.v2.domain.SettingId;
import com.iconsolutions.ipf.dynamicsettings.v2.domain.SettingType;
import lombok.RequiredArgsConstructor;
import java.util.concurrent.CompletionStage;
//tag::approvalsClientDirect[]
@RequiredArgsConstructor
public class DpsApprovalClientDirect implements DpsApprovalClientPort {
private final DpsApprovalService service;
@Override
public CompletionStage<Response<ApprovalSettingsDTO<Object>>> getApprovalsSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, SettingId settingId) {
return service.getApprovals(settingType)
.collectList()
.map(ApprovalSettingsDTO::new)
.map(approvalSettingsDTO -> new Response<>(processingContext, approvalSettingsDTO))
.toFuture();
}
@Override
public CompletionStage<Response<String>> approveSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, ApproveSetting approveSetting, SettingId settingId) {
return service.approveSetting(settingType, settingId, approveSetting)
.toFuture()
.thenApply(res -> new Response<>(processingContext, ""));
}
@Override
public CompletionStage<Response<String>> rejectSetting(ProcessingContext processingContext, SupportingContext supportingContext, SettingType settingType, SettingId settingId, RejectSetting rejectSetting) {
return service.rejectSetting(settingType, settingId, rejectSetting)
.toFuture()
.thenApply(res -> new Response<>(processingContext, ""));
}
}
//end::approvalsClientDirect[]
How to configure client library
Each API connector can be set up independently, but we also provide default connector configuration.
HTTP client configuration:
Connector Implementation
//tag::approvalsClientConnectorConfig[]
ipf.dps-api {
client-type = "connector"
http {
client {
host = "localhost"
endpoint-url = "/settings-objects/"
port = 8080
}
}
connector {
create-setting = ${ipf.dps-api.default-connector}
update-setting = ${ipf.dps-api.default-connector}
delete-setting = ${ipf.dps-api.default-connector}
get-setting = ${ipf.dps-api.default-connector}
search-setting = ${ipf.dps-api.default-connector}
search-ids-setting = ${ipf.dps-api.default-connector}
search-request-setting = ${ipf.dps-api.default-connector}
setting-schemas = ${ipf.dps-api.default-connector}
history-settings = ${ipf.dps-api.default-connector}
approve-settings = ${ipf.dps-api.default-connector}
get-approvals-setting = ${ipf.dps-api.default-connector}
reject-setting = ${ipf.dps-api.default-connector}
}
default-connector {
resiliency-settings {
# Determines the maximum number of retries to be made. Note that this includes the first failed attempt.
max-attempts = 2
# Retry if HTTP error code is in the list
retryable-status-codes = [500, 503]
# 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.
minimum-number-of-calls = 10
}
}
}
//end::approvalsClientConnectorConfig[]
Direct Implementation
//tag::approvalsClientDirectConfig[]
ipf.dps-api.client-type = "direct"
//end::approvalsClientDirectConfig[]