mirror of
https://github.com/valitydev/fraudo.git
synced 2024-11-06 01:45:16 +00:00
P2p change (#19)
* Generalize interfaces * Add tests for p2p * Add currency function * Added naming lists * Change logic exception
This commit is contained in:
parent
90a88facbe
commit
d714889a6d
2
pom.xml
2
pom.xml
@ -11,7 +11,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>fraudo</artifactId>
|
||||
<version>0.0.8-SNAPSHOT</version>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<hamcrest.junit.version>2.0.0.0</hamcrest.junit.version>
|
||||
|
@ -25,10 +25,12 @@ expression
|
||||
| in_white_list #inWhiteListExpression
|
||||
| in_black_list #inBlackListExpression
|
||||
| in_grey_list #inGreyListExpression
|
||||
| in_list #inListExpression
|
||||
| like #likeFunctionExpression
|
||||
| country #countryFunctionExpression
|
||||
| country_by #countryByFunctionExpression
|
||||
| amount #amountFunctionExpression
|
||||
| currency #currencyFunctionExpression
|
||||
| IDENTIFIER #identifierExpression
|
||||
| DECIMAL #decimalExpression
|
||||
| STRING #stringExpression
|
||||
@ -50,6 +52,10 @@ amount
|
||||
: 'amount' LPAREN RPAREN
|
||||
;
|
||||
|
||||
currency
|
||||
: 'currency' LPAREN RPAREN
|
||||
;
|
||||
|
||||
count
|
||||
: 'count' LPAREN STRING time_window (group_by)? RPAREN
|
||||
;
|
||||
@ -94,6 +100,10 @@ in_grey_list
|
||||
: 'inGreyList' LPAREN string_list RPAREN
|
||||
;
|
||||
|
||||
in_list
|
||||
: 'inList' LPAREN STRING DELIMETER string_list RPAREN
|
||||
;
|
||||
|
||||
like
|
||||
: 'like' LPAREN STRING DELIMETER STRING RPAREN
|
||||
;
|
||||
|
@ -1,26 +1,15 @@
|
||||
package com.rbkmoney.fraudo.aggregator;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.TimeWindow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CountAggregator {
|
||||
public interface CountAggregator<T, U> {
|
||||
|
||||
@Deprecated
|
||||
Integer count(CheckedField checkedField, FraudModel model, Long timeInMinutes);
|
||||
Integer count(U checkedField, T model, TimeWindow timeWindow, List<U> fields);
|
||||
|
||||
Integer count(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, List<CheckedField> fields);
|
||||
Integer countSuccess(U checkedField, T model, TimeWindow timeWindow, List<U> fields);
|
||||
|
||||
@Deprecated
|
||||
Integer countSuccess(CheckedField checkedField, FraudModel model, Long timeInMinutes);
|
||||
|
||||
Integer countSuccess(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, List<CheckedField> fields);
|
||||
|
||||
@Deprecated
|
||||
Integer countError(CheckedField checkedField, FraudModel model, Long timeInMinutes, String errorCode);
|
||||
|
||||
Integer countError(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, String errorCode, List<CheckedField> fields);
|
||||
Integer countError(U checkedField, T model, TimeWindow timeWindow, String errorCode, List<U> fields);
|
||||
|
||||
}
|
||||
|
@ -1,26 +1,15 @@
|
||||
package com.rbkmoney.fraudo.aggregator;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.TimeWindow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SumAggregator {
|
||||
public interface SumAggregator<T, U> {
|
||||
|
||||
@Deprecated
|
||||
Double sum(CheckedField checkedField, FraudModel model, Long timeInMinutes);
|
||||
Double sum(U checkedField, T model, TimeWindow timeWindow, List<U> fields);
|
||||
|
||||
Double sum(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, List<CheckedField> fields);
|
||||
Double sumSuccess(U checkedField, T model, TimeWindow timeWindow, List<U> fields);
|
||||
|
||||
@Deprecated
|
||||
Double sumSuccess(CheckedField checkedField, FraudModel model, Long timeInMinutes);
|
||||
|
||||
Double sumSuccess(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, List<CheckedField> fields);
|
||||
|
||||
@Deprecated
|
||||
Double sumError(CheckedField checkedField, FraudModel model, Long timeInMinutes, String errorCode);
|
||||
|
||||
Double sumError(CheckedField checkedField, FraudModel model, TimeWindow timeWindow, String errorCode, List<CheckedField> fields);
|
||||
Double sumError(U checkedField, T model, TimeWindow timeWindow, String errorCode, List<U> fields);
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,11 @@
|
||||
package com.rbkmoney.fraudo.aggregator;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.TimeWindow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UniqueValueAggregator {
|
||||
public interface UniqueValueAggregator<T, U> {
|
||||
|
||||
@Deprecated
|
||||
Integer countUniqueValue(CheckedField countField, FraudModel fraudModel, CheckedField onField, Long time);
|
||||
|
||||
Integer countUniqueValue(CheckedField countField, FraudModel fraudModel, CheckedField onField, TimeWindow timeWindow, List<CheckedField> fields);
|
||||
Integer countUniqueValue(U countField, T payoutModel, U onField, TimeWindow timeWindow, List<U> fields);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.rbkmoney.fraudo.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum P2PCheckedField {
|
||||
|
||||
EMAIL("email"),
|
||||
IP("ip"),
|
||||
FINGERPRINT("fingerprint"),
|
||||
COUNTRY_BANK("country_bank"),
|
||||
BIN("bin"),
|
||||
PAN("pan"),
|
||||
CURRENCY("currency"),
|
||||
IDENTITY_ID("identity_id"),
|
||||
CARD_TOKEN_FROM("card_token_from"),
|
||||
CARD_TOKEN_TO("card_token_to");
|
||||
|
||||
private String value;
|
||||
private static Map<String, P2PCheckedField> valueMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (P2PCheckedField value : P2PCheckedField.values()) {
|
||||
valueMap.put(value.value, value);
|
||||
}
|
||||
}
|
||||
|
||||
P2PCheckedField(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static P2PCheckedField getByValue(String value) {
|
||||
return valueMap.get(value);
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package com.rbkmoney.fraudo.constant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum CheckedField {
|
||||
public enum PaymentCheckedField {
|
||||
|
||||
EMAIL("email"),
|
||||
IP("ip"),
|
||||
@ -12,24 +12,25 @@ public enum CheckedField {
|
||||
COUNTRY_IP("country_ip"),
|
||||
BIN("bin"),
|
||||
PAN("pan"),
|
||||
CURRENCY("currency"),
|
||||
SHOP_ID("shop_id"),
|
||||
PARTY_ID("party_id"),
|
||||
CARD_TOKEN("card_token");
|
||||
|
||||
private String value;
|
||||
private static Map<String, CheckedField> valueMap = new HashMap<>();
|
||||
private static Map<String, PaymentCheckedField> valueMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (CheckedField value : CheckedField.values()) {
|
||||
for (PaymentCheckedField value : PaymentCheckedField.values()) {
|
||||
valueMap.put(value.value, value);
|
||||
}
|
||||
}
|
||||
|
||||
CheckedField(String value) {
|
||||
PaymentCheckedField(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static CheckedField getByValue(String value) {
|
||||
public static PaymentCheckedField getByValue(String value) {
|
||||
return valueMap.get(value);
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package com.rbkmoney.fraudo.exception;
|
||||
|
||||
public class NotValidContextException extends RuntimeException {
|
||||
|
||||
private static final String ERROR_MESSAGE = "Context is not valid!";
|
||||
|
||||
public NotValidContextException() {
|
||||
super(ERROR_MESSAGE);
|
||||
}
|
||||
}
|
@ -1,29 +1,39 @@
|
||||
package com.rbkmoney.fraudo.factory;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoVisitor;
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.BaseModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.visitor.*;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.visitor.CountVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.CustomFuncVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.ListVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.SumVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.impl.*;
|
||||
|
||||
public class FastFraudVisitorFactory implements FraudVisitorFactory {
|
||||
public class FastFraudVisitorFactory<T extends BaseModel, U> implements FraudVisitorFactory<T, U> {
|
||||
|
||||
@Override
|
||||
public FraudoVisitor<Object> createVisitor(FraudModel model,
|
||||
CountAggregator countAggregator,
|
||||
SumAggregator sumAggregator,
|
||||
UniqueValueAggregator uniqueValueAggregator,
|
||||
CountryResolver countryResolver,
|
||||
InListFinder blackListFinder,
|
||||
InListFinder whiteListFinder,
|
||||
InListFinder greyListFinder) {
|
||||
CountVisitorImpl countVisitor = new CountVisitorImpl(model, countAggregator);
|
||||
SumVisitorImpl sumVisitor = new SumVisitorImpl(model, sumAggregator);
|
||||
ListVisitorImpl listVisitor = new ListVisitorImpl(model, blackListFinder, whiteListFinder, greyListFinder);
|
||||
CustomFuncVisitorImpl customFuncVisitor = new CustomFuncVisitorImpl(model, uniqueValueAggregator, countryResolver);
|
||||
return new FastFraudVisitorImpl(countVisitor, sumVisitor, listVisitor, customFuncVisitor);
|
||||
public FastFraudVisitorImpl<T> createVisitor(
|
||||
CountAggregator<T, U> countAggregator,
|
||||
SumAggregator<T, U> sumAggregator,
|
||||
UniqueValueAggregator<T, U> uniqueValueAggregator,
|
||||
CountryResolver<U> countryResolver,
|
||||
InListFinder<T, U> listFinder,
|
||||
FieldResolver<T, U> fieldResolver,
|
||||
GroupByModelResolver<T, U> groupByModelResolver) {
|
||||
CountVisitor<T> countVisitor = new CountVisitorImpl<>(countAggregator, fieldResolver, groupByModelResolver);
|
||||
SumVisitor<T> sumVisitor = new SumVisitorImpl<>(sumAggregator, fieldResolver, groupByModelResolver);
|
||||
ListVisitor<T> listVisitor = new ListVisitorImpl<>(listFinder, fieldResolver);
|
||||
CustomFuncVisitor<T> customFuncVisitor = new CustomFuncVisitorImpl<>(
|
||||
uniqueValueAggregator,
|
||||
countryResolver,
|
||||
fieldResolver,
|
||||
groupByModelResolver);
|
||||
return new FastFraudVisitorImpl<>(countVisitor, sumVisitor, listVisitor, customFuncVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package com.rbkmoney.fraudo.factory;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoVisitor;
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.visitor.impl.FastFraudVisitorImpl;
|
||||
|
||||
public interface FraudVisitorFactory {
|
||||
public interface FraudVisitorFactory<T, U> {
|
||||
|
||||
FraudoVisitor<Object> createVisitor(FraudModel model,
|
||||
CountAggregator countAggregator,
|
||||
SumAggregator sumAggregator,
|
||||
UniqueValueAggregator uniqueValueAggregator,
|
||||
CountryResolver countryResolver,
|
||||
InListFinder blackListFinder,
|
||||
InListFinder whiteListFinder,
|
||||
InListFinder greyListFinder);
|
||||
FastFraudVisitorImpl createVisitor(CountAggregator<T, U> countAggregator,
|
||||
SumAggregator<T, U> sumAggregator,
|
||||
UniqueValueAggregator<T, U> uniqueValueAggregator,
|
||||
CountryResolver<U> countryResolver,
|
||||
InListFinder<T, U> listFinder,
|
||||
FieldResolver<T, U> fieldPairResolver,
|
||||
GroupByModelResolver<T, U> groupByModelResolver);
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,18 @@
|
||||
package com.rbkmoney.fraudo.finder;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
|
||||
import com.rbkmoney.fraudo.model.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface InListFinder {
|
||||
public interface InListFinder<T, U> {
|
||||
|
||||
Boolean findInList(String partyId, String shopId, CheckedField field, String value);
|
||||
Boolean findInBlackList(List<Pair<U, String>> fields, T model);
|
||||
|
||||
Boolean findInList(String partyId, String shopId, List<CheckedField> fields, List<String> value);
|
||||
Boolean findInWhiteList(List<Pair<U, String>> fields, T model);
|
||||
|
||||
Boolean findInGreyList(List<Pair<U, String>> fields, T model);
|
||||
|
||||
Boolean findInList(String name, List<Pair<U, String>> fields, T model);
|
||||
|
||||
}
|
||||
|
14
src/main/java/com/rbkmoney/fraudo/model/BaseModel.java
Normal file
14
src/main/java/com/rbkmoney/fraudo/model/BaseModel.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.rbkmoney.fraudo.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BaseModel {
|
||||
|
||||
private String ip;
|
||||
private String email;
|
||||
private String fingerprint;
|
||||
private Long amount;
|
||||
private String currency;
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.rbkmoney.fraudo.model;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class GroupByModel {
|
||||
|
||||
private List<CheckedField> checkedFields;
|
||||
|
||||
}
|
15
src/main/java/com/rbkmoney/fraudo/model/P2PModel.java
Normal file
15
src/main/java/com/rbkmoney/fraudo/model/P2PModel.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.rbkmoney.fraudo.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class P2PModel extends BaseModel {
|
||||
|
||||
private String bin;
|
||||
private String pan;
|
||||
private String country;
|
||||
private String cardTokenFrom;
|
||||
private String cardTokenTo;
|
||||
private String identityId;
|
||||
|
||||
}
|
15
src/main/java/com/rbkmoney/fraudo/model/Pair.java
Normal file
15
src/main/java/com/rbkmoney/fraudo/model/Pair.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.rbkmoney.fraudo.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Pair<T, U> {
|
||||
|
||||
private T first;
|
||||
private U second;
|
||||
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
package com.rbkmoney.fraudo.model;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
public class FraudModel {
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PaymentModel extends BaseModel {
|
||||
|
||||
private String ip;
|
||||
private String email;
|
||||
private String bin;
|
||||
private String pan;
|
||||
private String binCountryCode;
|
||||
private String cardToken;
|
||||
private String fingerprint;
|
||||
private String shopId;
|
||||
private String partyId;
|
||||
private Long amount;
|
||||
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
package com.rbkmoney.fraudo.resolver;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
|
||||
public interface CountryResolver {
|
||||
public interface CountryResolver<T> {
|
||||
|
||||
String UNKNOWN_VALUE = "unknown";
|
||||
|
||||
String resolveCountry(CheckedField checkedField, String value);
|
||||
String resolveCountry(T checkedField, String value);
|
||||
|
||||
}
|
||||
|
@ -1,30 +1,19 @@
|
||||
package com.rbkmoney.fraudo.resolver;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.exception.UnresolvableFieldException;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
|
||||
public class FieldResolver {
|
||||
import com.rbkmoney.fraudo.model.Pair;
|
||||
|
||||
public static String resolveString(String fieldName, FraudModel fraudModel) {
|
||||
switch (CheckedField.getByValue(fieldName)) {
|
||||
case BIN:
|
||||
return fraudModel.getBin();
|
||||
case IP:
|
||||
return fraudModel.getIp();
|
||||
case FINGERPRINT:
|
||||
return fraudModel.getFingerprint();
|
||||
case EMAIL:
|
||||
return fraudModel.getEmail();
|
||||
case COUNTRY_BANK:
|
||||
return fraudModel.getBinCountryCode();
|
||||
case CARD_TOKEN:
|
||||
return fraudModel.getCardToken();
|
||||
case PAN:
|
||||
return fraudModel.getPan();
|
||||
default:
|
||||
throw new UnresolvableFieldException(fieldName);
|
||||
}
|
||||
public interface FieldResolver<T, U> {
|
||||
|
||||
String resolveValue(String fieldName, T model);
|
||||
|
||||
U resolveName(String fieldName);
|
||||
|
||||
default Pair<U, String> resolve(String fieldName, T model) {
|
||||
return new Pair<>(
|
||||
resolveName(fieldName),
|
||||
resolveValue(fieldName, model)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,26 +1,29 @@
|
||||
package com.rbkmoney.fraudo.resolver;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GroupByModelResolver {
|
||||
@RequiredArgsConstructor
|
||||
public class GroupByModelResolver<T, U> implements GroupFieldsResolver<U> {
|
||||
|
||||
public static List<CheckedField> resolve(FraudoParser.Group_byContext groupByContext) {
|
||||
List<CheckedField> checkedFields = new ArrayList<>();
|
||||
private final FieldResolver<T, U> fieldResolver;
|
||||
|
||||
public List<U> resolve(FraudoParser.Group_byContext groupByContext) {
|
||||
List<U> fields = new ArrayList<>();
|
||||
if (groupByContext != null
|
||||
&& groupByContext.string_list() != null
|
||||
&& groupByContext.string_list().STRING() != null
|
||||
&& !groupByContext.string_list().STRING().isEmpty()) {
|
||||
checkedFields = groupByContext.string_list().STRING().stream()
|
||||
.map(terminalNode -> CheckedField.getByValue(TextUtil.safeGetText(terminalNode)))
|
||||
fields = groupByContext.string_list().STRING().stream()
|
||||
.map(terminalNode -> fieldResolver.resolveName(TextUtil.safeGetText(terminalNode)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return checkedFields;
|
||||
return fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.rbkmoney.fraudo.resolver;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface GroupFieldsResolver<T> {
|
||||
|
||||
List<T> resolve(FraudoParser.Group_byContext groupByContext);
|
||||
|
||||
}
|
@ -3,10 +3,13 @@ package com.rbkmoney.fraudo.resolver;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.model.TimeWindow;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class TimeWindowResolver {
|
||||
|
||||
public static TimeWindow resolve(FraudoParser.Time_windowContext ctx) {
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.rbkmoney.fraudo.resolver.p2p;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.P2PCheckedField;
|
||||
import com.rbkmoney.fraudo.exception.UnresolvableFieldException;
|
||||
import com.rbkmoney.fraudo.model.P2PModel;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
|
||||
public class P2PModelFieldResolver implements FieldResolver<P2PModel, P2PCheckedField> {
|
||||
|
||||
@Override
|
||||
public String resolveValue(String fieldName, P2PModel model) {
|
||||
switch (P2PCheckedField.getByValue(fieldName)) {
|
||||
case BIN:
|
||||
return model.getBin();
|
||||
case IP:
|
||||
return model.getIp();
|
||||
case FINGERPRINT:
|
||||
return model.getFingerprint();
|
||||
case EMAIL:
|
||||
return model.getEmail();
|
||||
case COUNTRY_BANK:
|
||||
return model.getCountry();
|
||||
case CARD_TOKEN_FROM:
|
||||
return model.getCardTokenFrom();
|
||||
case CARD_TOKEN_TO:
|
||||
return model.getCardTokenTo();
|
||||
case PAN:
|
||||
return model.getPan();
|
||||
default:
|
||||
throw new UnresolvableFieldException(fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2PCheckedField resolveName(String fieldName) {
|
||||
return P2PCheckedField.getByValue(fieldName);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.rbkmoney.fraudo.resolver.payout;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.PaymentCheckedField;
|
||||
import com.rbkmoney.fraudo.exception.UnresolvableFieldException;
|
||||
import com.rbkmoney.fraudo.model.PaymentModel;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
|
||||
public class PaymentModelFieldResolver implements FieldResolver<PaymentModel, PaymentCheckedField> {
|
||||
|
||||
@Override
|
||||
public String resolveValue(String fieldName, PaymentModel paymentModel) {
|
||||
switch (PaymentCheckedField.getByValue(fieldName)) {
|
||||
case BIN:
|
||||
return paymentModel.getBin();
|
||||
case IP:
|
||||
return paymentModel.getIp();
|
||||
case FINGERPRINT:
|
||||
return paymentModel.getFingerprint();
|
||||
case EMAIL:
|
||||
return paymentModel.getEmail();
|
||||
case COUNTRY_BANK:
|
||||
return paymentModel.getBinCountryCode();
|
||||
case CARD_TOKEN:
|
||||
return paymentModel.getCardToken();
|
||||
case PAN:
|
||||
return paymentModel.getPan();
|
||||
default:
|
||||
throw new UnresolvableFieldException(fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentCheckedField resolveName(String fieldName) {
|
||||
return PaymentCheckedField.getByValue(fieldName);
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.rbkmoney.fraudo.utils.key.generator;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.constant.PaymentCheckedField;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -19,7 +19,7 @@ public class CommonKeyGenerator {
|
||||
return new StringBuilder()
|
||||
.append(parseTree)
|
||||
.append(countTarget)
|
||||
.append(CheckedField.getByValue(countTarget))
|
||||
.append(PaymentCheckedField.getByValue(countTarget))
|
||||
.append(timeWindowContext != null ? timeWindowContext.children : "")
|
||||
.append(groupByContext != null ? groupByContext.string_list().children : "")
|
||||
.toString();
|
||||
@ -36,7 +36,7 @@ public class CommonKeyGenerator {
|
||||
.append(parseTree)
|
||||
.append(target)
|
||||
.append(errorCode)
|
||||
.append(CheckedField.getByValue(target))
|
||||
.append(PaymentCheckedField.getByValue(target))
|
||||
.append(timeWindowContext != null ? timeWindowContext.children : "")
|
||||
.append(groupByContext != null ? groupByContext.string_list().children : "")
|
||||
.toString();
|
||||
|
13
src/main/java/com/rbkmoney/fraudo/visitor/CountVisitor.java
Normal file
13
src/main/java/com/rbkmoney/fraudo/visitor/CountVisitor.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
|
||||
public interface CountVisitor<T> {
|
||||
|
||||
Integer visitCount(FraudoParser.CountContext ctx, T model);
|
||||
|
||||
Integer visitCountSuccess(FraudoParser.Count_successContext ctx, T model);
|
||||
|
||||
Integer visitCountError(FraudoParser.Count_errorContext ctx, T model);
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoBaseVisitor;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CountVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
|
||||
private final FraudModel fraudModel;
|
||||
private final CountAggregator countAggregator;
|
||||
|
||||
@Override
|
||||
public Object visitCount(com.rbkmoney.fraudo.FraudoParser.CountContext ctx) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return (double) countAggregator.count(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCount_success(FraudoParser.Count_successContext ctx) {
|
||||
String countTarget = ctx.STRING().getText();
|
||||
return (double) countAggregator.countSuccess(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCount_error(FraudoParser.Count_errorContext ctx) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String errorCode = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return (double) countAggregator.countError(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), errorCode, GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
|
||||
public interface CustomFuncVisitor<T> {
|
||||
|
||||
String visitCountryBy(FraudoParser.Country_byContext ctx, T model);
|
||||
|
||||
boolean visitIn(FraudoParser.InContext ctx, T model);
|
||||
|
||||
boolean visitLike(FraudoParser.LikeContext ctx, T model);
|
||||
|
||||
Integer visitUnique(FraudoParser.UniqueContext ctx, T model);
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoBaseVisitor;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CustomFuncVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
|
||||
private final FraudModel fraudModel;
|
||||
private final UniqueValueAggregator uniqueValueAggregator;
|
||||
private final CountryResolver countryResolver;
|
||||
|
||||
@Override
|
||||
public Object visitCountry_by(FraudoParser.Country_byContext ctx) {
|
||||
String fieldName = TextUtil.safeGetText(ctx.STRING());
|
||||
String fieldValue = FieldResolver.resolveString(fieldName, fraudModel);
|
||||
return countryResolver.resolveCountry(CheckedField.getByValue(fieldName), fieldValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn(FraudoParser.InContext ctx) {
|
||||
final String fieldValue;
|
||||
if (ctx.STRING() != null && ctx.STRING().getText() != null && !ctx.STRING().getText().isEmpty()) {
|
||||
String field = TextUtil.safeGetText(ctx.STRING());
|
||||
fieldValue = FieldResolver.resolveString(field, fraudModel);
|
||||
} else {
|
||||
String fieldName = TextUtil.safeGetText(ctx.country_by().STRING());
|
||||
String value = FieldResolver.resolveString(fieldName, fraudModel);
|
||||
fieldValue = countryResolver.resolveCountry(CheckedField.getByValue(fieldName), value);
|
||||
}
|
||||
return ctx.string_list().STRING().stream()
|
||||
.anyMatch(s -> fieldValue.equals(TextUtil.safeGetText(s)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLike(FraudoParser.LikeContext ctx) {
|
||||
String fieldName = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String fieldValue = FieldResolver.resolveString(fieldName, fraudModel);
|
||||
String pattern = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return fieldValue.matches(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitUnique(FraudoParser.UniqueContext ctx) {
|
||||
String field = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String fieldBy = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return (double) uniqueValueAggregator.countUniqueValue(CheckedField.getByValue(field), fraudModel,
|
||||
CheckedField.getByValue(fieldBy), TimeWindowResolver.resolve(ctx.time_window()), GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAmount(FraudoParser.AmountContext ctx) {
|
||||
return (double) fraudModel.getAmount();
|
||||
}
|
||||
}
|
15
src/main/java/com/rbkmoney/fraudo/visitor/ListVisitor.java
Normal file
15
src/main/java/com/rbkmoney/fraudo/visitor/ListVisitor.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
|
||||
public interface ListVisitor<T> {
|
||||
|
||||
Boolean visitInWhiteList(FraudoParser.In_white_listContext ctx, T model);
|
||||
|
||||
Boolean visitInBlackList(FraudoParser.In_black_listContext ctx, T model);
|
||||
|
||||
Boolean visitInGreyList(FraudoParser.In_grey_listContext ctx, T model);
|
||||
|
||||
Boolean visitInList(FraudoParser.In_listContext ctx, T model);
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoBaseVisitor;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ListVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
|
||||
private final FraudModel fraudModel;
|
||||
private final InListFinder blackListFinder;
|
||||
private final InListFinder whiteListFinder;
|
||||
private final InListFinder greyListFinder;
|
||||
|
||||
@Override
|
||||
public Object visitIn_white_list(FraudoParser.In_white_listContext ctx) {
|
||||
return findInList(ctx.string_list().STRING(), whiteListFinder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_black_list(FraudoParser.In_black_listContext ctx) {
|
||||
return findInList(ctx.string_list().STRING(), blackListFinder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_grey_list(FraudoParser.In_grey_listContext ctx) {
|
||||
return findInList(ctx.string_list().STRING(), greyListFinder);
|
||||
}
|
||||
|
||||
private Object findInList(List<TerminalNode> nodes, InListFinder listFinder) {
|
||||
List<String> fields = nodes.stream()
|
||||
.map(TextUtil::safeGetText)
|
||||
.collect(Collectors.toList());
|
||||
List<String> values = fields.stream()
|
||||
.map(field -> FieldResolver.resolveString(field, fraudModel))
|
||||
.collect(Collectors.toList());
|
||||
List<CheckedField> checkedFields = fields.stream()
|
||||
.map(CheckedField::getByValue)
|
||||
.collect(Collectors.toList());
|
||||
return listFinder.findInList(fraudModel.getPartyId(), fraudModel.getShopId(),
|
||||
checkedFields, values);
|
||||
}
|
||||
}
|
13
src/main/java/com/rbkmoney/fraudo/visitor/SumVisitor.java
Normal file
13
src/main/java/com/rbkmoney/fraudo/visitor/SumVisitor.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
|
||||
public interface SumVisitor<T> {
|
||||
|
||||
Double visitSum(FraudoParser.SumContext ctx, T model);
|
||||
|
||||
Double visitSumSuccess(FraudoParser.Sum_successContext ctx, T model);
|
||||
|
||||
Double visitSumError(FraudoParser.Sum_errorContext ctx, T model);
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoBaseVisitor;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.constant.CheckedField;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SumVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
|
||||
private final FraudModel fraudModel;
|
||||
private final SumAggregator sumAggregator;
|
||||
|
||||
@Override
|
||||
public Object visitSum(FraudoParser.SumContext ctx) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return sumAggregator.sum(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSum_success(FraudoParser.Sum_successContext ctx) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return sumAggregator.sumSuccess(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSum_error(FraudoParser.Sum_errorContext ctx) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String errorCode = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return sumAggregator.sumError(CheckedField.getByValue(countTarget), fraudModel,
|
||||
TimeWindowResolver.resolve(ctx.time_window()), errorCode, GroupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.rbkmoney.fraudo.visitor.impl;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupFieldsResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import com.rbkmoney.fraudo.visitor.CountVisitor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CountVisitorImpl<T, U> implements CountVisitor<T> {
|
||||
|
||||
private final CountAggregator<T, U> countAggregator;
|
||||
private final FieldResolver<T, U> fieldResolver;
|
||||
private final GroupFieldsResolver<U> groupFieldsResolver;
|
||||
|
||||
@Override
|
||||
public Integer visitCount(com.rbkmoney.fraudo.FraudoParser.CountContext ctx, T model) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return countAggregator.count(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
groupFieldsResolver.resolve(ctx.group_by())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer visitCountSuccess(FraudoParser.Count_successContext ctx, T model) {
|
||||
String countTarget = ctx.STRING().getText();
|
||||
return countAggregator.countSuccess(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
groupFieldsResolver.resolve(ctx.group_by())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer visitCountError(FraudoParser.Count_errorContext ctx, T model) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String errorCode = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return countAggregator.countError(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
errorCode,
|
||||
groupFieldsResolver.resolve(ctx.group_by())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.rbkmoney.fraudo.visitor.impl;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.model.Pair;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import com.rbkmoney.fraudo.visitor.CustomFuncVisitor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CustomFuncVisitorImpl<T, U> implements CustomFuncVisitor<T> {
|
||||
|
||||
private final UniqueValueAggregator<T, U> uniqueValueAggregator;
|
||||
private final CountryResolver<U> countryResolver;
|
||||
private final FieldResolver<T, U> fieldResolver;
|
||||
private final GroupByModelResolver<T, U> groupByModelResolver;
|
||||
|
||||
@Override
|
||||
public String visitCountryBy(FraudoParser.Country_byContext ctx, T model) {
|
||||
String fieldName = TextUtil.safeGetText(ctx.STRING());
|
||||
Pair<U, String> resolve = fieldResolver.resolve(fieldName, model);
|
||||
return countryResolver.resolveCountry(resolve.getFirst(), resolve.getSecond());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitIn(FraudoParser.InContext ctx, T model) {
|
||||
final String fieldValue;
|
||||
if (ctx.STRING() != null && ctx.STRING().getText() != null && !ctx.STRING().getText().isEmpty()) {
|
||||
String field = TextUtil.safeGetText(ctx.STRING());
|
||||
fieldValue = fieldResolver.resolve(field, model).getSecond();
|
||||
} else {
|
||||
String fieldName = TextUtil.safeGetText(ctx.country_by().STRING());
|
||||
Pair<U, String> resolve = fieldResolver.resolve(fieldName, model);
|
||||
fieldValue = countryResolver.resolveCountry(resolve.getFirst(), resolve.getSecond());
|
||||
}
|
||||
return ctx.string_list().STRING().stream()
|
||||
.anyMatch(s -> fieldValue.equals(TextUtil.safeGetText(s)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitLike(FraudoParser.LikeContext ctx, T model) {
|
||||
String fieldName = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String fieldValue = fieldResolver.resolve(fieldName, model).getSecond();
|
||||
String pattern = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return fieldValue.matches(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer visitUnique(FraudoParser.UniqueContext ctx, T model) {
|
||||
String field = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String fieldBy = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return uniqueValueAggregator.countUniqueValue(
|
||||
fieldResolver.resolveName(field),
|
||||
model,
|
||||
fieldResolver.resolveName(fieldBy),
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
groupByModelResolver.resolve(ctx.group_by())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,22 @@
|
||||
package com.rbkmoney.fraudo.visitor;
|
||||
package com.rbkmoney.fraudo.visitor.impl;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoBaseVisitor;
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.exception.NotImplementedOperatorException;
|
||||
import com.rbkmoney.fraudo.exception.NotValidContextException;
|
||||
import com.rbkmoney.fraudo.exception.UnknownResultException;
|
||||
import com.rbkmoney.fraudo.model.BaseModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import com.rbkmoney.fraudo.utils.key.generator.*;
|
||||
import com.rbkmoney.fraudo.visitor.CountVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.CustomFuncVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.ListVisitor;
|
||||
import com.rbkmoney.fraudo.visitor.SumVisitor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -18,14 +25,31 @@ import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class FastFraudVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
public class FastFraudVisitorImpl<T extends BaseModel> extends FraudoBaseVisitor<Object> {
|
||||
|
||||
private Map<String, Object> localFuncCache = new HashMap<>();
|
||||
private ThreadLocal<Map<String, Object>> localFuncCache;
|
||||
private ThreadLocal<T> threadLocalModel;
|
||||
|
||||
private final CountVisitorImpl countVisitor;
|
||||
private final SumVisitorImpl sumVisitor;
|
||||
private final ListVisitorImpl listVisitor;
|
||||
private final CustomFuncVisitorImpl customFuncVisitor;
|
||||
private final CountVisitor<T> countVisitor;
|
||||
private final SumVisitor<T> sumVisitor;
|
||||
private final ListVisitor<T> listVisitor;
|
||||
private final CustomFuncVisitor<T> customFuncVisitor;
|
||||
|
||||
public Object visit(ParseTree tree, T model) {
|
||||
if (model == null) {
|
||||
log.error("Model is not init!");
|
||||
throw new NotValidContextException();
|
||||
}
|
||||
|
||||
localFuncCache = ThreadLocal.withInitial(HashMap::new);
|
||||
threadLocalModel = ThreadLocal.withInitial(() -> model);
|
||||
|
||||
Object visit = super.visit(tree);
|
||||
|
||||
localFuncCache.remove();
|
||||
threadLocalModel.remove();
|
||||
return visit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitFraud_rule(FraudoParser.Fraud_ruleContext ctx) {
|
||||
@ -34,11 +58,11 @@ public class FastFraudVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
return ResultStatus.getByValue((String) super.visit(ctx.result()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Error when FastFraudVisitorImpl visitFraud_rule e: ", e);
|
||||
log.error("Error when FastFraudVisitorImpl visitFraud_rule e: ", e);
|
||||
if (ctx.catch_result() != null && ctx.catch_result().getText() != null) {
|
||||
return ResultStatus.getByValue(ctx.catch_result().getText());
|
||||
}
|
||||
return ResultStatus.THREE_DS;
|
||||
return ResultStatus.NOTIFY;
|
||||
}
|
||||
return ResultStatus.NORMAL;
|
||||
}
|
||||
@ -49,12 +73,12 @@ public class FastFraudVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
for (FraudoParser.Fraud_ruleContext fraudRuleContext : ctx.fraud_rule()) {
|
||||
ResultStatus result = (ResultStatus) visitFraud_rule(fraudRuleContext);
|
||||
String key = RuleKeyGenerator.generateRuleKey(fraudRuleContext);
|
||||
if (ResultStatus.NOTIFY.equals(result)) {
|
||||
notifications.add(key);
|
||||
} else if (result != null && !ResultStatus.NORMAL.equals(result)) {
|
||||
return new ResultModel(result, key, notifications);
|
||||
} else if (result == null) {
|
||||
if (result == null) {
|
||||
throw new UnknownResultException(fraudRuleContext.getText());
|
||||
} else if (result == ResultStatus.NOTIFY) {
|
||||
notifications.add(key);
|
||||
} else if (result != ResultStatus.NORMAL) {
|
||||
return new ResultModel(result, key, notifications);
|
||||
}
|
||||
}
|
||||
return new ResultModel(ResultStatus.NORMAL, notifications);
|
||||
@ -119,79 +143,113 @@ public class FastFraudVisitorImpl extends FraudoBaseVisitor<Object> {
|
||||
@Override
|
||||
public Object visitCount(FraudoParser.CountContext ctx) {
|
||||
String key = CountKeyGenerator.generate(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> countVisitor.visitCount(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> Double.valueOf(countVisitor.visitCount(ctx, threadLocalModel.get()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCount_success(FraudoParser.Count_successContext ctx) {
|
||||
String key = CountKeyGenerator.generateSuccessKey(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> countVisitor.visitCount_success(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> Double.valueOf(countVisitor.visitCountSuccess(ctx, threadLocalModel.get()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCount_error(FraudoParser.Count_errorContext ctx) {
|
||||
String key = CountKeyGenerator.generateErrorKey(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> countVisitor.visitCount_error(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> Double.valueOf(countVisitor.visitCountError(ctx, threadLocalModel.get()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSum(FraudoParser.SumContext ctx) {
|
||||
String key = SumKeyGenerator.generate(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> sumVisitor.visitSum(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> sumVisitor.visitSum(ctx, threadLocalModel.get())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSum_success(FraudoParser.Sum_successContext ctx) {
|
||||
String key = SumKeyGenerator.generateSuccessKey(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> sumVisitor.visitSum_success(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> sumVisitor.visitSumSuccess(ctx, threadLocalModel.get())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitSum_error(FraudoParser.Sum_errorContext ctx) {
|
||||
String key = SumKeyGenerator.generateErrorKey(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> sumVisitor.visitSum_error(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> sumVisitor.visitSumError(ctx, threadLocalModel.get())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCountry_by(FraudoParser.Country_byContext ctx) {
|
||||
String key = CountryKeyGenerator.generate(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> customFuncVisitor.visitCountry_by(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> customFuncVisitor.visitCountryBy(ctx, threadLocalModel.get())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn(FraudoParser.InContext ctx) {
|
||||
return customFuncVisitor.visitIn(ctx);
|
||||
return customFuncVisitor.visitIn(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLike(FraudoParser.LikeContext ctx) {
|
||||
return customFuncVisitor.visitLike(ctx);
|
||||
return customFuncVisitor.visitLike(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitUnique(FraudoParser.UniqueContext ctx) {
|
||||
String key = UniqueKeyGenerator.generate(ctx);
|
||||
return localFuncCache.computeIfAbsent(key, s -> customFuncVisitor.visitUnique(ctx));
|
||||
return localFuncCache.get().computeIfAbsent(
|
||||
key,
|
||||
s -> Double.valueOf(customFuncVisitor.visitUnique(ctx, threadLocalModel.get()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_white_list(FraudoParser.In_white_listContext ctx) {
|
||||
return listVisitor.visitIn_white_list(ctx);
|
||||
return listVisitor.visitInWhiteList(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_black_list(FraudoParser.In_black_listContext ctx) {
|
||||
return listVisitor.visitIn_black_list(ctx);
|
||||
return listVisitor.visitInBlackList(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_grey_list(FraudoParser.In_grey_listContext ctx) {
|
||||
return listVisitor.visitIn_grey_list(ctx);
|
||||
return listVisitor.visitInGreyList(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIn_list(FraudoParser.In_listContext ctx) {
|
||||
return listVisitor.visitInList(ctx, threadLocalModel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitAmount(FraudoParser.AmountContext ctx) {
|
||||
return customFuncVisitor.visitAmount(ctx);
|
||||
return Double.valueOf(threadLocalModel.get().getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitCurrency(FraudoParser.CurrencyContext ctx) {
|
||||
return threadLocalModel.get().getCurrency();
|
||||
}
|
||||
|
||||
private boolean asBoolean(FraudoParser.ExpressionContext ctx) {
|
@ -0,0 +1,57 @@
|
||||
package com.rbkmoney.fraudo.visitor.impl;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.Pair;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import com.rbkmoney.fraudo.visitor.ListVisitor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ListVisitorImpl<T, U> implements ListVisitor<T> {
|
||||
|
||||
private final InListFinder<T, U> listFinder;
|
||||
private final FieldResolver<T, U> fieldResolver;
|
||||
|
||||
@Override
|
||||
public Boolean visitInWhiteList(FraudoParser.In_white_listContext ctx, T model) {
|
||||
return findInList(ctx.string_list().STRING(), model, listFinder::findInWhiteList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitInBlackList(FraudoParser.In_black_listContext ctx, T model) {
|
||||
return findInList(ctx.string_list().STRING(), model, listFinder::findInBlackList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitInGreyList(FraudoParser.In_grey_listContext ctx, T model) {
|
||||
return findInList(ctx.string_list().STRING(), model, listFinder::findInGreyList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitInList(FraudoParser.In_listContext ctx, T model) {
|
||||
List<Pair<U, String>> checkedFields = initCheckedFields(model, ctx.string_list().STRING());
|
||||
String name = TextUtil.safeGetText(ctx.STRING());
|
||||
return listFinder.findInList(name, checkedFields, model);
|
||||
}
|
||||
|
||||
private List<Pair<U, String>> initCheckedFields(T model, List<TerminalNode> string) {
|
||||
List<String> fields = string.stream()
|
||||
.map(TextUtil::safeGetText)
|
||||
.collect(Collectors.toList());
|
||||
return fields.stream()
|
||||
.map(s -> fieldResolver.resolve(s, model))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Boolean findInList(List<TerminalNode> nodes, T model, BiPredicate<List<Pair<U, String>>, T> biPredicate) {
|
||||
List<Pair<U, String>> checkedFields = initCheckedFields(model, nodes);
|
||||
return biPredicate.test(checkedFields, model);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.rbkmoney.fraudo.visitor.impl;
|
||||
|
||||
import com.rbkmoney.fraudo.FraudoParser;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.TimeWindowResolver;
|
||||
import com.rbkmoney.fraudo.utils.TextUtil;
|
||||
import com.rbkmoney.fraudo.visitor.SumVisitor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SumVisitorImpl<T, U> implements SumVisitor<T> {
|
||||
|
||||
private final SumAggregator<T, U> sumAggregator;
|
||||
private final FieldResolver<T, U> fieldResolver;
|
||||
private final GroupByModelResolver<T, U> groupByModelResolver;
|
||||
|
||||
@Override
|
||||
public Double visitSum(FraudoParser.SumContext ctx, T model) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return sumAggregator.sum(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
groupByModelResolver.resolve(ctx.group_by())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double visitSumSuccess(FraudoParser.Sum_successContext ctx, T model) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING());
|
||||
return sumAggregator.sumSuccess(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
groupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double visitSumError(FraudoParser.Sum_errorContext ctx, T model) {
|
||||
String countTarget = TextUtil.safeGetText(ctx.STRING(0));
|
||||
String errorCode = TextUtil.safeGetText(ctx.STRING(1));
|
||||
return sumAggregator.sumError(
|
||||
fieldResolver.resolveName(countTarget),
|
||||
model,
|
||||
TimeWindowResolver.resolve(ctx.time_window()),
|
||||
errorCode,
|
||||
groupByModelResolver.resolve(ctx.group_by()));
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.factory.FastFraudVisitorFactory;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AbstractFraudoTest {
|
||||
|
||||
public static final String TEST_GMAIL_RU = "test@gmail.ru";
|
||||
|
||||
@Mock
|
||||
CountAggregator countAggregator;
|
||||
@Mock
|
||||
SumAggregator sumAggregator;
|
||||
@Mock
|
||||
UniqueValueAggregator uniqueValueAggregator;
|
||||
@Mock
|
||||
CountryResolver countryResolver;
|
||||
@Mock
|
||||
InListFinder whiteListFinder;
|
||||
@Mock
|
||||
InListFinder blackListFinder;
|
||||
@Mock
|
||||
InListFinder greyListFinder;
|
||||
|
||||
protected ResultModel parseAndVisit(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parse = getParseContext(resourceAsStream);
|
||||
return invokeParse(parse);
|
||||
}
|
||||
|
||||
protected ResultModel invokeParse(com.rbkmoney.fraudo.FraudoParser.ParseContext parse) {
|
||||
FraudModel model = new FraudModel();
|
||||
return invoke(parse, model);
|
||||
}
|
||||
|
||||
protected ResultModel invoke(com.rbkmoney.fraudo.FraudoParser.ParseContext parse, FraudModel model) {
|
||||
return (ResultModel) new FastFraudVisitorFactory()
|
||||
.createVisitor(model, countAggregator, sumAggregator, uniqueValueAggregator, countryResolver,
|
||||
blackListFinder, whiteListFinder, greyListFinder)
|
||||
.visit(parse);
|
||||
}
|
||||
|
||||
protected com.rbkmoney.fraudo.FraudoParser.ParseContext getParseContext(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoLexer lexer = new com.rbkmoney.fraudo.FraudoLexer(new ANTLRInputStream(resourceAsStream));
|
||||
com.rbkmoney.fraudo.FraudoParser parser = new com.rbkmoney.fraudo.FraudoParser(new CommonTokenStream(lexer));
|
||||
|
||||
return parser.parse();
|
||||
}
|
||||
|
||||
}
|
68
src/test/java/com/rbkmoney/fraudo/AbstractP2PTest.java
Normal file
68
src/test/java/com/rbkmoney/fraudo/AbstractP2PTest.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.constant.P2PCheckedField;
|
||||
import com.rbkmoney.fraudo.factory.FastFraudVisitorFactory;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.P2PModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.p2p.P2PModelFieldResolver;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AbstractP2PTest {
|
||||
|
||||
@Mock
|
||||
CountAggregator<P2PModel, P2PCheckedField> countAggregator;
|
||||
@Mock
|
||||
SumAggregator<P2PModel, P2PCheckedField> sumAggregator;
|
||||
@Mock
|
||||
UniqueValueAggregator<P2PModel, P2PCheckedField> uniqueValueAggregator;
|
||||
@Mock
|
||||
CountryResolver<P2PCheckedField> countryResolver;
|
||||
@Mock
|
||||
InListFinder<P2PModel, P2PCheckedField> listFinder;
|
||||
|
||||
private P2PModelFieldResolver fieldResolver = new P2PModelFieldResolver();
|
||||
private GroupByModelResolver<P2PModel, P2PCheckedField> groupByModelResolver = new GroupByModelResolver<>(fieldResolver);
|
||||
|
||||
|
||||
ResultModel parseAndVisit(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parse = getParseContext(resourceAsStream);
|
||||
return invokeParse(parse);
|
||||
}
|
||||
|
||||
ResultModel invokeParse(com.rbkmoney.fraudo.FraudoParser.ParseContext parse) {
|
||||
P2PModel model = new P2PModel();
|
||||
return invoke(parse, model);
|
||||
}
|
||||
|
||||
ResultModel invoke(com.rbkmoney.fraudo.FraudoParser.ParseContext parse, P2PModel model) {
|
||||
return (ResultModel) new FastFraudVisitorFactory<P2PModel, P2PCheckedField>()
|
||||
.createVisitor(
|
||||
countAggregator,
|
||||
sumAggregator,
|
||||
uniqueValueAggregator,
|
||||
countryResolver,
|
||||
listFinder,
|
||||
fieldResolver,
|
||||
groupByModelResolver)
|
||||
.visit(parse, model);
|
||||
}
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext getParseContext(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoLexer lexer = new com.rbkmoney.fraudo.FraudoLexer(new ANTLRInputStream(resourceAsStream));
|
||||
com.rbkmoney.fraudo.FraudoParser parser = new com.rbkmoney.fraudo.FraudoParser(new CommonTokenStream(lexer));
|
||||
|
||||
return parser.parse();
|
||||
}
|
||||
|
||||
}
|
68
src/test/java/com/rbkmoney/fraudo/AbstractPaymentTest.java
Normal file
68
src/test/java/com/rbkmoney/fraudo/AbstractPaymentTest.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.aggregator.CountAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.SumAggregator;
|
||||
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
|
||||
import com.rbkmoney.fraudo.constant.PaymentCheckedField;
|
||||
import com.rbkmoney.fraudo.factory.FastFraudVisitorFactory;
|
||||
import com.rbkmoney.fraudo.finder.InListFinder;
|
||||
import com.rbkmoney.fraudo.model.PaymentModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import com.rbkmoney.fraudo.resolver.CountryResolver;
|
||||
import com.rbkmoney.fraudo.resolver.FieldResolver;
|
||||
import com.rbkmoney.fraudo.resolver.GroupByModelResolver;
|
||||
import com.rbkmoney.fraudo.resolver.payout.PaymentModelFieldResolver;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AbstractPaymentTest {
|
||||
|
||||
@Mock
|
||||
CountAggregator<PaymentModel, PaymentCheckedField> countAggregator;
|
||||
@Mock
|
||||
SumAggregator<PaymentModel, PaymentCheckedField> sumAggregator;
|
||||
@Mock
|
||||
UniqueValueAggregator<PaymentModel, PaymentCheckedField> uniqueValueAggregator;
|
||||
@Mock
|
||||
CountryResolver<PaymentCheckedField> countryResolver;
|
||||
@Mock
|
||||
InListFinder<PaymentModel, PaymentCheckedField> inListFinder;
|
||||
|
||||
private FieldResolver<PaymentModel, PaymentCheckedField> fieldResolver = new PaymentModelFieldResolver();
|
||||
private GroupByModelResolver<PaymentModel, PaymentCheckedField> groupByModelResolver = new GroupByModelResolver<>(fieldResolver);
|
||||
|
||||
ResultModel parseAndVisit(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parse = getParseContext(resourceAsStream);
|
||||
return invokeParse(parse);
|
||||
}
|
||||
|
||||
ResultModel invokeParse(com.rbkmoney.fraudo.FraudoParser.ParseContext parse) {
|
||||
PaymentModel model = new PaymentModel();
|
||||
return invoke(parse, model);
|
||||
}
|
||||
|
||||
ResultModel invoke(com.rbkmoney.fraudo.FraudoParser.ParseContext parse, PaymentModel model) {
|
||||
return (ResultModel) new FastFraudVisitorFactory<PaymentModel, PaymentCheckedField>()
|
||||
.createVisitor(
|
||||
countAggregator,
|
||||
sumAggregator,
|
||||
uniqueValueAggregator,
|
||||
countryResolver,
|
||||
inListFinder,
|
||||
fieldResolver,
|
||||
groupByModelResolver)
|
||||
.visit(parse, model);
|
||||
}
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext getParseContext(InputStream resourceAsStream) throws IOException {
|
||||
com.rbkmoney.fraudo.FraudoLexer lexer = new com.rbkmoney.fraudo.FraudoLexer(new ANTLRInputStream(resourceAsStream));
|
||||
com.rbkmoney.fraudo.FraudoParser parser = new com.rbkmoney.fraudo.FraudoParser(new CommonTokenStream(lexer));
|
||||
|
||||
return parser.parse();
|
||||
}
|
||||
|
||||
}
|
@ -2,10 +2,8 @@ package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.InputStream;
|
||||
@ -14,7 +12,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class CountTest extends AbstractFraudoTest {
|
||||
public class CountTest extends AbstractPaymentTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
@ -2,7 +2,7 @@ package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.exception.UnknownResultException;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.PaymentModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class CustomTest extends AbstractFraudoTest {
|
||||
public class CustomTest extends AbstractPaymentTest {
|
||||
|
||||
public static final String TEST_GMAIL_RU = "test@gmail.ru";
|
||||
|
||||
@ -79,7 +79,7 @@ public class CustomTest extends AbstractFraudoTest {
|
||||
public void inTest() throws Exception {
|
||||
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/in.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setEmail(TEST_GMAIL_RU);
|
||||
ResultModel result = invoke(parseContext, model);
|
||||
assertEquals(ResultStatus.ACCEPT, result.getResultStatus());
|
||||
@ -91,7 +91,7 @@ public class CustomTest extends AbstractFraudoTest {
|
||||
when(countryResolver.resolveCountry(any(), anyString())).thenReturn("RU");
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
ResultModel result = invoke(parseContext, model);
|
||||
assertEquals(ResultStatus.ACCEPT, result.getResultStatus());
|
||||
}
|
||||
@ -100,10 +100,15 @@ public class CustomTest extends AbstractFraudoTest {
|
||||
public void amountTest() throws Exception {
|
||||
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/amount.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setAmount(56L);
|
||||
model.setCurrency("RUB");
|
||||
ResultModel result = invoke(parseContext, model);
|
||||
assertEquals(ResultStatus.ACCEPT, result.getResultStatus());
|
||||
|
||||
model.setCurrency("USD");
|
||||
result = invoke(parseContext, model);
|
||||
assertEquals(ResultStatus.NORMAL, result.getResultStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -119,7 +124,7 @@ public class CustomTest extends AbstractFraudoTest {
|
||||
public void likeTest() throws Exception {
|
||||
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/like.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setEmail(TEST_GMAIL_RU);
|
||||
model.setBin("553619");
|
||||
model.setPan("9137");
|
||||
@ -135,7 +140,7 @@ public class CustomTest extends AbstractFraudoTest {
|
||||
public void inNotTest() throws Exception {
|
||||
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/in_not.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setEmail(TEST_GMAIL_RU);
|
||||
ResultModel result = invoke(parseContext, model);
|
||||
assertEquals(ResultStatus.NORMAL, result.getResultStatus());
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.exception.UnknownResultException;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
@ -14,7 +12,7 @@ import java.io.InputStream;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
|
||||
public class ListTest extends AbstractFraudoTest {
|
||||
public class ListTest extends AbstractPaymentTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@ -25,13 +23,13 @@ public class ListTest extends AbstractFraudoTest {
|
||||
public void whiteBlackListTest() throws Exception {
|
||||
InputStream resourceAsStream = ListTest.class.getResourceAsStream("/rules/whitelist.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
Mockito.when(whiteListFinder.findInList(anyString(), anyString(), anyList(), anyList())).thenReturn(true);
|
||||
Mockito.when(inListFinder.findInWhiteList(anyList(), anyObject())).thenReturn(true);
|
||||
ResultModel result = invokeParse(parseContext);
|
||||
Assert.assertEquals(ResultStatus.DECLINE, result.getResultStatus());
|
||||
|
||||
resourceAsStream = ListTest.class.getResourceAsStream("/rules/blacklist.frd");
|
||||
parseContext = getParseContext(resourceAsStream);
|
||||
Mockito.when(blackListFinder.findInList(anyString(), anyString(), anyList(), anyList())).thenReturn(true);
|
||||
Mockito.when(inListFinder.findInBlackList(anyList(), anyObject())).thenReturn(true);
|
||||
result = invokeParse(parseContext);
|
||||
Assert.assertEquals(ResultStatus.NORMAL, result.getResultStatus());
|
||||
Assert.assertEquals(1, result.getNotificationsRule().size());
|
||||
@ -41,7 +39,16 @@ public class ListTest extends AbstractFraudoTest {
|
||||
public void greyListTest() throws Exception {
|
||||
InputStream resourceAsStream = ListTest.class.getResourceAsStream("/rules/greyList.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
Mockito.when(greyListFinder.findInList(anyString(), anyString(), anyList(), anyList())).thenReturn(true);
|
||||
Mockito.when(inListFinder.findInGreyList(anyList(), anyObject())).thenReturn(true);
|
||||
ResultModel result = invokeParse(parseContext);
|
||||
Assert.assertEquals(ResultStatus.ACCEPT, result.getResultStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namingListTest() throws Exception {
|
||||
InputStream resourceAsStream = ListTest.class.getResourceAsStream("/rules/namingList.frd");
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
Mockito.when(inListFinder.findInList(anyString(), anyList(), anyObject())).thenReturn(true);
|
||||
ResultModel result = invokeParse(parseContext);
|
||||
Assert.assertEquals(ResultStatus.ACCEPT, result.getResultStatus());
|
||||
}
|
||||
|
101
src/test/java/com/rbkmoney/fraudo/P2PTest.java
Normal file
101
src/test/java/com/rbkmoney/fraudo/P2PTest.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.model.P2PModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class P2PTest extends AbstractP2PTest {
|
||||
|
||||
public static final long TIME_CALL_AGGR_FUNC = 200L;
|
||||
public static final long MILLISTIME_FAST_FUNC = 10L;
|
||||
public static final long TIME_CALLING = 200L;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timingTest() throws Exception {
|
||||
InputStream resourceAsStream = P2PTest.class.getResourceAsStream("/rules/p2p_template.frd");
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
mockAggr(countDownLatch);
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
|
||||
P2PModel model = new P2PModel();
|
||||
model.setAmount(MILLISTIME_FAST_FUNC);
|
||||
model.setBin("444443");
|
||||
model.setCardTokenFrom("13213");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
ResultModel result = invoke(parseContext, model);
|
||||
long executionTime = System.currentTimeMillis() - start;
|
||||
assertEquals(ResultStatus.NORMAL, result.getResultStatus());
|
||||
assertEquals(0, countDownLatch.getCount());
|
||||
assertTrue(executionTime < TIME_CALL_AGGR_FUNC + 1 + TIME_CALLING);
|
||||
|
||||
System.out.println("executionTime=" + executionTime);
|
||||
}
|
||||
|
||||
private void mockAggr(CountDownLatch countDownLatch) {
|
||||
when(countAggregator.count(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Integer>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
when(countAggregator.countSuccess(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Integer>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
|
||||
when(sumAggregator.sum(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
});
|
||||
when(sumAggregator.sumSuccess(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
});
|
||||
|
||||
when(listFinder.findInBlackList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(listFinder.findInWhiteList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(listFinder.findInGreyList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(listFinder.findInList(anyString(), anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(countryResolver.resolveCountry(anyObject(), anyString()))
|
||||
.thenAnswer((Answer<String>) invocationOnMock -> "RUS");
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.PaymentModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -16,7 +16,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class RealTimerTest extends AbstractFraudoTest {
|
||||
public class RealTimerTest extends AbstractPaymentTest {
|
||||
|
||||
public static final long TIME_CALL_AGGR_FUNC = 200L;
|
||||
public static final long MILLISTIME_FAST_FUNC = 10L;
|
||||
@ -29,13 +29,13 @@ public class RealTimerTest extends AbstractFraudoTest {
|
||||
|
||||
@Test
|
||||
public void timingTest() throws Exception {
|
||||
InputStream resourceAsStream = RealTimerTest.class.getResourceAsStream("/rules/real_template.frd");
|
||||
InputStream resourceAsStream = RealTimerTest.class.getResourceAsStream("/rules/payment_template.frd");
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
mockAggr(countDownLatch);
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setAmount(MILLISTIME_FAST_FUNC);
|
||||
model.setBin("444443");
|
||||
|
||||
@ -57,7 +57,7 @@ public class RealTimerTest extends AbstractFraudoTest {
|
||||
|
||||
com.rbkmoney.fraudo.FraudoParser.ParseContext parseContext = getParseContext(resourceAsStream);
|
||||
|
||||
FraudModel model = new FraudModel();
|
||||
PaymentModel model = new PaymentModel();
|
||||
model.setAmount(MILLISTIME_FAST_FUNC);
|
||||
model.setBin("444443");
|
||||
|
||||
@ -79,71 +79,40 @@ public class RealTimerTest extends AbstractFraudoTest {
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
when(countAggregator.count(any(), any(), any()))
|
||||
.thenAnswer((Answer<Integer>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
when(countAggregator.countSuccess(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Integer>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
when(countAggregator.countSuccess(any(), any(), any()))
|
||||
.thenAnswer((Answer<Integer>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
countDownLatch.countDown();
|
||||
return 1;
|
||||
});
|
||||
|
||||
when(sumAggregator.sum(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
});
|
||||
when(sumAggregator.sum(any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
});
|
||||
when(sumAggregator.sumSuccess(any(), any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
});
|
||||
when(sumAggregator.sumSuccess(any(), any(), any()))
|
||||
.thenAnswer((Answer<Double>) invocationOnMock -> {
|
||||
Thread.sleep(TIME_CALL_AGGR_FUNC);
|
||||
return 10000.0;
|
||||
|
||||
when(inListFinder.findInWhiteList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(inListFinder.findInGreyList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(inListFinder.findInBlackList(anyList(), anyObject()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
|
||||
when(whiteListFinder.findInList(anyString(), anyString(), anyList(), anyList()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(greyListFinder.findInList(anyString(), anyString(), anyList(), anyList()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(greyListFinder.findInList(anyString(), anyString(), anyObject(), anyString()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(blackListFinder.findInList(anyString(), anyString(), anyObject(), anyString()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(blackListFinder.findInList(anyString(), anyString(), anyList(), anyList()))
|
||||
.thenAnswer((Answer<Boolean>) invocationOnMock -> {
|
||||
Thread.sleep(MILLISTIME_FAST_FUNC);
|
||||
return false;
|
||||
});
|
||||
when(countryResolver.resolveCountry(anyObject(), anyString()))
|
||||
.thenAnswer((Answer<String>) invocationOnMock -> "RUS");
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.rbkmoney.fraudo;
|
||||
|
||||
import com.rbkmoney.fraudo.constant.ResultStatus;
|
||||
import com.rbkmoney.fraudo.exception.UnknownResultException;
|
||||
import com.rbkmoney.fraudo.model.FraudModel;
|
||||
import com.rbkmoney.fraudo.model.ResultModel;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
@ -14,7 +12,7 @@ import java.io.InputStream;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
|
||||
public class SumTest extends AbstractFraudoTest {
|
||||
public class SumTest extends AbstractPaymentTest {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
10
src/test/resources/logback-test.xml
Executable file
10
src/test/resources/logback-test.xml
Executable 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" level="ALL"/>
|
||||
</configuration>
|
@ -1,2 +1,2 @@
|
||||
rule: amount() < 100
|
||||
rule: amount() < 100 AND currency() == "RUB"
|
||||
-> accept;
|
2
src/test/resources/rules/namingList.frd
Normal file
2
src/test/resources/rules/namingList.frd
Normal file
@ -0,0 +1,2 @@
|
||||
rule: inList("test", "email")
|
||||
-> accept;
|
12
src/test/resources/rules/p2p_template.frd
Normal file
12
src/test/resources/rules/p2p_template.frd
Normal file
@ -0,0 +1,12 @@
|
||||
rule:amount_limit70k:amount()>5000->decline;
|
||||
rule:grey:inGreyList("card_token_from","email")->accept;
|
||||
rule:white:inWhiteList("email","fingerprint","card_token_from","bin","ip")->accept;
|
||||
rule:black:inBlackList("email","fingerprint","card_token_from","bin","ip")->decline;
|
||||
rule:tur_bk:in("bin","444444") AND amount()<77000 ->accept;
|
||||
rule:tur_bin2:in("bin","444444") AND count("card_token_from",1440,"party_id")<12->accept;
|
||||
rule:bad_countries:in(countryBy("country_bank"),"AUS")->decline;
|
||||
rule:amount_country801R:amount()>8100 AND in(countryBy("country_bank"),"HND")->decline;
|
||||
rule:amount_country2100R:amount()>12000 AND in(countryBy("country_bank"),"RUS")->decline;
|
||||
rule:amount_country3500R:amount()>31000 AND in(countryBy("country_bank"),"PER","BRA")->decline;
|
||||
rule:tur_low:count("card_token_from",1440,"party_id")<21 AND amount()<33000 AND in(countryBy("country_bank"),"UZB")->accept;
|
||||
rule:cards_test_count_3:unique("fingerprint","card_token_from",1440)>3 AND not in(countryBy("country_bank"),"UZB")->decline;
|
Loading…
Reference in New Issue
Block a user