From 540e49b59edec562f59e97ad7795b67b4e9ae322 Mon Sep 17 00:00:00 2001 From: struga Date: Fri, 10 Mar 2023 15:38:28 +0700 Subject: [PATCH] Add alter threeds (#64) --- pom.xml | 2 +- ...itModelToRecTokenProxyResultConverter.java | 4 +- ...GenerateTokenResultIntentResolverImpl.java | 4 +- ...rectGenerateTokenResultIntentResolver.java | 4 +- .../service/factory/IntentResultFactory.java | 131 ++-------------- ...tentResultForwardThreeDsParamsFactory.java | 9 +- .../factory/RecurrentIntentResultFactory.java | 83 +---------- ...tentResultForwardThreeDsParamsFactory.java | 7 +- .../factory/SimpleIntentResultFactory.java | 141 ++++++++++++++++++ .../SimpleRecurrentIntentResultFactory.java | 91 +++++++++++ .../flow/lib/flow/config/HandlerConfig.java | 16 +- .../ds/config/FullThreeDsFlowConfig.java | 8 +- ...SimpleRedirectWithPollingDsFlowConfig.java | 8 +- 13 files changed, 285 insertions(+), 223 deletions(-) create mode 100644 src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleIntentResultFactory.java create mode 100644 src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleRecurrentIntentResultFactory.java diff --git a/pom.xml b/pom.xml index 1f478ae..875dbad 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ adapter-flow-lib - 0.1.22 + 0.1.23 jar adapter-flow-lib diff --git a/src/main/java/dev/vality/adapter/flow/lib/converter/exit/ExitModelToRecTokenProxyResultConverter.java b/src/main/java/dev/vality/adapter/flow/lib/converter/exit/ExitModelToRecTokenProxyResultConverter.java index d6f9831..50442ed 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/converter/exit/ExitModelToRecTokenProxyResultConverter.java +++ b/src/main/java/dev/vality/adapter/flow/lib/converter/exit/ExitModelToRecTokenProxyResultConverter.java @@ -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 { - private final RecurrentIntentResultFactory recurrentIntentResultFactory; + private final SimpleRecurrentIntentResultFactory recurrentIntentResultFactory; private final TemporaryContextSerializer serializer; private final RecurrentResultIntentResolver recurrentResultIntentResolver; private final ExitStateModelToTemporaryContextConverter contextConverter; diff --git a/src/main/java/dev/vality/adapter/flow/lib/flow/full/GenerateTokenResultIntentResolverImpl.java b/src/main/java/dev/vality/adapter/flow/lib/flow/full/GenerateTokenResultIntentResolverImpl.java index 939aecb..40e995c 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/flow/full/GenerateTokenResultIntentResolverImpl.java +++ b/src/main/java/dev/vality/adapter/flow/lib/flow/full/GenerateTokenResultIntentResolverImpl.java @@ -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) { diff --git a/src/main/java/dev/vality/adapter/flow/lib/flow/simple/SimpleRedirectGenerateTokenResultIntentResolver.java b/src/main/java/dev/vality/adapter/flow/lib/flow/simple/SimpleRedirectGenerateTokenResultIntentResolver.java index 9252524..05e9337 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/flow/simple/SimpleRedirectGenerateTokenResultIntentResolver.java +++ b/src/main/java/dev/vality/adapter/flow/lib/flow/simple/SimpleRedirectGenerateTokenResultIntentResolver.java @@ -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) { diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultFactory.java index 0b89c5a..cf1fa3b 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultFactory.java +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultFactory.java @@ -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 params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel); - String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl(); - Map 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 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 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 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 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); } diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultForwardThreeDsParamsFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultForwardThreeDsParamsFactory.java index ebdc25d..5015d05 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultForwardThreeDsParamsFactory.java +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/IntentResultForwardThreeDsParamsFactory.java @@ -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 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)))); diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultFactory.java index 3833e09..52b8638 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultFactory.java +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultFactory.java @@ -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 params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel); - String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl(); - Map 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 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); } diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultForwardThreeDsParamsFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultForwardThreeDsParamsFactory.java index fd10ffb..9349cfa 100644 --- a/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultForwardThreeDsParamsFactory.java +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/RecurrentIntentResultForwardThreeDsParamsFactory.java @@ -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))) diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleIntentResultFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleIntentResultFactory.java new file mode 100644 index 0000000..17c65f4 --- /dev/null +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleIntentResultFactory.java @@ -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 params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel); + String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl(); + Map 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 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 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 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 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)))); + } + +} diff --git a/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleRecurrentIntentResultFactory.java b/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleRecurrentIntentResultFactory.java new file mode 100644 index 0000000..01b1837 --- /dev/null +++ b/src/main/java/dev/vality/adapter/flow/lib/service/factory/SimpleRecurrentIntentResultFactory.java @@ -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 params = ThreeDsDataInitializer.initThreeDsParameters(exitStateModel); + String redirectUrl = entryStateModel.getBaseRequestModel().getSuccessRedirectUrl(); + Map 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 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))) + ); + } +} diff --git a/src/test/java/dev/vality/adapter/flow/lib/flow/config/HandlerConfig.java b/src/test/java/dev/vality/adapter/flow/lib/flow/config/HandlerConfig.java index 2ba0b7c..8e00897 100644 --- a/src/test/java/dev/vality/adapter/flow/lib/flow/config/HandlerConfig.java +++ b/src/test/java/dev/vality/adapter/flow/lib/flow/config/HandlerConfig.java @@ -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); } diff --git a/src/test/java/dev/vality/adapter/flow/lib/flow/full/three/ds/config/FullThreeDsFlowConfig.java b/src/test/java/dev/vality/adapter/flow/lib/flow/full/three/ds/config/FullThreeDsFlowConfig.java index 361f921..74aad0d 100644 --- a/src/test/java/dev/vality/adapter/flow/lib/flow/full/three/ds/config/FullThreeDsFlowConfig.java +++ b/src/test/java/dev/vality/adapter/flow/lib/flow/full/three/ds/config/FullThreeDsFlowConfig.java @@ -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); } diff --git a/src/test/java/dev/vality/adapter/flow/lib/flow/simple/redirect/config/SimpleRedirectWithPollingDsFlowConfig.java b/src/test/java/dev/vality/adapter/flow/lib/flow/simple/redirect/config/SimpleRedirectWithPollingDsFlowConfig.java index 15517d9..ed63d7e 100644 --- a/src/test/java/dev/vality/adapter/flow/lib/flow/simple/redirect/config/SimpleRedirectWithPollingDsFlowConfig.java +++ b/src/test/java/dev/vality/adapter/flow/lib/flow/simple/redirect/config/SimpleRedirectWithPollingDsFlowConfig.java @@ -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); }