mirror of
https://github.com/valitydev/adapter-bank-payout-spring-boot-starter.git
synced 2024-11-06 00:45:21 +00:00
Lib for OCT(payout) adapter spring (#1)
* Move here common logic for payout adapter
This commit is contained in:
parent
c700838120
commit
d988b9d85e
78
.gitignore
vendored
Normal file
78
.gitignore
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
.eunit
|
||||
deps
|
||||
*.o
|
||||
*.beam
|
||||
*.plt
|
||||
erl_crash.dump
|
||||
ebin/*.beam
|
||||
rel/example_project
|
||||
.concrete/DEV_MODE
|
||||
.rebar
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
*.iws
|
||||
*.ipr
|
||||
*.iml
|
||||
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
env.list
|
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "build_utils"]
|
||||
path = build_utils
|
||||
url = git@github.com:rbkmoney/build_utils.git
|
||||
branch = master
|
15
Jenkinsfile
vendored
Normal file
15
Jenkinsfile
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#!groovy
|
||||
build('adapter-bank-payout-spring-boot-starter', 'docker-host') {
|
||||
|
||||
checkoutRepo()
|
||||
loadBuildUtils()
|
||||
|
||||
def javaLibPipeline
|
||||
runStage('load JavaLib pipeline') {
|
||||
javaLibPipeline = load("build_utils/jenkins_lib/pipeJavaLib.groovy")
|
||||
}
|
||||
|
||||
def buildImageTag = "fcf116dd775cc2e91bffb6a36835754e3f2d5321"
|
||||
javaLibPipeline(buildImageTag)
|
||||
|
||||
}
|
39
README.md
39
README.md
@ -1 +1,40 @@
|
||||
# adapter-bank-payout-spring-boot-starter
|
||||
|
||||
For new payout:
|
||||
|
||||
1. implement RemoteClient
|
||||
2. implement ResultProcessor and config ChainProcessor:
|
||||
|
||||
```
|
||||
@Bean
|
||||
@Autowired
|
||||
public ResultProcessor<Response, ProcessResult> responseProcessorChain(ErrorMapping errorMapping) {
|
||||
SuccessProcessor successProcessor = new SuccessProcessor(null);
|
||||
return new ErrorProcessor(errorMapping, successProcessor);
|
||||
}
|
||||
```
|
||||
3. implement WithdrawalConverter
|
||||
4. implement GenericServlet for woody:
|
||||
|
||||
```
|
||||
@WebServlet("/adapter/{app-path}/payout")
|
||||
public class PayoutServlet extends GenericServlet {
|
||||
|
||||
@Autowired
|
||||
private AdapterSrv.Iface payoutAdapterServiceLogDecorator;
|
||||
|
||||
private Servlet servlet;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
servlet = new THServiceBuilder().build(AdapterSrv.Iface.class, payoutAdapterServiceLogDecorator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
|
||||
servlet.service(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
1
build_utils
Submodule
1
build_utils
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ea4aa042f482551d624fd49a570d28488f479e93
|
179
pom.xml
Normal file
179
pom.xml
Normal file
@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.rbkmoney</groupId>
|
||||
<artifactId>adapter-bank-payout-spring-boot-starter</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Adapter bank payout spring boot starter</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>8</java.version>
|
||||
<spring-boot.version>2.1.0.RELEASE</spring-boot.version>
|
||||
<damsel-utils.version>2.1.9</damsel-utils.version>
|
||||
<damsel.version>1.256-2afe121</damsel.version>
|
||||
<serializer.version>0.6.7</serializer.version>
|
||||
<hellgate-adapter-client.version>2.1.9</hellgate-adapter-client.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!--third party-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>4.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--spring-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--rbk-->
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney</groupId>
|
||||
<artifactId>error-mapping-java</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney.woody</groupId>
|
||||
<artifactId>woody-thrift</artifactId>
|
||||
<version>1.1.15</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney</groupId>
|
||||
<artifactId>damsel</artifactId>
|
||||
<version>${damsel.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney</groupId>
|
||||
<artifactId>damsel-utils</artifactId>
|
||||
<version>${damsel-utils.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney.geck</groupId>
|
||||
<artifactId>serializer</artifactId>
|
||||
<version>${serializer.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney.proxy-libs</groupId>
|
||||
<artifactId>hellgate-adapter-client</artifactId>
|
||||
<version>${hellgate-adapter-client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<distributionManagement>
|
||||
<downloadUrl>http://java-nexus.msk1.rbkmoney.net:8081/nexus/content/groups/public</downloadUrl>
|
||||
<repository>
|
||||
<uniqueVersion>false</uniqueVersion>
|
||||
<id>releases</id>
|
||||
<name>RBKmoney releases repository</name>
|
||||
<url>http://java-nexus.msk1.rbkmoney.net:8081/nexus/content/repositories/releases</url>
|
||||
<layout>default</layout>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<uniqueVersion>true</uniqueVersion>
|
||||
<id>snapshots</id>
|
||||
<name>RBKmoney snapshots repository</name>
|
||||
<url>http://java-nexus.msk1.rbkmoney.net:8081/nexus/content/repositories/snapshots</url>
|
||||
<layout>default</layout>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.2</version>
|
||||
<configuration>
|
||||
<destFile>${sonar.jacoco.reportPath}</destFile>
|
||||
<append>true</append>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.client;
|
||||
|
||||
public interface RemoteClient<T, R> {
|
||||
|
||||
R payout(T request);
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.rbkmoney.error.mapping.ErrorMapping;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Configuration
|
||||
public class ErrorMappingConfiguration {
|
||||
|
||||
@Value("${error-mapping.file}")
|
||||
private Resource filePath;
|
||||
|
||||
@Value("${error-mapping.patternReason:\"'%s' - '%s'\"}")
|
||||
private String patternReason;
|
||||
|
||||
@Bean
|
||||
ErrorMapping errorMapping() throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
|
||||
|
||||
ErrorMapping errorMapping = new ErrorMapping(filePath.getInputStream(), patternReason, mapper);
|
||||
errorMapping.validateMappingFormat();
|
||||
return errorMapping;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.config;
|
||||
|
||||
import com.rbkmoney.woody.api.flow.WFlow;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Configuration
|
||||
public class FilterConfiguration {
|
||||
|
||||
public static final String HEALTH = "/actuator/health";
|
||||
|
||||
@Value("${server.rest.port}")
|
||||
private int restPort;
|
||||
|
||||
@Value("/${server.rest.endpoint}/")
|
||||
private String restEndpoint;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean externalPortRestrictingFilter() {
|
||||
Filter filter = new OncePerRequestFilter() {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
String servletPath = request.getServletPath();
|
||||
if ((request.getLocalPort() == restPort)
|
||||
&& !(servletPath.startsWith(restEndpoint) || servletPath.startsWith(HEALTH))) {
|
||||
response.sendError(404, "Unknown address");
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
};
|
||||
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(filter);
|
||||
filterRegistrationBean.setOrder(-100);
|
||||
filterRegistrationBean.setName("httpPortFilter");
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean woodyFilter() {
|
||||
WFlow wFlow = new WFlow();
|
||||
Filter filter = new OncePerRequestFilter() {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
if ((request.getLocalPort() == restPort)
|
||||
&& request.getServletPath().startsWith(restEndpoint)) {
|
||||
wFlow.createServiceFork(() -> {
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (IOException | ServletException e) {
|
||||
sneakyThrow(e);
|
||||
}
|
||||
}).run();
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private <E extends Throwable, T> T sneakyThrow(Throwable t) throws E {
|
||||
throw (E) t;
|
||||
}
|
||||
};
|
||||
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(filter);
|
||||
filterRegistrationBean.setOrder(-50);
|
||||
filterRegistrationBean.setName("woodyFilter");
|
||||
filterRegistrationBean.addUrlPatterns(restEndpoint + "*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@ConfigurationProperties("adapter")
|
||||
@Validated
|
||||
public class AdapterProperties {
|
||||
|
||||
@NotEmpty
|
||||
private String url;
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties("time.config")
|
||||
@Validated
|
||||
@Getter
|
||||
@Setter
|
||||
public class TimerProperties {
|
||||
|
||||
@NotNull
|
||||
private int redirectTimeout;
|
||||
|
||||
@NotNull
|
||||
private int maxTimePolling;
|
||||
|
||||
@NotNull
|
||||
private int pollingDelay;
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.converter;
|
||||
|
||||
import com.rbkmoney.damsel.msgpack.Value;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.Withdrawal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface WithdrawalConverter<T> {
|
||||
|
||||
T convert(Withdrawal withdrawal, Value state, Map<String, String> options);
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.processor;
|
||||
|
||||
public interface ResultProcessor<T, R> {
|
||||
|
||||
R process(T t);
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.service;
|
||||
|
||||
|
||||
import com.rbkmoney.adapter.bank.payout.spring.boot.starter.client.RemoteClient;
|
||||
import com.rbkmoney.adapter.bank.payout.spring.boot.starter.converter.WithdrawalConverter;
|
||||
import com.rbkmoney.adapter.bank.payout.spring.boot.starter.processor.ResultProcessor;
|
||||
import com.rbkmoney.damsel.msgpack.Value;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.AdapterSrv;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.ProcessResult;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.Withdrawal;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PayoutAdapterService<R, T> implements AdapterSrv.Iface {
|
||||
|
||||
private final WithdrawalConverter<T> converter;
|
||||
private final RemoteClient<T, R> client;
|
||||
private final ResultProcessor<R, ProcessResult> resultProcessorChain;
|
||||
|
||||
@Override
|
||||
public ProcessResult processWithdrawal(Withdrawal withdrawal, Value state, Map<String, String> options) {
|
||||
T request = converter.convert(withdrawal, state, options);
|
||||
R response = client.payout(request);
|
||||
return resultProcessorChain.process(response);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.service;
|
||||
|
||||
import com.rbkmoney.damsel.msgpack.Value;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.AdapterSrv;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.ProcessResult;
|
||||
import com.rbkmoney.damsel.withdrawals.provider_adapter.Withdrawal;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.thrift.TException;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.rbkmoney.java.damsel.utils.verification.ProxyProviderVerification.isUndefinedResultOrUnavailable;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class PayoutAdapterServiceLogDecorator implements AdapterSrv.Iface {
|
||||
|
||||
private final AdapterSrv.Iface payoutAdapterService;
|
||||
|
||||
@Override
|
||||
public ProcessResult processWithdrawal(Withdrawal withdrawal, Value state, Map<String, String> options) throws TException {
|
||||
String withdrawalId = withdrawal.getId();
|
||||
log.info("processWithdrawal: start with withdrawalId {}", withdrawalId);
|
||||
try {
|
||||
ProcessResult processResult = payoutAdapterService.processWithdrawal(withdrawal, state, options);
|
||||
log.info("processWithdrawal: finish {} with withdrawalId {}", processResult, withdrawalId);
|
||||
return processResult;
|
||||
} catch (Exception ex) {
|
||||
String message = "Exception in processPayment with withdrawalId " + withdrawalId;
|
||||
if (isUndefinedResultOrUnavailable(ex)) {
|
||||
log.warn(message, ex);
|
||||
} else {
|
||||
log.error(message, ex);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.utils;
|
||||
|
||||
import com.rbkmoney.damsel.cds.ExpDate;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class CardDateConverter {
|
||||
|
||||
public static String getYearFromExpDate(ExpDate expDate) {
|
||||
return String.format("%1$02d", expDate.getYear() % 100);
|
||||
}
|
||||
|
||||
public static String getYearFromShort(short year) {
|
||||
return String.format("%1$02d", year % 100);
|
||||
}
|
||||
|
||||
public static String getMonthFromExpDate(ExpDate expDate) {
|
||||
return String.format("%02d", expDate.getMonth());
|
||||
}
|
||||
|
||||
public static String getMonthFromByte(byte month) {
|
||||
return String.format("%02d", month);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.rbkmoney.adapter.bank.payout.spring.boot.starter.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SignGenerator {
|
||||
|
||||
public static String prepareDataForHmac(String[] fields, MultiValueMap<String, String> params) {
|
||||
StringBuilder dataHmac = new StringBuilder();
|
||||
Arrays.asList(fields)
|
||||
.forEach(field -> {
|
||||
List<String> fieldParameters = params.get(field);
|
||||
if (fieldParameters != null
|
||||
&& !fieldParameters.isEmpty()
|
||||
&& fieldParameters.get(0) != null
|
||||
&& !fieldParameters.get(0).isEmpty()
|
||||
) {
|
||||
dataHmac.append(fieldParameters.get(0).length());
|
||||
dataHmac.append(fieldParameters.get(0));
|
||||
} else {
|
||||
dataHmac.append("-");
|
||||
}
|
||||
}
|
||||
);
|
||||
return dataHmac.toString();
|
||||
}
|
||||
|
||||
public static String sign(String[] fieldsForSign, MultiValueMap<String, String> params, String key, String algorithm) {
|
||||
String dataHmac = prepareDataForHmac(fieldsForSign, params);
|
||||
String pSign = sign(dataHmac, key, algorithm);
|
||||
return pSign.toUpperCase();
|
||||
}
|
||||
|
||||
public static String sign(String data, String key, String algorithm) {
|
||||
try {
|
||||
byte[] decodedKey = Hex.decodeHex(key.toCharArray());
|
||||
SecretKeySpec keySpec = new SecretKeySpec(decodedKey, algorithm);
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
mac.init(keySpec);
|
||||
|
||||
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] signatureBytes = mac.doFinal(dataBytes);
|
||||
|
||||
return new String(new Hex().encode(signatureBytes));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
7
src/main/resources/META-INF/spring.factories
Normal file
7
src/main/resources/META-INF/spring.factories
Normal file
@ -0,0 +1,7 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.ErrorMappingConfiguration,\
|
||||
com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.properties.TimerProperties,\
|
||||
com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.properties.AdapterProperties,\
|
||||
com.rbkmoney.adapter.bank.payout.spring.boot.starter.service.PayoutAdapterService,\
|
||||
com.rbkmoney.adapter.bank.payout.spring.boot.starter.config.FilterConfiguration
|
||||
|
9
src/main/resources/application.yml
Normal file
9
src/main/resources/application.yml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
time.config:
|
||||
redirectTimeout: 600
|
||||
maxTimePolling: 600
|
||||
pollingDelay: 10
|
||||
---
|
||||
error-mapping:
|
||||
file: classpath:fixture/errors.json
|
||||
patternReason: "'%s' - '%s'" # 'code' - 'description'
|
8
src/main/resources/fixture/errors.json
Normal file
8
src/main/resources/fixture/errors.json
Normal file
@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"code":"unknown",
|
||||
"description":"unknown",
|
||||
"regexp":".*",
|
||||
"mapping":"authorization_failed:unknown"
|
||||
}
|
||||
]
|
10
src/test/resources/logback-test.xml
Normal file
10
src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
|
||||
|
||||
<root level="warn">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
<logger name="com.rbkmoney.woody" level="ALL"/>
|
||||
</configuration>
|
Loading…
Reference in New Issue
Block a user