PROX-266: Clearing MTS Bank. Testing and debugging application

This commit is contained in:
Baikov Dmitrii 2019-01-18 19:06:19 +03:00 committed by GitHub
parent bc78208d16
commit 371149ddd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 643 additions and 156 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "build_utils"]
path = build_utils
url = git@github.com:rbkmoney/build_utils.git
branch = master

16
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,16 @@
#!groovy
build('midgard', 'java-maven') {
checkoutRepo()
loadBuildUtils()
def javaServicePipeline
runStage('load JavaService pipeline') {
javaServicePipeline = load("build_utils/jenkins_lib/pipeJavaService.groovy")
}
def serviceName = env.REPO_NAME
def mvnArgs = '-DjvmArgs="-Xmx256m"'
def useJava11 = false
javaServicePipeline(serviceName, useJava11, mvnArgs)
}

1
build_utils Submodule

@ -0,0 +1 @@
Subproject commit 3e57e009cc329db6c3760434286c96ed98a5ba83

View File

@ -7,7 +7,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@ServletComponentScan
@SpringBootApplication(scanBasePackages = {"com.rbkmoney.midgard_adapter"})
@SpringBootApplication(scanBasePackages = {"com.rbkmoney.midgard.adapter.mts"})
public class MidgardAdapterMtsApplication {
public static void main(String[] args) throws Exception {

View File

@ -1,6 +0,0 @@
package com.rbkmoney.midgard.adapter.mts.helpers;
/** Вспомогательный класс для работы с клиринговым файлом */
public class ClearingFileHelper {
}

View File

@ -1,13 +1,12 @@
package com.rbkmoney.midgard.adapter.mts.sevices;
import com.rbkmoney.midgard.ClearingAdapterException;
import com.rbkmoney.midgard.ClearingAdapterSrv;
import com.rbkmoney.midgard.ClearingDataPackage;
import com.rbkmoney.midgard.ClearingEventResponse;
import com.rbkmoney.midgard.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class ClearingAdapterService implements ClearingAdapterSrv.Iface {
@ -15,17 +14,18 @@ public class ClearingAdapterService implements ClearingAdapterSrv.Iface {
private static final int FIRST_PACKAGE = 1;
@Override
public void startClearingEvent(long clearingId) throws ClearingAdapterException, TException {
public String startClearingEvent(long clearingId) throws ClearingAdapterException, TException {
//TODO: возможно придется выпилить так как запуск клиринга первым пакетом мне кажется более элегантным
return "1";
}
@Override
public void sendClearingDataPackage(ClearingDataPackage dataPackage) throws ClearingAdapterException, TException {
public ClearingDataPackageTag sendClearingDataPackage(String upload_id, ClearingDataPackage dataPackage) throws ClearingAdapterException, TException {
log.info("Data package have received: {}", dataPackage);
if (dataPackage == null) {
log.error("Received empty data package!");
return;
return new ClearingDataPackageTag();
}
if (dataPackage.getPackageNumber() == FIRST_PACKAGE) {
createXmlFile(dataPackage);
@ -42,8 +42,15 @@ public class ClearingAdapterService implements ClearingAdapterSrv.Iface {
}
log.info("Data package {} for clearing event {} processed", dataPackage.getPackageNumber(),
dataPackage.getClearingId());
return new ClearingDataPackageTag();
}
@Override
public void completeClearingEvent(String upload_id, long clearing_id, List<ClearingDataPackageTag> tags) throws ClearingAdapterException, TException {
}
private void createXmlFile(ClearingDataPackage clearingDataPackage) {
writeHeader(clearingDataPackage.getClearingId());
}

View File

@ -3,7 +3,7 @@ server:
spring:
application:
name: @name@
name: clearing_adapter_mts
retry-policy:
maxAttempts: 10

View File

@ -1,30 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFr1nKABCADBJY7N/TwoPNMqcZcGt5FdLc3lBjrOSOR4xzSGrmpIRWvvmi/Q
cuuVE37cNbXPdktQbl/ToUoeruX9mq/DEzrKQVeohX/eusCJIHseZ54k8EiLoRny
J3buE4SgayXWJCN/MikEXCR1GR4/GiuiAeN6FryF31000/A8z6ioyqRT1j5PF1Df
wbjZTzxjDnR3NrZEDakRy5H6u97LL3iihGE8/HAb1at502a3MFX/aJ8BBP3U23Tf
PvssGQWLl6uaCy9zIFojbfSVTlj/SqJH4Ev8nTy50JmA/AtGc//zZmIH4hjn0bb0
q3EicLhbyScX/FL07Iz0U+SYoSRR+GC2tNlbABEBAAG0C3Rlc3RrZXlzaWduiQFO
BBMBCAA4FiEELt04yuhovxuvpAui8n771Ido0vQFAlr1nKACGwMFCwkIBwIGFQoJ
CAsCBBYCAwECHgECF4AACgkQ8n771Ido0vR3xAgAj7piDo5tkm/hO7ga6fm/5p2s
64XU3rPj+vgs0bM1Xu/cs9ytXtncD9+H8l8bZAbjI1hI6zb60e9wf1ApUgeTRn1m
FxzahVqhzR1MRqFc6ex698+vWa3G4411T3VDdDeC5uOdxGgp12652XH7mzz9Alz6
u9gBn6mBwC2lKGxAbHjAwP4BuKasOLB8WUc7zO1D3uvAw7dMCtA6ScF8wgNeokDl
F1APJ+gSko6biC2hS/l4QLR/GugpducuHJnpUOqUec2YNkRVpJKttU44HlGi/5Dm
qrciJM2HiD5tnu/P0luvpar9+J83ZpYDbJvjYVQHfuwmuoYRWgoitHovbO3PEbkB
DQRa9ZygAQgAwke/bZRbLhrXIIhxMjtiEgTTSsM4OpFc70/qJhB8Zq9kBl2td2fF
85zILRpRW/sRr3iwHqWao4Zqi3SRwDjWGxfBgLhtNHnrEawnmdK/EOhnQ2+napc5
u9t/mLi1HVknkxpO8Ua35Wrm8hRt9+v1IsUz2yyBvYS8hT6Ea/Bv7c0CMTWXeV1I
4Ji7541Irru5XJ2V5v/Hs7N3WHH7agHVYNRLse+FIkBSBcijCDn1ZsUSYR9aHURa
l0+NH9Bqw/KTdZQHTU6w7jXVA3R6io8bNaSu7eyIlPyCL8Lll+9I5eGNy4fzC8sl
QJQJSZOa/e+6O8S5J32hvMzHdqMKJ/s2EwARAQABiQE2BBgBCAAgFiEELt04yuho
vxuvpAui8n771Ido0vQFAlr1nKACGwwACgkQ8n771Ido0vTBkQf9ErGyb+LmI/Rf
+YqBwdJLmAjQbFdQJaofuJWDH2iIK+nb5+VOFOa1Pm1MiqpjiwSiMSMNucaya+8m
7MxQ+LV+8HSGZlMhzJHjQ78NRWt9x8V4yI8HSz/vWSE6T11zUKLCfOfYRznTzTSC
Fpyjofs7ADgsuSBEHiR4GjZCeZ3sXUvS94Yri5vsdfTL9EkdycAewk+NiS3II1QE
+QzqJpOraqYowXGLBozDKX6dj+wGeX04vMmHKAbcQsQPAq+JgD8VgKTzMPR6Ztnp
n9+sglSZZBACzRfJmYmai7mM0s2dIi1FYpRPQQURrbN8u4AjPzSNpJ23q0hBUj5D
ecwtZig8fQ==
=l0ss
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -13,10 +13,10 @@
<artifactId>midgard-service</artifactId>
<version>1.0.0</version>
<name>Midgard Clearing</name>
<name>Midgard Clearing Service</name>
<description>Application for work with clearing data</description>
<properties>
<server.port>8023</server.port>
<server.port>8022</server.port>
<!-- Environment settings -->
<flyway.version>5.2.4</flyway.version>
<jooq.version>3.11.7</jooq.version>
@ -97,7 +97,37 @@
<dependency>
<groupId>com.rbkmoney.maven.plugins</groupId>
<artifactId>pg-embedded-plugin</artifactId>
<version>1.3</version>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.rbkmoney.geck</groupId>
<artifactId>serializer</artifactId>
<version>0.6.4</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.benas</groupId> <!-- Ha Ha! Benis! -->
<artifactId>random-beans</artifactId>
<version>3.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.rbkmoney.hg-mock</groupId>
<artifactId>generator</artifactId>
<version>0.9.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.opentable.components</groupId>
<artifactId>otj-pg-embedded</artifactId>
<version>0.12.6</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -110,7 +140,7 @@
<plugin>
<groupId>com.rbkmoney.maven.plugins</groupId>
<artifactId>pg-embedded-plugin</artifactId>
<version>1.3</version>
<version>1.4</version>
<configuration>
<port>${local.pg.port}</port>
<dbName>midgard</dbName>

View File

@ -5,5 +5,5 @@ import org.jooq.generated.midgard.tables.pojos.ClearingTransactionCashFlow;
import java.util.List;
public interface ClearingCashFlowDao extends ClearingDao<List<ClearingTransactionCashFlow>> {
public interface ClearingCashFlowDao extends ClearingDao<List<ClearingTransactionCashFlow>, Long> {
}

View File

@ -35,13 +35,16 @@ public class ClearingCashFlowDaoImpl extends AbstractGenericDao implements Clear
Query query = getDslContext().insertInto(CLEARING_TRANSACTION_CASH_FLOW).set(record);
executeWithReturn(query, keyHolder);
}
return keyHolder.getKey().longValue();
return cashFlowList.stream()
.map(cashFlow -> cashFlow.getSourceEventId())
.findFirst()
.orElse(0L);
}
@Override
public List<ClearingTransactionCashFlow> get(String sourceEventId) throws DaoException {
public List<ClearingTransactionCashFlow> get(Long sourceEventId) throws DaoException {
Query query = getDslContext().selectFrom(CLEARING_TRANSACTION_CASH_FLOW)
.where(CLEARING_TRANSACTION_CASH_FLOW.SOURCE_EVENT_ID.eq(Long.parseLong(sourceEventId)));
.where(CLEARING_TRANSACTION_CASH_FLOW.SOURCE_EVENT_ID.eq(sourceEventId));
return fetch(query, cashFlowRowMapper);
}

View File

@ -6,14 +6,14 @@ import org.jooq.generated.midgard.tables.pojos.ClearingEventInfo;
import java.util.List;
public interface ClearingEventInfoDao extends ClearingDao<ClearingEventInfo> {
public interface ClearingEventInfoDao extends ClearingDao<ClearingEventInfo, Long> {
ClearingEventInfo getClearingEvent(long eventId);
void updateClearingStatus(Long clearingId, ClearingEventStatus status);
List<ClearingEventInfo> getClearingEventsByStatus(ClearingEventStatus status);
List<ClearingEventInfo> getAllClearingEvents(ClearingEventStatus status);
Long prepareTransactionData(long clearingId, String providerId);
Long prepareTransactionData(long clearingId, int providerId);
}

View File

@ -38,7 +38,7 @@ public class ClearingEventInfoDaoImpl extends AbstractGenericDao implements Clea
public Long save(ClearingEventInfo clearingEvent) throws DaoException {
log.debug("Adding new clearing event for provider: {}", clearingEvent.getProviderId());
ClearingEventInfoRecord record = getDslContext().newRecord(CLEARING_EVENT_INFO, clearingEvent);
Query query = getDslContext().insertInto(CLEARING_EVENT_INFO).set(record);
Query query = getDslContext().insertInto(CLEARING_EVENT_INFO).set(record).returning(CLEARING_EVENT_INFO.ID);
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
executeWithReturn(query, keyHolder);
log.debug("Clearing event for provider {} have been added", clearingEvent.getProviderId());
@ -46,10 +46,10 @@ public class ClearingEventInfoDaoImpl extends AbstractGenericDao implements Clea
}
@Override
public ClearingEventInfo get(String id) throws DaoException {
public ClearingEventInfo get(Long id) throws DaoException {
log.debug("Getting a clearing event info with id {}", id);
Query query = getDslContext().selectFrom(CLEARING_EVENT_INFO)
.where(CLEARING_EVENT_INFO.ID.eq(Long.parseLong(id)));
.where(CLEARING_EVENT_INFO.ID.eq(id));
ClearingEventInfo clearingEvent = fetchOne(query, clearingEventsRowMapper);
log.debug("Clearing event: {}", clearingEvent);
return clearingEvent;
@ -74,18 +74,18 @@ public class ClearingEventInfoDaoImpl extends AbstractGenericDao implements Clea
}
@Override
public List<ClearingEventInfo> getClearingEventsByStatus(ClearingEventStatus status) throws DaoException {
public List<ClearingEventInfo> getAllClearingEvents(ClearingEventStatus status) throws DaoException {
Query query = getDslContext().selectFrom(CLEARING_EVENT_INFO)
.where(CLEARING_EVENT_INFO.STATUS.eq(status));
return fetch(query, clearingEventsRowMapper);
}
@Override
public Long prepareTransactionData(long clearingId, String providerId) {
public Long prepareTransactionData(long clearingId, int providerId) {
PrepareTransactionData prepareTransactionData = new PrepareTransactionData();
prepareTransactionData.setClearingId(clearingId);
prepareTransactionData.setProviderId(providerId);
prepareTransactionData.execute();
prepareTransactionData.setSrcClearingId(clearingId);
prepareTransactionData.setSrcProviderId(providerId);
executeProc(prepareTransactionData);
return clearingId;
}

View File

@ -4,7 +4,7 @@ import com.rbkmoney.midgard.service.clearing.dao.common.ClearingDao;
import com.rbkmoney.midgard.service.clearing.exception.DaoException;
import org.jooq.generated.midgard.tables.pojos.ClearingRefund;
public interface ClearingRefundDao extends ClearingDao<ClearingRefund> {
public interface ClearingRefundDao extends ClearingDao<ClearingRefund, String> {
ClearingRefund getRefund(String transactionId) throws DaoException;

View File

@ -3,6 +3,7 @@ package com.rbkmoney.midgard.service.clearing.dao.common;
import com.rbkmoney.midgard.service.clearing.exception.DaoException;
import org.jooq.*;
import org.jooq.conf.ParamType;
import org.jooq.impl.AbstractRoutine;
import org.jooq.impl.DSL;
import org.jooq.impl.DefaultConfiguration;
import org.springframework.context.annotation.DependsOn;
@ -29,6 +30,7 @@ public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport im
setDataSource(dataSource);
Configuration configuration = new DefaultConfiguration();
configuration.set(SQLDialect.POSTGRES_9_5);
configuration.set(dataSource);
this.dslContext = DSL.using(configuration);
}
@ -36,6 +38,11 @@ public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport im
return dslContext;
}
@Override
public void executeProc(AbstractRoutine<Void> procedure) {
procedure.execute(dslContext.configuration());
}
@Override
public int execute(Query query) throws DaoException {
return execute(query, -1);

View File

@ -1,9 +1,9 @@
package com.rbkmoney.midgard.service.clearing.dao.common;
public interface ClearingDao<T> extends Dao {
public interface ClearingDao<T, V> extends Dao {
Long save(T element);
T get(String id);
T get(V id);
}

View File

@ -2,6 +2,7 @@ package com.rbkmoney.midgard.service.clearing.dao.common;
import com.rbkmoney.midgard.service.clearing.exception.DaoException;
import org.jooq.Query;
import org.jooq.impl.AbstractRoutine;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
@ -11,6 +12,8 @@ import java.util.List;
public interface Dao {
void executeProc(AbstractRoutine<Void> procedure);
int execute(Query query);
int execute(Query query, int expectedRowsAffected) throws DaoException;

View File

@ -8,7 +8,7 @@ import org.jooq.generated.midgard.tables.pojos.FailureTransaction;
import java.util.List;
public interface TransactionsDao extends ClearingDao<ClearingTransaction> {
public interface TransactionsDao extends ClearingDao<ClearingTransaction, String> {
ClearingTransaction getTransaction(String invoiceId, String paymentId) throws DaoException;

View File

@ -0,0 +1,17 @@
package com.rbkmoney.midgard.service.clearing.decorators;
import com.rbkmoney.midgard.ClearingAdapterSrv;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class ClearingAdapter {
private ClearingAdapterSrv.Iface adapter;
private String adapterName;
private int adapterId;
}

View File

@ -0,0 +1,21 @@
package com.rbkmoney.midgard.service.clearing.exception;
public class AdapterNotFoundException extends RuntimeException {
public AdapterNotFoundException(String message) {
super(message);
}
public AdapterNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public AdapterNotFoundException(Throwable cause) {
super(cause);
}
public AdapterNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -1,28 +1,25 @@
package com.rbkmoney.midgard.service.clearing.handlers;
import com.rbkmoney.midgard.ClearingAdapterException;
import com.rbkmoney.midgard.ClearingAdapterSrv;
import com.rbkmoney.midgard.ClearingDataPackage;
import com.rbkmoney.midgard.Transaction;
import com.rbkmoney.midgard.*;
import com.rbkmoney.midgard.service.clearing.decorators.ClearingAdapter;
import com.rbkmoney.midgard.service.clearing.dao.clearing_cash_flow.ClearingCashFlowDao;
import com.rbkmoney.midgard.service.clearing.dao.clearing_info.ClearingEventInfoDao;
import com.rbkmoney.midgard.service.clearing.dao.clearing_refund.ClearingRefundDao;
import com.rbkmoney.midgard.service.clearing.dao.transaction.TransactionsDao;
import com.rbkmoney.midgard.service.clearing.exception.AdapterNotFoundException;
import com.rbkmoney.midgard.service.clearing.utils.MappingUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.jooq.generated.midgard.enums.ClearingTrxType;
import org.jooq.generated.midgard.tables.pojos.ClearingEventTransactionInfo;
import org.jooq.generated.midgard.tables.pojos.ClearingRefund;
import org.jooq.generated.midgard.tables.pojos.ClearingTransaction;
import org.jooq.generated.midgard.tables.pojos.ClearingTransactionCashFlow;
import org.jooq.generated.midgard.tables.pojos.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import static org.jooq.generated.midgard.enums.ClearingTrxType.*;
import static org.jooq.generated.midgard.enums.ClearingTrxType.PAYMENT;
import static org.jooq.generated.midgard.enums.ClearingTrxType.REFUND;
@Slf4j
@RequiredArgsConstructor
@ -35,8 +32,9 @@ public class ClearingEventHandler implements Handler {
private final ClearingCashFlowDao cashFlowDao;
// TODO: адаптеров может быть много. Реализовать выбор из нескольких согласно provider id
private final ClearingAdapterSrv.Iface clearingAdapterService;
private final ClearingEventInfoDao clearingEventInfoDao;
private final List<ClearingAdapter> adapters;
@Value("${clearing-service.package-size}")
private int packageSize;
@ -45,18 +43,33 @@ public class ClearingEventHandler implements Handler {
@Override
public void handle(Long clearingId) {
int packagesCount = getClearingTransactionPackagesCount(clearingId);
for (int packageNumber = INIT_PACKAGE_NUMBER; packageNumber < packagesCount; packageNumber++) {
ClearingDataPackage dataPackage = getClearingTransactionPackage(clearingId, packageNumber);
try {
//TODO: нужно предварительно получить конкретный адаптер из списка
clearingAdapterService.sendClearingDataPackage(dataPackage);
} catch (ClearingAdapterException ex) {
//TODO: придумать обработку ошибки
log.error("Error occurred while processing the package by the adapter", ex);
} catch (TException ex) {
log.error("Вata transfer error", ex);
try {
ClearingEventInfo clearingEventInfo = clearingEventInfoDao.get(clearingId);
int providerId = clearingEventInfo == null ? 0 : clearingEventInfo.getProviderId();
ClearingAdapter clearingAdapter = adapters.stream()
.filter(clrAdapter -> clrAdapter.getAdapterId() == providerId)
.findFirst()
.orElseThrow(() ->
new AdapterNotFoundException("Adapter with provider id " + providerId + " not found"));
ClearingAdapterSrv.Iface adapter = clearingAdapter.getAdapter();
String uploadId = adapter.startClearingEvent(clearingId);
int packagesCount = getClearingTransactionPackagesCount(clearingId);
List<ClearingDataPackageTag> tagList = new ArrayList<>();
for (int packageNumber = INIT_PACKAGE_NUMBER; packageNumber < packagesCount; packageNumber++) {
ClearingDataPackage dataPackage = getClearingTransactionPackage(clearingId, packageNumber);
ClearingDataPackageTag tag = adapter.sendClearingDataPackage(uploadId, dataPackage);
tagList.add(tag);
}
adapter.completeClearingEvent(uploadId, clearingId, tagList);
} catch (ClearingAdapterException ex) {
log.error("Error occurred while processing the package by the adapter", ex);
//TODO: реализовать корректную обработку ошибки
} catch (TException e) {
log.error("Error communicating with adapter", e);
// TODO: реализовать корректную обработку ошибки
}
}
@ -83,7 +96,7 @@ public class ClearingEventHandler implements Handler {
private Transaction getTransaction(ClearingEventTransactionInfo info) {
ClearingTransaction clearingTransaction = transactionsDao.get(info.getTransactionId());
List<ClearingTransactionCashFlow> cashFlowList =
cashFlowDao.get(clearingTransaction.getEventId().toString());
cashFlowDao.get(clearingTransaction.getEventId());
return MappingUtils.transformClearingTransaction(clearingTransaction, cashFlowList);
}
@ -92,7 +105,7 @@ public class ClearingEventHandler implements Handler {
ClearingTransaction clearingTransaction =
transactionsDao.getTransaction(refund.getInvoiceId(), refund.getPaymentId());
List<ClearingTransactionCashFlow> cashFlowList =
cashFlowDao.get(clearingTransaction.getEventId().toString());
cashFlowDao.get(clearingTransaction.getEventId());
return MappingUtils.transformRefundTransaction(clearingTransaction, cashFlowList, refund);
}
@ -104,7 +117,7 @@ public class ClearingEventHandler implements Handler {
private int getClearingTransactionPackagesCount(long clearingId) {
int packagesCount = transactionsDao.getProcessedClearingTransactionCount(clearingId);
return (int) Math.floor((double) packagesCount / packageSize);
return (int) Math.ceil((double) packagesCount / packageSize);
}
}

View File

@ -30,7 +30,7 @@ public class ClearingEventService implements ClearingServiceSrv.Iface {
@Override
public void startClearingEvent(ClearingEvent clearingEvent) {
long eventId = clearingEvent.getEventId();
String providerId = clearingEvent.getProviderId();
int providerId = clearingEvent.getProviderId();
log.info("Starting clearing event for provider id {}", providerId);
// Подготовка транзакций для клиринга
Long clearingId = prepareClearingEvent(eventId, providerId);
@ -54,14 +54,16 @@ public class ClearingEventService implements ClearingServiceSrv.Iface {
}
@Transactional
public Long prepareClearingEvent(long eventId, String providerId) {
public Long prepareClearingEvent(long eventId, int providerId) {
Long clearingId = createNewClearingEvent(eventId, providerId);
clearingEventInfoDao.prepareTransactionData(clearingId, providerId);
return clearingId;
}
//TODO: рассмотреть вариант, когда для банка присутствует незавершенное клиринговое событие.
private Long createNewClearingEvent(long eventId, String providerId) {
// TODO: рассмотреть вариант, когда для банка присутствует незавершенное клиринговое событие.
// Возможно имеет смысл анализировать статус незавершенного события и в зависимости от этого
// завершать зависшее событие и начинать его заново, либо отбивать пришедшее с ошибкой
private Long createNewClearingEvent(long eventId, int providerId) {
log.trace("Creating new clearing event for provider {} by event ", providerId, eventId);
ClearingEventInfo clearingEvent = new ClearingEventInfo();
clearingEvent.setProviderId(providerId);

View File

@ -23,7 +23,7 @@ import java.util.stream.Collectors;
@Service
public class ClearingRevisionService implements GenericService {
private final ClearingEventInfoDao clearingEventInfoDao;
private final ClearingEventInfoDao eventInfoDao;
private final ClearingRevisionHandler revisionHandler;
@ -32,9 +32,9 @@ public class ClearingRevisionService implements GenericService {
public void process() {
log.info("Clearing revision process get started");
List<ClearingEventInfo> clearingEvents = clearingEventInfoDao.getClearingEventsByStatus(ClearingEventStatus.EXECUTE);
List<ClearingEventInfo> clearingEvents = eventInfoDao.getAllClearingEvents(ClearingEventStatus.EXECUTE);
List<Long> clearingIds = clearingEvents.stream()
.map(event -> event.getId())
.map(ClearingEventInfo::getId)
.collect(Collectors.toList());
log.debug("Active clearing event IDs: {}", clearingIds);

View File

@ -11,6 +11,7 @@ import org.jooq.generated.midgard.tables.pojos.ClearingRefund;
import org.jooq.generated.midgard.tables.pojos.ClearingTransaction;
import org.jooq.generated.midgard.tables.pojos.ClearingTransactionCashFlow;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
@ -23,12 +24,13 @@ public final class MappingUtils {
trx.setInvoiceId(payment.getInvoiceId());
trx.setPaymentId(payment.getPaymentId());
trx.setProviderId(payment.getRouteProviderId());
//TODO: что то придумать с tran_id
trx.setTransactionId(payment.getInvoiceId() + "_" + payment.getPaymentId());
trx.setTransactionDate(payment.getCreatedAt());
trx.setTransactionAmount(payment.getAmount());
trx.setTransactionCurrency(payment.getCurrencyCode());
trx.setTransactionClearingState(TransactionClearingState.READY);
trx.setPartyId(payment.getPartyId());
trx.setShopId(payment.getShopId());
@ -37,9 +39,6 @@ public final class MappingUtils {
trx.setPayerBankCardBin(payment.getPayerBankCardBin());
trx.setPayerBankCardMaskedPan(payment.getPayerBankCardMaskedPan());
trx.setPayerBankCardTokenProvider(payment.getPayerBankCardTokenProvider());
trx.setFee(payment.getFee());
trx.setExternalFee(payment.getExternalFee());
trx.setProviderFee(payment.getProviderFee());
trx.setExtra(payment.getSessionPayloadTransactionBoundTrxExtraJson());
return trx;
}
@ -62,11 +61,11 @@ public final class MappingUtils {
Transaction tran = new Transaction();
GeneralTransactionInfo generalTranInfo = new GeneralTransactionInfo();
generalTranInfo.setTransactionId(clrTran.getTransactionId());
//TODO: перешнать в строку по отпределенному формату
generalTranInfo.setTransactionDate(clrTran.getTransactionDate().toString());
//TODO: проверить корректность получения даты на адаптере
generalTranInfo.setTransactionDate(clrTran.getTransactionDate().toInstant(ZoneOffset.UTC).toString());
generalTranInfo.setTransactionAmount(clrTran.getTransactionAmount());
generalTranInfo.setTransactionCurrency(clrTran.getTransactionCurrency());
generalTranInfo.setMcc(clrTran.getMcc());
generalTranInfo.setMcc(clrTran.getMcc() == null ? 0 : clrTran.getMcc());
tran.setGeneralTransactionInfo(generalTranInfo);
TransactionCardInfo tranCardInfo = new TransactionCardInfo();
@ -80,6 +79,7 @@ public final class MappingUtils {
Content additionalTranData = new Content();
additionalTranData.setType("String");
//TODO: Возможно так же стоит передавать строку, но не факт
//TODO: проверить на конкретном extra
additionalTranData.setData(clrTran.getExtra().getBytes());
tran.setAdditionalTransactionData(additionalTranData);
@ -95,30 +95,34 @@ public final class MappingUtils {
private static TransactionCashFlow transformCashFlow(ClearingTransactionCashFlow cashFlow) {
TransactionCashFlow tranCashFlow = new TransactionCashFlow();
tranCashFlow.setObjType(CashFlowChangeType.valueOf(cashFlow.getObjType().name()));
tranCashFlow.setAmount(cashFlow.getAmount());
tranCashFlow.setCurrencyCode(cashFlow.getCurrencyCode());
tranCashFlow.setSourceAccountId(cashFlow.getSourceAccountId());
tranCashFlow.setSourceAccountType(CashFlowAccountType.valueOf(cashFlow.getSourceAccountType().getName()));
tranCashFlow.setSourceAccountType(CashFlowAccountType.valueOf(cashFlow.getSourceAccountType().name()));
tranCashFlow.setSourceAccountTypeValue(cashFlow.getSourceAccountTypeValue());
tranCashFlow.setDestinationAccountId(cashFlow.getDestinationAccountId());
tranCashFlow.setDestinationAccountType(
CashFlowAccountType.valueOf(cashFlow.getDestinationAccountType().getName()));
CashFlowAccountType.valueOf(cashFlow.getDestinationAccountType().name()));
tranCashFlow.setDestinationAccountTypeValue(cashFlow.getDestinationAccountTypeValue());
tranCashFlow.setObjType(CashFlowChangeType.valueOf(cashFlow.getObjType().getName()));
return tranCashFlow;
}
public static ClearingTransactionCashFlow transformCashFlow(CashFlow cashFlow) {
ClearingTransactionCashFlow tranCashFlow = new ClearingTransactionCashFlow();
tranCashFlow.setObjType(PaymentChangeType.valueOf(cashFlow.getObjType().name()));
tranCashFlow.setAmount(cashFlow.getAmount());
tranCashFlow.setCurrencyCode(cashFlow.getCurrencyCode());
tranCashFlow.setSourceAccountId(cashFlow.getSourceAccountId());
tranCashFlow.setSourceAccountType(CashFlowAccount.valueOf(cashFlow.getSourceAccountType().getName()));
tranCashFlow.setSourceAccountType(CashFlowAccount.valueOf(cashFlow.getSourceAccountType().name()));
tranCashFlow.setSourceAccountTypeValue(cashFlow.getSourceAccountTypeValue());
tranCashFlow.setDestinationAccountId(cashFlow.getDestinationAccountId());
tranCashFlow.setDestinationAccountType(CashFlowAccount.valueOf(cashFlow.getDestinationAccountType().getName()));
tranCashFlow.setDestinationAccountType(CashFlowAccount.valueOf(cashFlow.getDestinationAccountType().name()));
tranCashFlow.setDestinationAccountTypeValue(cashFlow.getDestinationAccountTypeValue());
tranCashFlow.setObjType(PaymentChangeType.valueOf(cashFlow.getObjType().getName()));
return tranCashFlow;
}

View File

@ -1,6 +1,7 @@
package com.rbkmoney.midgard.service.config;
import com.rbkmoney.midgard.ClearingAdapterSrv;
import com.rbkmoney.midgard.service.clearing.decorators.ClearingAdapter;
import com.rbkmoney.midgard.service.config.props.MtsAdapterProps;
import com.rbkmoney.woody.thrift.impl.http.THSpawnClientBuilder;
import org.springframework.context.annotation.Bean;
@ -19,4 +20,11 @@ public class ClearingServiceConfig {
.build(ClearingAdapterSrv.Iface.class);
}
@Bean
public ClearingAdapter mtsClearingAdapter(MtsAdapterProps props) throws IOException {
return new ClearingAdapter(mtsClearingAdapterThriftClient(props),
props.getName(),
props.getProviderId());
}
}

View File

@ -7,7 +7,7 @@ CREATE TABLE midgard.clearing_transaction (
event_id BIGINT NOT NULL,
invoice_id CHARACTER VARYING NOT NULL,
payment_id CHARACTER VARYING NOT NULL,
provider_id INT NOT NULL,
provider_id INTEGER NOT NULL,
transaction_id CHARACTER VARYING NOT NULL,
transaction_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
transaction_amount BIGINT NOT NULL,
@ -15,8 +15,6 @@ CREATE TABLE midgard.clearing_transaction (
transaction_clearing_state transaction_clearing_state NOT NULL,
party_id CHARACTER VARYING NOT NULL,
shop_id CHARACTER VARYING NOT NULL,
terminal_id VARCHAR(8) NULL,
optional_json CHARACTER VARYING NULL,
mcc INTEGER NULL,
payer_bank_card_token CHARACTER VARYING NULL,
payer_bank_card_payment_system CHARACTER VARYING NULL,
@ -24,9 +22,6 @@ CREATE TABLE midgard.clearing_transaction (
payer_bank_card_masked_pan CHARACTER VARYING NULL,
payer_bank_card_token_provider CHARACTER VARYING NULL,
extra CHARACTER VARYING NULL,
fee BIGINT NULL,
provider_fee BIGINT NULL,
external_fee BIGINT NULL,
comment CHARACTER VARYING NULL,
clearing_id BIGINT NULL,
last_act_time TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc'),
@ -63,9 +58,9 @@ CREATE INDEX clearing_refund_state_idx ON midgard.clearing_refund (payment_id, i
/***************************************************************************/
CREATE TYPE midgard.cash_flow_account AS ENUM ('MERCHANT', 'PROVIDER', 'SYSTEM', 'EXTERNAL', 'WALLET');
CREATE TYPE midgard.cash_flow_account AS ENUM ('merchant', 'provider', 'system', 'external', 'wallet');
CREATE TYPE midgard.payment_change_type AS ENUM ('PAYMENT', 'REFUND', 'ADJUSTMENT', 'PAYOUT');
CREATE TYPE midgard.payment_change_type AS ENUM ('payment', 'refund', 'adjustment', 'payout');
CREATE TABLE midgard.clearing_transaction_cash_flow(
id BIGSERIAL NOT NULL,
@ -93,7 +88,7 @@ CREATE TABLE midgard.clearing_event_info (
id BIGSERIAL NOT NULL,
event_id BIGINT NOT NULL,
date TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc'),
provider_id VARCHAR(100) NOT NULL,
provider_id INTEGER NOT NULL,
status clearing_event_status NOT NULL,
CONSTRAINT clearing_event_info_PK PRIMARY KEY (id)
);

View File

@ -1,35 +1,35 @@
CREATE OR REPLACE FUNCTION midgard.prepare_transaction_data(clearing_id bigint, provider_id varchar(100))
CREATE OR REPLACE FUNCTION midgard.prepare_transaction_data(src_clearing_id bigint, src_provider_id int)
RETURNS VOID
LANGUAGE PLPGSQL
IMMUTABLE
VOLATILE
PARALLEL SAFE
AS $$
BEGIN
/** Получение списка готовых к клиринговому событию транзакций */
WITH clearing_trx_cte as (
SELECT clearing_id,
SELECT src_clearing_id as clearing_id,
trx.transaction_id,
'PAYMENT' as trx_type
cast('PAYMENT' as midgard.clearing_trx_type) as trx_type
FROM midgard.clearing_transaction trx
WHERE trx.provider_id = provider_id
WHERE trx.provider_id = src_provider_id
AND trx.transaction_clearing_state in ('READY', 'FAILED')
),
clearing_refund_trx_cte as (
SELECT clearing_id,
SELECT src_clearing_id as clearing_id,
refund_trx.transaction_id,
'REFUND' as trx_type
cast('REFUND' as midgard.clearing_trx_type) as trx_type
FROM midgard.clearing_refund refund_trx
JOIN midgard.clearing_transaction trx
ON trx.provider_id = provider_id
ON trx.provider_id = src_provider_id
AND refund_trx.invoice_id = trx.invoice_id
AND refund_trx.payment_id = trx.payment_id
WHERE refund_trx.transaction_clearing_state in ('READY', 'FAILED')
WHERE refund_trx.clearing_state in ('READY', 'FAILED')
),
ordered_clearing_trx_cte as (
SELECT clearing_id, transaction_id, trx_type, trx_state,
row_number() over(partition BY clearing_id ORDER BY trx_state, transaction_id) as row_num
SELECT clearing_id, transaction_id, trx_type,
row_number() over(partition BY clearing_id ORDER BY trx_type, transaction_id) as row_num
FROM (
SELECT * FROM clearing_trx_cte
UNION ALL
@ -37,23 +37,23 @@ BEGIN
) cte
)
INSERT INTO midgard.clearing_event_info(clearing_id, transaction_id, transaction_type, state, row_number)
SELECT clearing_id, transaction_id, trx_type, trx_state, row_num
INSERT INTO midgard.clearing_event_transaction_info(clearing_id, transaction_id, transaction_type, row_number)
SELECT clearing_id, transaction_id, trx_type, row_num
FROM ordered_clearing_trx_cte;
/** Перевести статус добавленных в клиринговый эвент транзакций в статус "ACTIVE" */
UPDATE midgard.clearing_transaction
SET transaction_clearing_state = 'ACTIVE'
SET transaction_clearing_state = cast('ACTIVE' as midgard.transaction_clearing_state)
WHERE transaction_id IN (SELECT transaction_id
FROM midgard.clearing_event_info cei
WHERE cei.clearing_id = clearing_id
FROM midgard.clearing_event_transaction_info cei
WHERE cei.clearing_id = src_clearing_id
and transaction_type = 'PAYMENT');
UPDATE midgard.clearing_refund
SET clearing_state = 'ACTIVE'
SET clearing_state = cast('ACTIVE' as midgard.transaction_clearing_state)
WHERE transaction_id IN (SELECT transaction_id
FROM midgard.clearing_event_info cei
WHERE cei.clearing_id = clearing_id
FROM midgard.clearing_event_transaction_info cei
WHERE cei.clearing_id = src_clearing_id
and transaction_type = 'REFUND');
END;

View File

@ -1,12 +0,0 @@
package com.rbkmoney.midgard.base.test;
import org.junit.Test;
public class SimpleTest {
@Test
public void simpleTest() {
//TODO: write tests
}
}

View File

@ -0,0 +1,134 @@
package com.rbkmoney.midgard.base.tests.integration;
import com.opentable.db.postgres.embedded.EmbeddedPostgres;
import com.rbkmoney.midgard.service.MidgardClearingApplication;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.plugins.annotations.Parameter;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.boot.test.util.TestPropertyValues.Type.MAP;
/**
* Created by jeckep on 08.02.17.
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@TestPropertySource(properties = {"bm.pollingEnabled=false"})
@ContextConfiguration(classes = {MidgardClearingApplication.class},
initializers = AbstractIntegrationTest.Initializer.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public abstract class AbstractIntegrationTest {
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Parameter(defaultValue = "${project.build.directory}")
private static String projectBuildDir;
private static final int port = 15432;
private static final String dbName = "midgard";
private static final String dbUser = "postgres";
private static final String dbPassword = "postgres";
private static final String jdbcUrl = "jdbc:postgresql://localhost:" + port + "/" + dbName;
private EmbeddedPostgres postgres;
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of("spring.datasource.url=" + jdbcUrl,
"spring.datasource.username=" + dbUser,
"spring.datasource.password=" + dbPassword,
"flyway.url=" + jdbcUrl,
"flyway.user=" + dbUser,
"flyway.password=" + dbPassword)
.applyTo(configurableApplicationContext.getEnvironment(), MAP, "testcontainers");
if (postgres == null) {
startPgServer();
createDatabase();
}
}
private void startPgServer() {
try {
log.info("The PG server is starting...");
EmbeddedPostgres.Builder builder = EmbeddedPostgres.builder();
String dbDir = prepareDbDir(projectBuildDir);
log.info("Dir for PG files: " + dbDir);
builder.setDataDirectory(dbDir);
builder.setPort(port);
postgres = builder.start();
log.info("The PG server was started!");
} catch (IOException e) {
log.error("An error occurred while starting server ", e);
e.printStackTrace();
}
}
private void createDatabase() {
try (Connection conn = postgres.getPostgresDatabase().getConnection()) {
Statement statement = conn.createStatement();
statement.execute("CREATE DATABASE " + dbName);
statement.close();
} catch (SQLException e) {
log.error("An error occurred while creating the database "+ dbName, e);
e.printStackTrace();
}
}
private void dropScheme(String schemaName) {
log.debug("Delete {} scheme", schemaName);
DataSource database = postgres.getDatabase(dbUser, dbName);
try (Connection connection = database.getConnection()) {
Statement statement = connection.createStatement();
statement.execute("DROP SCHEMA " + schemaName + " CASCADE");
statement.close();
} catch (SQLException ex) {
log.error("An error occurred while drop the schema " + schemaName);
ex.printStackTrace();
}
}
private String prepareDbDir(String projectBuildDir) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String currentDate = dateFormat.format(new Date());
String dir = projectBuildDir + File.separator + "pgdata_" + currentDate;
log.info("Postgres source files in {}", dir);
return dir;
}
@After
public void destroy() throws IOException {
if (postgres != null) {
postgres.close();
postgres = null;
}
}
}
}

View File

@ -0,0 +1,37 @@
package com.rbkmoney.midgard.base.tests.integration;
import com.rbkmoney.midgard.ClearingEvent;
import com.rbkmoney.midgard.service.clearing.services.ClearingEventService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class ClearingEventIntegrationTest extends AbstractIntegrationTest {
@Autowired
private ClearingEventService clearingEventService;
private ClearingEvent clearingEvent;
@Test
public void clearingEventIntegrationTest() throws InterruptedException {
ClearingEvent clearingEvent = new ClearingEvent();
clearingEvent.setEventId(1);
clearingEvent.setProviderId(100);
//TODO: write integration tests
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
lock.tryLock(60L, TimeUnit.SECONDS);
} finally {
lock.unlock();
}
}
}

View File

@ -0,0 +1,45 @@
package com.rbkmoney.midgard.base.tests.unit;
import com.rbkmoney.midgard.Transaction;
import org.jooq.generated.feed.tables.pojos.Payment;
import org.jooq.generated.feed.tables.pojos.Refund;
import org.jooq.generated.midgard.tables.pojos.ClearingRefund;
import org.jooq.generated.midgard.tables.pojos.ClearingTransaction;
import org.jooq.generated.midgard.tables.pojos.ClearingTransactionCashFlow;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static com.rbkmoney.midgard.base.tests.unit.data.TestTransactionsData.*;
import static com.rbkmoney.midgard.service.clearing.utils.MappingUtils.*;
import static org.junit.Assert.assertEquals;
public class MappingTest {
@Test
public void transactionTest() {
Payment payment = getTestPayment();
ClearingTransaction transaction = transformTransaction(payment);
ClearingTransaction testClearingTransaction = getTestClearingTransaction();
assertEquals("Resulting clearing transaction is not equal to the reference",
transaction, testClearingTransaction);
List<ClearingTransactionCashFlow> clearingTransactionCashFlowList = new ArrayList<>();
clearingTransactionCashFlowList.add(getTestClearingTransactionCashFlow());
Transaction protoTransaction = transformClearingTransaction(transaction, clearingTransactionCashFlowList);
Transaction testProtoTransaction = getTestProtoTransaction();
assertEquals("Resulting transaction is not equal to the reference",
protoTransaction, testProtoTransaction);
}
@Test
public void refundTransactionTest() {
Refund testRefund = getTestRefund();
ClearingRefund clearingRefund = transformRefund(testRefund);
ClearingRefund testClearingRefund = getTestClearingRefund();
assertEquals("Resulting clearing refund transaction is not equal to the reference",
clearingRefund, testClearingRefund);
}
}

View File

@ -0,0 +1,188 @@
package com.rbkmoney.midgard.base.tests.unit.data;
import com.rbkmoney.midgard.*;
import org.jooq.generated.feed.tables.pojos.CashFlow;
import org.jooq.generated.feed.tables.pojos.Payment;
import org.jooq.generated.feed.tables.pojos.Refund;
import org.jooq.generated.midgard.enums.TransactionClearingState;
import org.jooq.generated.midgard.tables.pojos.ClearingRefund;
import org.jooq.generated.midgard.tables.pojos.ClearingTransaction;
import org.jooq.generated.midgard.tables.pojos.ClearingTransactionCashFlow;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
public final class TestTransactionsData {
private static final LocalDateTime dateTIme =
LocalDateTime.of(2019, 01, 12, 12, 12, 44);
public static Payment getTestPayment() {
Payment payment = new Payment();
payment.setEventId(1L);
payment.setEventCreatedAt(dateTIme);
payment.setInvoiceId("invoice_1");
payment.setPaymentId("payment_1");
payment.setRouteProviderId(1);
payment.setCreatedAt(dateTIme);
payment.setAmount(1000L);
payment.setCurrencyCode("RUB");
payment.setPartyId("pt_1");
payment.setShopId("sh_1");
payment.setPayerBankCardToken("token_1");
payment.setPayerBankCardPaymentSystem("visa");
payment.setPayerBankCardBin("454545");
payment.setPayerBankCardMaskedPan("4545 45** **** 9809");
payment.setPayerBankCardTokenProvider("provider_1");
payment.setSessionPayloadTransactionBoundTrxExtraJson("extra json");
return payment;
}
public static ClearingTransaction getTestClearingTransaction() {
ClearingTransaction trx = new ClearingTransaction();
trx.setEventId(1L);
trx.setInvoiceId("invoice_1");
trx.setPaymentId("payment_1");
trx.setProviderId(1);
trx.setTransactionId(trx.getInvoiceId() + "_" + trx.getPaymentId());
trx.setTransactionDate(dateTIme);
trx.setTransactionAmount(1000L);
trx.setTransactionCurrency("RUB");
trx.setTransactionClearingState(TransactionClearingState.READY);
trx.setPartyId("pt_1");
trx.setShopId("sh_1");
trx.setPayerBankCardToken("token_1");
trx.setPayerBankCardPaymentSystem("visa");
trx.setPayerBankCardBin("454545");
trx.setPayerBankCardMaskedPan("4545 45** **** 9809");
trx.setPayerBankCardTokenProvider("provider_1");
trx.setExtra("extra json");
return trx;
}
public static CashFlow getTestCashFlow() {
CashFlow cashFlow = new CashFlow();
cashFlow.setAmount(1000L);
cashFlow.setCurrencyCode("RUB");
cashFlow.setSourceAccountId(1L);
cashFlow.setSourceAccountType(org.jooq.generated.feed.enums.CashFlowAccount.merchant);
cashFlow.setSourceAccountTypeValue("1000");
cashFlow.setDestinationAccountId(2L);
cashFlow.setDestinationAccountType(org.jooq.generated.feed.enums.CashFlowAccount.system);
cashFlow.setDestinationAccountTypeValue("20");
cashFlow.setObjType(org.jooq.generated.feed.enums.PaymentChangeType.payment);
return cashFlow;
}
public static ClearingTransactionCashFlow getTestClearingTransactionCashFlow() {
ClearingTransactionCashFlow tranCashFlow = new ClearingTransactionCashFlow();
tranCashFlow.setAmount(1000L);
tranCashFlow.setCurrencyCode("RUB");
tranCashFlow.setSourceAccountId(1L);
tranCashFlow.setSourceAccountType(org.jooq.generated.midgard.enums.CashFlowAccount.merchant);
tranCashFlow.setSourceAccountTypeValue("1000");
tranCashFlow.setDestinationAccountId(2L);
tranCashFlow.setDestinationAccountType(org.jooq.generated.midgard.enums.CashFlowAccount.system);
tranCashFlow.setDestinationAccountTypeValue("20");
tranCashFlow.setObjType(org.jooq.generated.midgard.enums.PaymentChangeType.payment);
return tranCashFlow;
}
public static TransactionCashFlow getTestTransactionCashFlow() {
TransactionCashFlow tranCashFlow = new TransactionCashFlow();
tranCashFlow.setAmount(1000L);
tranCashFlow.setCurrencyCode("RUB");
tranCashFlow.setSourceAccountId(1L);
tranCashFlow.setSourceAccountType(CashFlowAccountType.merchant);
tranCashFlow.setSourceAccountTypeValue("1000");
tranCashFlow.setDestinationAccountId(2L);
tranCashFlow.setDestinationAccountType(CashFlowAccountType.system);
tranCashFlow.setDestinationAccountTypeValue("20");
tranCashFlow.setObjType(CashFlowChangeType.payment);
return tranCashFlow;
}
public static Transaction getTestProtoTransaction() {
Transaction trx = new Transaction();
GeneralTransactionInfo generalTranInfo = new GeneralTransactionInfo();
generalTranInfo.setTransactionId("invoice_1_payment_1");
generalTranInfo.setTransactionDate(dateTIme.toInstant(ZoneOffset.UTC).toString());
generalTranInfo.setTransactionAmount(1000L);
generalTranInfo.setTransactionCurrency("RUB");
generalTranInfo.setMcc(0);
trx.setGeneralTransactionInfo(generalTranInfo);
TransactionCardInfo tranCardInfo = new TransactionCardInfo();
tranCardInfo.setPayerBankCardToken("token_1");
tranCardInfo.setPayerBankCardBin("454545");
tranCardInfo.setPayerBankCardMaskedPan("4545 45** **** 9809");
tranCardInfo.setPayerBankCardPaymentSystem("visa");
tranCardInfo.setPayerBankCardTokenProvider("provider_1");
trx.setTransactionCardInfo(tranCardInfo);
Content additionalTranData = new Content();
additionalTranData.setType("String");
//TODO: Возможно так же стоит передавать строку, но не факт
additionalTranData.setData("extra json".getBytes());
trx.setAdditionalTransactionData(additionalTranData);
List<TransactionCashFlow> transactionCashFlowList = new ArrayList<>();
transactionCashFlowList.add(getTestTransactionCashFlow());
trx.setTransactionCashFlow(transactionCashFlowList);
return trx;
}
public static Refund getTestRefund() {
Refund refund = new Refund();
refund.setEventId(3L);
refund.setInvoiceId("invoice_3");
refund.setPaymentId("payment_3");
refund.setPartyId("pt_3");
refund.setShopId("sh_3");
refund.setCreatedAt(dateTIme);
refund.setAmount(1000L);
refund.setCurrencyCode("RUB");
refund.setReason("some reason");
refund.setDomainRevision(1L);
return refund;
}
public static ClearingRefund getTestClearingRefund() {
ClearingRefund clearingRefund = new ClearingRefund();
clearingRefund.setEventId(3L);
clearingRefund.setInvoiceId("invoice_3");
clearingRefund.setPaymentId("payment_3");
clearingRefund.setPartyId("pt_3");
clearingRefund.setShopId("sh_3");
clearingRefund.setCreatedAt(dateTIme);
clearingRefund.setAmount(1000L);
clearingRefund.setCurrencyCode("RUB");
clearingRefund.setReason("some reason");
clearingRefund.setDomainRevision(1L);
clearingRefund.setClearingState(TransactionClearingState.READY);
return clearingRefund;
}
private TestTransactionsData() {}
}

View File

@ -12,7 +12,7 @@
<parent>
<groupId>com.rbkmoney</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<version>2.1.0.RELEASE</version>
</parent>
<groupId>com.rbkmoney</groupId>
@ -100,7 +100,7 @@
<dependency>
<groupId>com.rbkmoney</groupId>
<artifactId>midgard-proto</artifactId>
<version>1.4-1651ed1</version>
<version>1.7-a90a857</version>
</dependency>
<dependency>
<groupId>com.rbkmoney</groupId>