Add alter threeds (#64)

This commit is contained in:
struga 2023-03-10 15:38:28 +07:00 committed by GitHub
parent abb37c3447
commit 540e49b59e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 285 additions and 223 deletions

View File

@ -12,7 +12,7 @@
</parent>
<artifactId>adapter-flow-lib</artifactId>
<version>0.1.22</version>
<version>0.1.23</version>
<packaging>jar</packaging>
<name>adapter-flow-lib</name>

View File

@ -4,7 +4,7 @@ import dev.vality.adapter.flow.lib.converter.ExitStateModelToTemporaryContextCon
import dev.vality.adapter.flow.lib.flow.RecurrentResultIntentResolver;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.serde.TemporaryContextSerializer;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.utils.AdditionalInfoUtils;
import dev.vality.damsel.domain.TransactionInfo;
import dev.vality.damsel.proxy_provider.RecurrentTokenIntent;
@ -17,7 +17,7 @@ import java.util.HashMap;
@RequiredArgsConstructor
public class ExitModelToRecTokenProxyResultConverter implements Converter<ExitStateModel, RecurrentTokenProxyResult> {
private final RecurrentIntentResultFactory recurrentIntentResultFactory;
private final SimpleRecurrentIntentResultFactory recurrentIntentResultFactory;
private final TemporaryContextSerializer serializer;
private final RecurrentResultIntentResolver recurrentResultIntentResolver;
private final ExitStateModelToTemporaryContextConverter contextConverter;

View File

@ -3,14 +3,14 @@ package dev.vality.adapter.flow.lib.flow.full;
import dev.vality.adapter.flow.lib.constant.Step;
import dev.vality.adapter.flow.lib.flow.RecurrentResultIntentResolver;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.damsel.proxy_provider.RecurrentTokenIntent;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class GenerateTokenResultIntentResolverImpl implements RecurrentResultIntentResolver {
private final RecurrentIntentResultFactory recurrentIntentResultFactory;
private final SimpleRecurrentIntentResultFactory recurrentIntentResultFactory;
@Override
public RecurrentTokenIntent initIntentByStep(ExitStateModel exitStateModel) {

View File

@ -3,14 +3,14 @@ package dev.vality.adapter.flow.lib.flow.simple;
import dev.vality.adapter.flow.lib.constant.Step;
import dev.vality.adapter.flow.lib.flow.RecurrentResultIntentResolver;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.damsel.proxy_provider.RecurrentTokenIntent;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class SimpleRedirectGenerateTokenResultIntentResolver implements RecurrentResultIntentResolver {
private final RecurrentIntentResultFactory recurrentIntentResultFactory;
private final SimpleRecurrentIntentResultFactory recurrentIntentResultFactory;
@Override
public RecurrentTokenIntent initIntentByStep(ExitStateModel exitStateModel) {

View File

@ -1,134 +1,21 @@
package dev.vality.adapter.flow.lib.service.factory;
import dev.vality.adapter.common.mapper.ErrorMapping;
import dev.vality.adapter.flow.lib.constant.HttpMethod;
import dev.vality.adapter.flow.lib.constant.RedirectFields;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.model.PollingInfo;
import dev.vality.adapter.flow.lib.model.ThreeDsData;
import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
import dev.vality.adapter.flow.lib.service.PollingInfoService;
import dev.vality.adapter.flow.lib.service.TagManagementService;
import dev.vality.adapter.flow.lib.utils.ThreeDsDataInitializer;
import dev.vality.adapter.flow.lib.utils.TimeoutUtils;
import dev.vality.adapter.flow.lib.utils.TimerProperties;
import dev.vality.damsel.base.Timer;
import dev.vality.damsel.proxy_provider.*;
import dev.vality.damsel.timeout_behaviour.TimeoutBehaviour;
import dev.vality.damsel.user_interaction.UserInteraction;
import lombok.RequiredArgsConstructor;
import dev.vality.damsel.proxy_provider.Intent;
import java.nio.ByteBuffer;
import java.util.Map;
public interface IntentResultFactory {
import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirectTimeout;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.*;
Intent createFinishIntentSuccessWithCheckToken(ExitStateModel exitStateModel);
@RequiredArgsConstructor
public class IntentResultFactory {
Intent createSuspendIntentWithFailedAfterTimeout(ExitStateModel exitStateModel);
private final TimerProperties timerProperties;
private final CallbackUrlExtractor callbackUrlExtractor;
private final TagManagementService tagManagementService;
private final ParametersSerializer parametersSerializer;
private final PollingInfoService pollingInfoService;
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
Intent createSuspendIntentWithCallbackAfterTimeout(ExitStateModel exitStateModel);
public Intent createFinishIntentSuccessWithCheckToken(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
if (entryStateModel.getBaseRequestModel().getRecurrentPaymentData() != null
&& entryStateModel.getBaseRequestModel().getRecurrentPaymentData().isMakeRecurrent()) {
return createFinishIntentSuccessWithToken(exitStateModel.getRecToken());
}
return createFinishIntentSuccess();
}
Intent createFinishIntentSuccess();
public Intent createSuspendIntentWithFailedAfterTimeout(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return Intent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin))
).setUserInteraction(createUserInteraction(threeDsData, params))
);
}
Intent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel);
public Intent createSuspendIntentWithCallbackAfterTimeout(ExitStateModel exitStateModel) {
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return Intent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin)))
.setTimeoutBehaviour(TimeoutBehaviour.callback(
ByteBuffer.wrap(parametersSerializer.writeByte(params)))
).setUserInteraction(createUserInteraction(threeDsData, params))
);
}
private UserInteraction createUserInteraction(ThreeDsData threeDsData, Map<String, String> parameters) {
if (threeDsData.getHttpMethod() == HttpMethod.GET) {
return createGetUserInteraction(threeDsData.getAcsUrl());
} else {
return createPostUserInteraction(threeDsData.getAcsUrl(), parameters);
}
}
public Intent createFinishIntentSuccess() {
return Intent.finish(new FinishIntent(FinishStatus.success(new Success())));
}
public Intent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
int nextTimeoutSec =
exponentialBackOffPollingService.prepareNextPollingInterval(pollingInfo, adapterConfigurations);
return Intent.sleep(new SleepIntent(Timer.timeout(nextTimeoutSec)));
}
public Intent createFinishIntentFailed(ExitStateModel exitStateModel) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(exitStateModel.getErrorCode(),
exitStateModel.getErrorMessage()))));
}
public Intent createFinishIntentFailed(String errorCode, String errorMessage) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage))));
}
Intent createFinishIntentFailed(ExitStateModel exitStateModel);
Intent createFinishIntentFailed(String errorCode, String errorMessage);
}

View File

@ -26,7 +26,7 @@ import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirect
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.*;
@RequiredArgsConstructor
public class IntentResultForwardThreeDsParamsFactory {
public class IntentResultForwardThreeDsParamsFactory implements IntentResultFactory {
private final TimerProperties timerProperties;
private final TagManagementService tagManagementService;
@ -35,6 +35,7 @@ public class IntentResultForwardThreeDsParamsFactory {
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
@Override
public Intent createFinishIntentSuccessWithCheckToken(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
if (entryStateModel.getBaseRequestModel().getRecurrentPaymentData() != null
@ -44,6 +45,7 @@ public class IntentResultForwardThreeDsParamsFactory {
return createFinishIntentSuccess();
}
@Override
public Intent createSuspendIntentWithFailedAfterTimeout(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
@ -60,6 +62,7 @@ public class IntentResultForwardThreeDsParamsFactory {
);
}
@Override
public Intent createSuspendIntentWithCallbackAfterTimeout(ExitStateModel exitStateModel) {
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
@ -91,10 +94,12 @@ public class IntentResultForwardThreeDsParamsFactory {
}
}
@Override
public Intent createFinishIntentSuccess() {
return Intent.finish(new FinishIntent(FinishStatus.success(new Success())));
}
@Override
public Intent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
@ -109,12 +114,14 @@ public class IntentResultForwardThreeDsParamsFactory {
return Intent.sleep(new SleepIntent(Timer.timeout(nextTimeoutSec)));
}
@Override
public Intent createFinishIntentFailed(ExitStateModel exitStateModel) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(exitStateModel.getErrorCode(),
exitStateModel.getErrorMessage()))));
}
@Override
public Intent createFinishIntentFailed(String errorCode, String errorMessage) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage))));

View File

@ -1,86 +1,17 @@
package dev.vality.adapter.flow.lib.service.factory;
import dev.vality.adapter.common.mapper.ErrorMapping;
import dev.vality.adapter.flow.lib.constant.RedirectFields;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.model.PollingInfo;
import dev.vality.adapter.flow.lib.model.ThreeDsData;
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
import dev.vality.adapter.flow.lib.service.PollingInfoService;
import dev.vality.adapter.flow.lib.service.TagManagementService;
import dev.vality.adapter.flow.lib.utils.ThreeDsDataInitializer;
import dev.vality.adapter.flow.lib.utils.TimeoutUtils;
import dev.vality.adapter.flow.lib.utils.TimerProperties;
import dev.vality.damsel.base.Timer;
import dev.vality.damsel.proxy_provider.*;
import lombok.RequiredArgsConstructor;
import dev.vality.damsel.proxy_provider.RecurrentTokenIntent;
import java.util.Map;
public interface RecurrentIntentResultFactory {
import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirectTimeout;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.createPostUserInteraction;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.createRecurrentTokenStatusSuccess;
RecurrentTokenIntent createIntentWithSuspension(ExitStateModel exitStateModel);
@RequiredArgsConstructor
public class RecurrentIntentResultFactory {
RecurrentTokenIntent createSleepIntentForReinvocation();
private final TimerProperties timerProperties;
private final CallbackUrlExtractor callbackUrlExtractor;
private final TagManagementService tagManagementService;
private final PollingInfoService pollingInfoService;
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
RecurrentTokenIntent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel);
public RecurrentTokenIntent createIntentWithSuspension(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return RecurrentTokenIntent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin))
).setUserInteraction(createPostUserInteraction(threeDsData.getAcsUrl(), params))
);
}
RecurrentTokenIntent createFinishIntent(String recToken);
public RecurrentTokenIntent createSleepIntentForReinvocation() {
return RecurrentTokenIntent.sleep(new SleepIntent(Timer.timeout(0)));
}
public RecurrentTokenIntent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
int nextTimeoutSec =
exponentialBackOffPollingService.prepareNextPollingInterval(pollingInfo, adapterConfigurations);
return RecurrentTokenIntent.sleep(
new SleepIntent(Timer.timeout(nextTimeoutSec))
);
}
public RecurrentTokenIntent createFinishIntent(String recToken) {
return RecurrentTokenIntent.finish(
createRecurrentTokenStatusSuccess(recToken)
);
}
public RecurrentTokenIntent createFinishIntentFailed(String errorCode, String errorMessage) {
return RecurrentTokenIntent.finish(new RecurrentTokenFinishIntent(RecurrentTokenFinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage)))
);
}
RecurrentTokenIntent createFinishIntentFailed(String errorCode, String errorMessage);
}

View File

@ -22,7 +22,7 @@ import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.crea
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.createRecurrentTokenStatusSuccess;
@RequiredArgsConstructor
public class RecurrentIntentResultForwardThreeDsParamsFactory {
public class RecurrentIntentResultForwardThreeDsParamsFactory implements RecurrentIntentResultFactory {
private final TimerProperties timerProperties;
private final TagManagementService tagManagementService;
@ -30,6 +30,7 @@ public class RecurrentIntentResultForwardThreeDsParamsFactory {
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
@Override
public RecurrentTokenIntent createIntentWithSuspension(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
@ -46,10 +47,12 @@ public class RecurrentIntentResultForwardThreeDsParamsFactory {
);
}
@Override
public RecurrentTokenIntent createSleepIntentForReinvocation() {
return RecurrentTokenIntent.sleep(new SleepIntent(Timer.timeout(0)));
}
@Override
public RecurrentTokenIntent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
@ -66,12 +69,14 @@ public class RecurrentIntentResultForwardThreeDsParamsFactory {
);
}
@Override
public RecurrentTokenIntent createFinishIntent(String recToken) {
return RecurrentTokenIntent.finish(
createRecurrentTokenStatusSuccess(recToken)
);
}
@Override
public RecurrentTokenIntent createFinishIntentFailed(String errorCode, String errorMessage) {
return RecurrentTokenIntent.finish(new RecurrentTokenFinishIntent(RecurrentTokenFinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage)))

View File

@ -0,0 +1,141 @@
package dev.vality.adapter.flow.lib.service.factory;
import dev.vality.adapter.common.mapper.ErrorMapping;
import dev.vality.adapter.flow.lib.constant.HttpMethod;
import dev.vality.adapter.flow.lib.constant.RedirectFields;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.model.PollingInfo;
import dev.vality.adapter.flow.lib.model.ThreeDsData;
import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
import dev.vality.adapter.flow.lib.service.PollingInfoService;
import dev.vality.adapter.flow.lib.service.TagManagementService;
import dev.vality.adapter.flow.lib.utils.ThreeDsDataInitializer;
import dev.vality.adapter.flow.lib.utils.TimeoutUtils;
import dev.vality.adapter.flow.lib.utils.TimerProperties;
import dev.vality.damsel.base.Timer;
import dev.vality.damsel.proxy_provider.*;
import dev.vality.damsel.timeout_behaviour.TimeoutBehaviour;
import dev.vality.damsel.user_interaction.UserInteraction;
import lombok.RequiredArgsConstructor;
import java.nio.ByteBuffer;
import java.util.Map;
import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirectTimeout;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.*;
@RequiredArgsConstructor
public class SimpleIntentResultFactory implements IntentResultFactory {
private final TimerProperties timerProperties;
private final CallbackUrlExtractor callbackUrlExtractor;
private final TagManagementService tagManagementService;
private final ParametersSerializer parametersSerializer;
private final PollingInfoService pollingInfoService;
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
@Override
public Intent createFinishIntentSuccessWithCheckToken(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
if (entryStateModel.getBaseRequestModel().getRecurrentPaymentData() != null
&& entryStateModel.getBaseRequestModel().getRecurrentPaymentData().isMakeRecurrent()) {
return createFinishIntentSuccessWithToken(exitStateModel.getRecToken());
}
return createFinishIntentSuccess();
}
@Override
public Intent createSuspendIntentWithFailedAfterTimeout(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return Intent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin))
).setUserInteraction(createUserInteraction(threeDsData, params))
);
}
@Override
public Intent createSuspendIntentWithCallbackAfterTimeout(ExitStateModel exitStateModel) {
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return Intent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin)))
.setTimeoutBehaviour(TimeoutBehaviour.callback(
ByteBuffer.wrap(parametersSerializer.writeByte(params)))
).setUserInteraction(createUserInteraction(threeDsData, params))
);
}
private UserInteraction createUserInteraction(ThreeDsData threeDsData, Map<String, String> parameters) {
if (threeDsData.getHttpMethod() == HttpMethod.GET) {
return createGetUserInteraction(threeDsData.getAcsUrl());
} else {
return createPostUserInteraction(threeDsData.getAcsUrl(), parameters);
}
}
@Override
public Intent createFinishIntentSuccess() {
return Intent.finish(new FinishIntent(FinishStatus.success(new Success())));
}
@Override
public Intent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
int nextTimeoutSec =
exponentialBackOffPollingService.prepareNextPollingInterval(pollingInfo, adapterConfigurations);
return Intent.sleep(new SleepIntent(Timer.timeout(nextTimeoutSec)));
}
@Override
public Intent createFinishIntentFailed(ExitStateModel exitStateModel) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(exitStateModel.getErrorCode(),
exitStateModel.getErrorMessage()))));
}
@Override
public Intent createFinishIntentFailed(String errorCode, String errorMessage) {
return Intent.finish(new FinishIntent(FinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage))));
}
}

View File

@ -0,0 +1,91 @@
package dev.vality.adapter.flow.lib.service.factory;
import dev.vality.adapter.common.mapper.ErrorMapping;
import dev.vality.adapter.flow.lib.constant.RedirectFields;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.model.PollingInfo;
import dev.vality.adapter.flow.lib.model.ThreeDsData;
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
import dev.vality.adapter.flow.lib.service.PollingInfoService;
import dev.vality.adapter.flow.lib.service.TagManagementService;
import dev.vality.adapter.flow.lib.utils.ThreeDsDataInitializer;
import dev.vality.adapter.flow.lib.utils.TimeoutUtils;
import dev.vality.adapter.flow.lib.utils.TimerProperties;
import dev.vality.damsel.base.Timer;
import dev.vality.damsel.proxy_provider.*;
import lombok.RequiredArgsConstructor;
import java.util.Map;
import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirectTimeout;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.createPostUserInteraction;
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.createRecurrentTokenStatusSuccess;
@RequiredArgsConstructor
public class SimpleRecurrentIntentResultFactory implements RecurrentIntentResultFactory {
private final TimerProperties timerProperties;
private final CallbackUrlExtractor callbackUrlExtractor;
private final TagManagementService tagManagementService;
private final PollingInfoService pollingInfoService;
private final ErrorMapping errorMapping;
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
@Override
public RecurrentTokenIntent createIntentWithSuspension(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
ThreeDsData threeDsData = exitStateModel.getThreeDsData();
Map<String, String> params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel);
String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl();
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
params.put(RedirectFields.TERM_URL.getValue(),
callbackUrlExtractor.extractCallbackUrl(adapterConfigurations, redirectUrl));
int timerRedirectTimeoutMin = extractRedirectTimeout(
adapterConfigurations,
timerProperties.getRedirectTimeoutMin());
return RecurrentTokenIntent.suspend(
new SuspendIntent(
tagManagementService.findTag(params),
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin))
).setUserInteraction(createPostUserInteraction(threeDsData.getAcsUrl(), params))
);
}
@Override
public RecurrentTokenIntent createSleepIntentForReinvocation() {
return RecurrentTokenIntent.sleep(new SleepIntent(Timer.timeout(0)));
}
@Override
public RecurrentTokenIntent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
if (pollingInfoService.isDeadline(pollingInfo)) {
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
}
exitStateModel.setPollingInfo(pollingInfo);
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
int nextTimeoutSec =
exponentialBackOffPollingService.prepareNextPollingInterval(pollingInfo, adapterConfigurations);
return RecurrentTokenIntent.sleep(
new SleepIntent(Timer.timeout(nextTimeoutSec))
);
}
@Override
public RecurrentTokenIntent createFinishIntent(String recToken) {
return RecurrentTokenIntent.finish(
createRecurrentTokenStatusSuccess(recToken)
);
}
@Override
public RecurrentTokenIntent createFinishIntentFailed(String errorCode, String errorMessage) {
return RecurrentTokenIntent.finish(new RecurrentTokenFinishIntent(RecurrentTokenFinishStatus.failure(
errorMapping.mapFailure(errorCode, errorMessage)))
);
}
}

View File

@ -22,8 +22,8 @@ import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
import dev.vality.adapter.flow.lib.serde.TemporaryContextDeserializer;
import dev.vality.adapter.flow.lib.serde.TemporaryContextSerializer;
import dev.vality.adapter.flow.lib.service.*;
import dev.vality.adapter.flow.lib.service.factory.IntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.utils.AdapterProperties;
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
import dev.vality.adapter.flow.lib.utils.TimerProperties;
@ -143,7 +143,7 @@ public class HandlerConfig {
@Bean
public ExitModelToRecTokenProxyResultConverter exitModelToRecTokenProxyResultConverter(
RecurrentIntentResultFactory recurrentIntentResultFactory,
SimpleRecurrentIntentResultFactory recurrentIntentResultFactory,
TemporaryContextSerializer temporaryContextSerializer,
RecurrentResultIntentResolver recurrentResultIntentResolver,
ExitStateModelToTemporaryContextConverter exitStateModelToTemporaryContextConverter) {
@ -187,7 +187,7 @@ public class HandlerConfig {
@Bean
public ExitModelToProxyResultConverter exitModelToProxyResultConverter(
IntentResultFactory intentResultFactory,
SimpleIntentResultFactory intentResultFactory,
TemporaryContextSerializer temporaryContextSerializer,
ResultIntentResolver resultIntentResolver,
ExitStateModelToTemporaryContextConverter exitStateModelToTemporaryContextConverter) {
@ -224,7 +224,7 @@ public class HandlerConfig {
}
@Bean
public IntentResultFactory intentResultFactory(
public SimpleIntentResultFactory intentResultFactory(
TimerProperties timerProperties,
CallbackUrlExtractor callbackUrlExtractor,
TagManagementService tagManagementService,
@ -232,19 +232,19 @@ public class HandlerConfig {
PollingInfoService pollingInfoService,
ErrorMapping errorMapping,
ExponentialBackOffPollingService exponentialBackOffPollingService) {
return new IntentResultFactory(timerProperties, callbackUrlExtractor, tagManagementService,
return new SimpleIntentResultFactory(timerProperties, callbackUrlExtractor, tagManagementService,
parametersSerializer, pollingInfoService, errorMapping, exponentialBackOffPollingService);
}
@Bean
public RecurrentIntentResultFactory recurrentIntentResultFactory(
public SimpleRecurrentIntentResultFactory recurrentIntentResultFactory(
TimerProperties timerProperties,
CallbackUrlExtractor callbackUrlExtractor,
TagManagementService tagManagementService,
PollingInfoService pollingInfoService,
ErrorMapping errorMapping,
ExponentialBackOffPollingService exponentialBackOffPollingService) {
return new RecurrentIntentResultFactory(timerProperties, callbackUrlExtractor, tagManagementService,
return new SimpleRecurrentIntentResultFactory(timerProperties, callbackUrlExtractor, tagManagementService,
pollingInfoService, errorMapping, exponentialBackOffPollingService);
}

View File

@ -20,8 +20,8 @@ import dev.vality.adapter.flow.lib.model.BaseResponseModel;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.processor.Processor;
import dev.vality.adapter.flow.lib.service.factory.IntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.damsel.proxy_provider.PaymentContext;
import dev.vality.damsel.proxy_provider.PaymentProxyResult;
import dev.vality.damsel.proxy_provider.RecurrentTokenContext;
@ -78,12 +78,12 @@ public class FullThreeDsFlowConfig {
@Bean
public RecurrentResultIntentResolver recurrentResultIntentResolver(
RecurrentIntentResultFactory recurrentIntentResultFactory) {
SimpleRecurrentIntentResultFactory recurrentIntentResultFactory) {
return new GenerateTokenResultIntentResolverImpl(recurrentIntentResultFactory);
}
@Bean
public ResultIntentResolver resultIntentResolver(IntentResultFactory intentResultFactory) {
public ResultIntentResolver resultIntentResolver(SimpleIntentResultFactory intentResultFactory) {
return new ResultIntentResolverImpl(intentResultFactory);
}

View File

@ -20,8 +20,8 @@ import dev.vality.adapter.flow.lib.model.BaseResponseModel;
import dev.vality.adapter.flow.lib.model.EntryStateModel;
import dev.vality.adapter.flow.lib.model.ExitStateModel;
import dev.vality.adapter.flow.lib.processor.Processor;
import dev.vality.adapter.flow.lib.service.factory.IntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.RecurrentIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleIntentResultFactory;
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
import dev.vality.damsel.proxy_provider.PaymentContext;
import dev.vality.damsel.proxy_provider.PaymentProxyResult;
import dev.vality.damsel.proxy_provider.RecurrentTokenContext;
@ -61,12 +61,12 @@ public class SimpleRedirectWithPollingDsFlowConfig {
@Bean
public RecurrentResultIntentResolver recurrentResultIntentResolver(
RecurrentIntentResultFactory recurrentIntentResultFactory) {
SimpleRecurrentIntentResultFactory recurrentIntentResultFactory) {
return new SimpleRedirectGenerateTokenResultIntentResolver(recurrentIntentResultFactory);
}
@Bean
public ResultIntentResolver resultIntentResolver(IntentResultFactory intentResultFactory) {
public ResultIntentResolver resultIntentResolver(SimpleIntentResultFactory intentResultFactory) {
return new SimpleRedirectWithPollingResultIntentResolver(intentResultFactory);
}