diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2cb3849a..c0915544 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,4 +7,4 @@ on:
jobs:
build:
- uses: valitydev/java-workflow/.github/workflows/maven-service-build.yml@v1
+ uses: valitydev/java-workflow/.github/workflows/maven-service-build.yml@v3
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index d5fa3bc8..ce19205a 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -12,7 +12,7 @@ env:
jobs:
deploy:
- uses: valitydev/java-workflow/.github/workflows/maven-service-deploy.yml@v1
+ uses: valitydev/java-workflow/.github/workflows/maven-service-deploy.yml@v3
secrets:
github-token: ${{ secrets.GITHUB_TOKEN }}
mm-webhook-url: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
diff --git a/.gitignore b/.gitignore
index fb08ff78..2fe58507 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@ buildNumber.properties
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
+.vscode/
# Sensitive or high-churn files:
.idea/dataSources.ids
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..ffd50ab9
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "anapi-v2",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/pom.xml b/pom.xml
index 46cfb4ae..46f4e220 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,11 +6,11 @@
dev.vality
service-parent-pom
- 1.0.19
+ 3.1.1
anapi-v2
- 1.0.4
+ 2.0.0
jar
anapi-v2
@@ -19,18 +19,12 @@
UTF-8
UTF-8
- 15
+ 21
8022
8023
${server.port} ${management.port}
${env.REGISTRY}
- 2.10.5
- 2.5
- 2.12.5
- 2.5.3
- 1.3.2
- 2.3.1
- 1.0.4
+ 0.12.6
@@ -38,33 +32,23 @@
dev.vality
- swag-anapi-v2
- 1.81-8f1ba21-server
+ swag-anapi-v2-server
+ 1.101-adc5097
dev.vality
bouncer-proto
- 1.51-23d1761
+ 1.57-31866c3
dev.vality
org-management-proto
- 1.12-1a0110a
-
-
- dev.vality
- payout-manager-proto
- 1.38-635dc24
+ 1.17-04de2f4
dev.vality
magista-proto
- 1.44-5352f74
-
-
- dev.vality
- party-shop-proto
- 1.19-72faaf6
+ 1.55-bbdee33
dev.vality
@@ -83,19 +67,25 @@
dev.vality
damsel
- 1.614-3df747f
-
-
- dev.vality
- token-keeper-proto
- 1.32-8b8bb43
+
+ org.springframework.boot
+ spring-boot-starter-security
+
org.springframework.boot
spring-boot-starter-aop
+
+ org.springframework.security
+ spring-security-config
+
+
+ org.springframework.security
+ spring-security-web
+
org.springframework.boot
spring-boot-starter
@@ -123,27 +113,15 @@
spring-boot-configuration-processor
true
-
-
-
- javax.servlet
- javax.servlet-api
-
-
- io.swagger
- swagger-annotations
- 1.6.12
- provided
-
- io.springfox
- springfox-swagger2
- ${springfox-version}
+ org.springframework.boot
+ spring-boot-starter-oauth2-resource-server
+
+
- io.springfox
- springfox-swagger-ui
- ${springfox-version}
+ jakarta.servlet
+ jakarta.servlet-api
org.projectlombok
@@ -151,31 +129,8 @@
provided
- javax.servlet
- servlet-api
- ${servlet-api-version}
- provided
-
-
- javax.annotation
- javax.annotation-api
- ${javax-annotation-api-version}
-
-
- javax.validation
- validation-api
- 2.0.1.Final
- provided
-
-
- javax.xml.bind
- jaxb-api
- ${jaxb-version}
-
-
- com.google.code.findbugs
- jsr305
- 3.0.2
+ jakarta.validation
+ jakarta.validation-api
provided
@@ -184,11 +139,6 @@
0.2.6
provided
-
- org.bouncycastle
- bcprov-jdk15on
- 1.70
-
io.micrometer
micrometer-core
@@ -206,20 +156,32 @@
io.jsonwebtoken
- jjwt
- 0.9.1
+ jjwt-api
+ ${jjwt-version}
+ test
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ ${jjwt-version}
test
- com.github.tomakehurst
- wiremock-jre8-standalone
- 2.35.1
+ io.jsonwebtoken
+ jjwt-jackson
+ ${jjwt-version}
test
org.springframework.cloud
spring-cloud-contract-wiremock
- 3.1.4
+ 4.3.0
+ test
+
+
+ org.bouncycastle
+ bcpkix-jdk18on
+ 1.79
test
@@ -256,12 +218,12 @@
org.apache.maven.plugins
maven-remote-resources-plugin
- 3.1.0
+ 3.3.0
org.apache.maven.shared
maven-filtering
- 3.3.1
+ 3.4.0
diff --git a/src/main/java/dev/vality/anapi/v2/api/AnalyticsApiDelegateService.java b/src/main/java/dev/vality/anapi/v2/api/AnalyticsApiDelegateService.java
index d9bf539f..17c76788 100644
--- a/src/main/java/dev/vality/anapi/v2/api/AnalyticsApiDelegateService.java
+++ b/src/main/java/dev/vality/anapi/v2/api/AnalyticsApiDelegateService.java
@@ -5,11 +5,8 @@
import dev.vality.anapi.v2.security.AccessService;
import dev.vality.anapi.v2.service.AnalyticsService;
import dev.vality.anapi.v2.util.DeadlineUtil;
-import dev.vality.damsel.analytics.FilterRequest;
-import dev.vality.damsel.analytics.MerchantFilter;
-import dev.vality.damsel.analytics.SplitFilterRequest;
+import dev.vality.damsel.analytics.*;
import dev.vality.damsel.analytics.SplitUnit;
-import dev.vality.damsel.analytics.TimeFilter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
@@ -29,7 +26,7 @@ public class AnalyticsApiDelegateService implements AnalyticsApiDelegate {
private final AnalyticsService analyticsService;
@Override
- public ResponseEntity getAveragePayment(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getAveragePayment(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -38,9 +35,9 @@ public ResponseEntity getAveragePayment(String xRequestID, St
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse200 response;
+ GetPaymentsAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse200();
+ response = new GetPaymentsAmount200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getAveragePayment(filterRequest);
@@ -50,7 +47,7 @@ public ResponseEntity getAveragePayment(String xRequestID, St
}
@Override
- public ResponseEntity getCreditingsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getCreditingsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -59,9 +56,9 @@ public ResponseEntity getCreditingsAmount(String xRequestID,
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse200 response;
+ GetPaymentsAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse200();
+ response = new GetPaymentsAmount200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getCreditingsAmount(filterRequest);
@@ -71,7 +68,7 @@ public ResponseEntity getCreditingsAmount(String xRequestID,
}
@Override
- public ResponseEntity getCurrentBalances(String xRequestID, String partyID, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getCurrentBalances(String xRequestID, String partyID, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -80,9 +77,9 @@ public ResponseEntity getCurrentBalances(String xRequestID, S
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse200 response;
+ GetPaymentsAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse200();
+ response = new GetPaymentsAmount200Response();
} else {
var merchantFilter = getMerchantFilter(partyID, shopIDs, excludeShopIDs);
response = analyticsService.getCurrentBalances(merchantFilter);
@@ -92,7 +89,7 @@ public ResponseEntity getCurrentBalances(String xRequestID, S
}
@Override
- public ResponseEntity getCurrentShopBalances(String xRequestID, String partyID, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getCurrentShopBalances(String xRequestID, String partyID, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -101,9 +98,9 @@ public ResponseEntity getCurrentShopBalances(String xRequest
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2007 response;
+ GetCurrentShopBalances200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2007();
+ response = new GetCurrentShopBalances200Response();
} else {
var merchantFilter = getMerchantFilter(partyID, shopIDs, excludeShopIDs);
response = analyticsService.getCurrentShopBalances(merchantFilter);
@@ -113,7 +110,7 @@ public ResponseEntity getCurrentShopBalances(String xRequest
}
@Override
- public ResponseEntity getPaymentsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -122,9 +119,9 @@ public ResponseEntity getPaymentsAmount(String xRequestID, St
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse200 response;
+ GetPaymentsAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse200();
+ response = new GetPaymentsAmount200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getPaymentsAmount(filterRequest);
@@ -134,7 +131,7 @@ public ResponseEntity getPaymentsAmount(String xRequestID, St
}
@Override
- public ResponseEntity getPaymentsCount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsCount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -143,9 +140,9 @@ public ResponseEntity getPaymentsCount(String xRequestID, St
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2001 response;
+ GetPaymentsCount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2001();
+ response = new GetPaymentsCount200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getPaymentsCount(filterRequest);
@@ -155,7 +152,7 @@ public ResponseEntity getPaymentsCount(String xRequestID, St
}
@Override
- public ResponseEntity getPaymentsErrorDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsErrorDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -164,9 +161,9 @@ public ResponseEntity getPaymentsErrorDistribution(String xR
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2002 response;
+ GetPaymentsErrorDistribution200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2002();
+ response = new GetPaymentsErrorDistribution200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getPaymentsErrorDistribution(filterRequest);
@@ -176,7 +173,7 @@ public ResponseEntity getPaymentsErrorDistribution(String xR
}
@Override
- public ResponseEntity getPaymentsSplitAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String splitUnit, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsSplitAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String splitUnit, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -185,9 +182,9 @@ public ResponseEntity getPaymentsSplitAmount(String xRequest
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2003 response;
+ GetPaymentsSplitAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2003();
+ response = new GetPaymentsSplitAmount200Response();
} else {
var splitFilterRequest = getSplitFilterRequest(
partyID,
@@ -202,7 +199,7 @@ public ResponseEntity getPaymentsSplitAmount(String xRequest
}
@Override
- public ResponseEntity getPaymentsSplitCount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String splitUnit, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsSplitCount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String splitUnit, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -211,9 +208,9 @@ public ResponseEntity getPaymentsSplitCount(String xRequestI
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2004 response;
+ GetPaymentsSplitCount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2004();
+ response = new GetPaymentsSplitCount200Response();
} else {
var splitFilterRequest = getSplitFilterRequest(
partyID,
@@ -228,7 +225,7 @@ public ResponseEntity getPaymentsSplitCount(String xRequestI
}
@Override
- public ResponseEntity getPaymentsSubErrorDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsSubErrorDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -237,9 +234,9 @@ public ResponseEntity getPaymentsSubErrorDistribution(String
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2005 response;
+ GetPaymentsSubErrorDistribution200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2005();
+ response = new GetPaymentsSubErrorDistribution200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getPaymentsSubErrorDistribution(filterRequest);
@@ -249,7 +246,7 @@ public ResponseEntity getPaymentsSubErrorDistribution(String
}
@Override
- public ResponseEntity getPaymentsToolDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getPaymentsToolDistribution(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -258,9 +255,9 @@ public ResponseEntity getPaymentsToolDistribution(String xRe
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2006 response;
+ GetPaymentsToolDistribution200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2006();
+ response = new GetPaymentsToolDistribution200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getPaymentsToolDistribution(filterRequest);
@@ -270,7 +267,7 @@ public ResponseEntity getPaymentsToolDistribution(String xRe
}
@Override
- public ResponseEntity getRefundsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
+ public ResponseEntity getRefundsAmount(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, String xRequestDeadline, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -279,9 +276,9 @@ public ResponseEntity getRefundsAmount(String xRequestID, Str
.shopIds(shopIDs)
.realm(paymentInstitutionRealm)
.build());
- InlineResponse200 response;
+ GetPaymentsAmount200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse200();
+ response = new GetPaymentsAmount200Response();
} else {
var filterRequest = getFilterRequest(partyID, shopIDs, excludeShopIDs, fromTime, toTime);
response = analyticsService.getRefundsAmount(filterRequest);
diff --git a/src/main/java/dev/vality/anapi/v2/api/ReportsApiDelegateService.java b/src/main/java/dev/vality/anapi/v2/api/ReportsApiDelegateService.java
index 86553606..e889c4b6 100644
--- a/src/main/java/dev/vality/anapi/v2/api/ReportsApiDelegateService.java
+++ b/src/main/java/dev/vality/anapi/v2/api/ReportsApiDelegateService.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2.api;
import dev.vality.anapi.v2.converter.reporter.request.ParamsToStatReportRequestConverter;
-import dev.vality.anapi.v2.model.InlineResponse20014;
import dev.vality.anapi.v2.model.Report;
import dev.vality.anapi.v2.model.ReportLink;
+import dev.vality.anapi.v2.model.SearchReports200Response;
import dev.vality.anapi.v2.security.AccessData;
import dev.vality.anapi.v2.security.AccessService;
import dev.vality.anapi.v2.service.ReporterService;
-import dev.vality.geck.common.util.TypeUtil;
import dev.vality.anapi.v2.util.DeadlineUtil;
+import dev.vality.geck.common.util.TypeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -102,11 +102,12 @@ public ResponseEntity getReport(String xRequestID, String partyID, Long
}
@Override
- public ResponseEntity searchReports(String xRequestID, String partyID, OffsetDateTime fromTime,
- OffsetDateTime toTime, Integer limit,
- List reportTypes, String xRequestDeadline,
- String shopID, String paymentInstitutionRealm,
- String continuationToken) {
+ public ResponseEntity searchReports(String xRequestID, String partyID,
+ OffsetDateTime fromTime,
+ OffsetDateTime toTime, Integer limit,
+ List reportTypes, String xRequestDeadline,
+ String shopID, String paymentInstitutionRealm,
+ String continuationToken) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
List shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -115,14 +116,14 @@ public ResponseEntity searchReports(String xRequestID, Stri
.shopIds(shopID == null ? null : List.of(shopID))
.realm(paymentInstitutionRealm)
.build());
- InlineResponse20014 response;
+ SearchReports200Response response;
if (shopID == null || shopIDs.contains(shopID)) {
var request =
statReportRequestConverter.convert(partyID, shopID, fromTime, toTime, limit, reportTypes,
continuationToken);
response = reporterService.getReports(request);
} else {
- response = new InlineResponse20014();
+ response = new SearchReports200Response();
}
log.info("<- Res [200]: xRequestID={}", xRequestID);
return ResponseEntity.ok(response);
diff --git a/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegate.java b/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegate.java
index dfaba874..dde0c756 100644
--- a/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegate.java
+++ b/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegate.java
@@ -9,7 +9,6 @@ public interface SearchApiDelegate
PaymentsApiDelegate,
ChargebacksApiDelegate,
InvoicesApiDelegate,
- PayoutsApiDelegate,
RefundsApiDelegate,
InvoiceTemplatesApiDelegate {
diff --git a/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegateService.java b/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegateService.java
index be30c954..94cf339b 100644
--- a/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegateService.java
+++ b/src/main/java/dev/vality/anapi/v2/api/SearchApiDelegateService.java
@@ -27,11 +27,10 @@ public class SearchApiDelegateService implements SearchApiDelegate {
private final ParamsToPaymentSearchQueryConverter paymentSearchConverter;
private final ParamsToRefundSearchQueryConverter refundSearchConverter;
private final ParamsToChargebackSearchQueryConverter chargebackSearchConverter;
- private final ParamsToPayoutSearchQueryConverter payoutSearchConverter;
private final ParamsToInvoiceTemplateSearchQueryConverter invoiceTemplateSearchConverter;
@Override
- public ResponseEntity searchInvoices(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String invoiceStatus, Long invoiceAmountFrom, Long invoiceAmountTo, String externalID, String continuationToken) {
+ public ResponseEntity searchInvoices(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String invoiceStatus, Long invoiceAmountFrom, Long invoiceAmountTo, String externalID, String continuationToken) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -40,9 +39,9 @@ public ResponseEntity searchInvoices(String xRequestID, Stri
.shopIds(ConverterUtil.merge(shopID, shopIDs))
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2008 response;
+ SearchInvoices200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2008();
+ response = new SearchInvoices200Response();
} else {
var query = invoiceSearchConverter.convert(
partyID,
@@ -64,7 +63,7 @@ public ResponseEntity searchInvoices(String xRequestID, Stri
}
@Override
- public ResponseEntity searchPayments(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String paymentID, String paymentStatus, String paymentFlow, String paymentMethod, String paymentTerminalProvider, String payerEmail, String payerIP, String payerFingerprint, String customerID, String first6, String last4, String rrn, String approvalCode, String bankCardTokenProvider, String bankCardPaymentSystem, Long paymentAmountFrom, Long paymentAmountTo, String externalID, String continuationToken) {
+ public ResponseEntity searchPayments(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, List excludeShopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String paymentID, String paymentStatus, String paymentFlow, String paymentMethod, String paymentTerminalProvider, String payerEmail, String payerIP, String payerFingerprint, String customerID, String first6, String last4, String rrn, String approvalCode, String bankCardTokenProvider, String bankCardPaymentSystem, Long paymentAmountFrom, Long paymentAmountTo, String externalID, String continuationToken) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -73,9 +72,9 @@ public ResponseEntity searchPayments(String xRequestID, Stri
.shopIds(ConverterUtil.merge(shopID, shopIDs))
.realm(paymentInstitutionRealm)
.build());
- InlineResponse2009 response;
+ SearchPayments200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse2009();
+ response = new SearchPayments200Response();
} else {
var query = paymentSearchConverter.convert(
partyID,
@@ -111,7 +110,7 @@ public ResponseEntity searchPayments(String xRequestID, Stri
}
@Override
- public ResponseEntity searchRefunds(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String paymentID, String refundID, String refundStatus, String externalID, String continuationToken) {
+ public ResponseEntity searchRefunds(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, List invoiceIDs, String paymentID, String refundID, String refundStatus, String externalID, String continuationToken) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -120,9 +119,9 @@ public ResponseEntity searchRefunds(String xRequestID, Stri
.shopIds(ConverterUtil.merge(shopID, shopIDs))
.realm(paymentInstitutionRealm)
.build());
- InlineResponse20010 response;
+ SearchRefunds200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse20010();
+ response = new SearchRefunds200Response();
} else {
var query = refundSearchConverter.convert(
partyID,
@@ -144,7 +143,7 @@ public ResponseEntity searchRefunds(String xRequestID, Stri
}
@Override
- public ResponseEntity searchChargebacks(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, String paymentID, String chargebackID, List chargebackStatuses, List chargebackStages, List chargebackCategories, String continuationToken) {
+ public ResponseEntity searchChargebacks(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String invoiceID, String paymentID, String chargebackID, List chargebackStatuses, List chargebackStages, List chargebackCategories, String continuationToken) {
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
@@ -153,9 +152,9 @@ public ResponseEntity searchChargebacks(String xRequestID,
.shopIds(ConverterUtil.merge(shopID, shopIDs))
.realm(paymentInstitutionRealm)
.build());
- InlineResponse20011 response;
+ SearchChargebacks200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse20011();
+ response = new SearchChargebacks200Response();
} else {
var query = chargebackSearchConverter.convert(
partyID,
@@ -177,36 +176,7 @@ public ResponseEntity searchChargebacks(String xRequestID,
}
@Override
- public ResponseEntity searchPayouts(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, String shopID, List shopIDs, String paymentInstitutionRealm, String payoutID, String payoutToolType, String continuationToken) {
- DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
- shopIDs = accessService.getRestrictedShops(
- AccessData.builder()
- .operationId("SearchPayouts")
- .partyId(partyID)
- .shopIds(ConverterUtil.merge(shopID, shopIDs))
- .realm(paymentInstitutionRealm)
- .build());
- InlineResponse20012 response;
- if (shopIDs.isEmpty()) {
- response = new InlineResponse20012();
- } else {
- var query = payoutSearchConverter.convert(
- partyID,
- fromTime,
- toTime,
- limit,
- shopIDs,
- payoutID,
- payoutToolType,
- continuationToken);
- response = magistaService.searchPayouts(query);
- }
- log.info("<- Res [200]: xRequestID={}", xRequestID);
- return ResponseEntity.ok(response);
- }
-
- @Override
- public ResponseEntity searchInvoiceTemplates(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, List shopIDs, String paymentInstitutionRealm, String invoiceTemplateID, String invoiceTemplateStatus, String name, String product, OffsetDateTime invoiceValidUntil, String continuationToken) {
+ public ResponseEntity searchInvoiceTemplates(String xRequestID, String partyID, OffsetDateTime fromTime, OffsetDateTime toTime, Integer limit, String xRequestDeadline, List shopIDs, String paymentInstitutionRealm, String invoiceTemplateID, String invoiceTemplateStatus, String name, String product, OffsetDateTime invoiceValidUntil, String continuationToken) {
shopIDs = accessService.getRestrictedShops(
AccessData.builder()
.operationId("SearchInvoiceTemplates")
@@ -215,9 +185,9 @@ public ResponseEntity searchInvoiceTemplates(String xReques
.realm(paymentInstitutionRealm)
.build());
DeadlineUtil.checkDeadline(xRequestDeadline, xRequestID);
- InlineResponse20013 response;
+ SearchInvoiceTemplates200Response response;
if (shopIDs.isEmpty()) {
- response = new InlineResponse20013();
+ response = new SearchInvoiceTemplates200Response();
} else {
var query = invoiceTemplateSearchConverter.convert(
partyID,
diff --git a/src/main/java/dev/vality/anapi/v2/config/ApplicationConfig.java b/src/main/java/dev/vality/anapi/v2/config/ApplicationConfig.java
index 4f9c8b77..4b2772a9 100644
--- a/src/main/java/dev/vality/anapi/v2/config/ApplicationConfig.java
+++ b/src/main/java/dev/vality/anapi/v2/config/ApplicationConfig.java
@@ -2,11 +2,10 @@
import dev.vality.bouncer.decisions.ArbiterSrv;
import dev.vality.damsel.analytics.AnalyticsServiceSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
+import dev.vality.damsel.domain_config_v2.RepositoryClientSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
import dev.vality.reporter.ReportingSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import dev.vality.woody.api.trace.context.metadata.user.UserIdentityEmailExtensionKit;
import dev.vality.woody.api.trace.context.metadata.user.UserIdentityIdExtensionKit;
import dev.vality.woody.api.trace.context.metadata.user.UserIdentityRealmExtensionKit;
@@ -44,13 +43,13 @@ public AnalyticsServiceSrv.Iface analyticsClient(
}
@Bean
- public VortigonServiceSrv.Iface vortigonClient(
- @Value("${service.vortigon.url}") Resource resource,
- @Value("${service.vortigon.networkTimeout}") int networkTimeout) throws IOException {
+ public RepositoryClientSrv.Iface dominantClient(
+ @Value("${service.dominant.url}") Resource resource,
+ @Value("${service.dominant.networkTimeout}") int networkTimeout) throws IOException {
return new THSpawnClientBuilder()
.withNetworkTimeout(networkTimeout)
.withAddress(resource.getURI())
- .build(VortigonServiceSrv.Iface.class);
+ .build(RepositoryClientSrv.Iface.class);
}
@Bean
@@ -87,14 +86,4 @@ public ReportingSrv.Iface reporterClient(
.withAddress(resource.getURI())
.build(ReportingSrv.Iface.class);
}
-
- @Bean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient(
- @Value("${service.tokenKeeper.url}") Resource resource,
- @Value("${service.tokenKeeper.networkTimeout}") int networkTimeout) throws IOException {
- return new THSpawnClientBuilder()
- .withNetworkTimeout(networkTimeout)
- .withAddress(resource.getURI())
- .build(TokenAuthenticatorSrv.Iface.class);
- }
}
diff --git a/src/main/java/dev/vality/anapi/v2/config/SecurityConfig.java b/src/main/java/dev/vality/anapi/v2/config/SecurityConfig.java
new file mode 100644
index 00000000..72d49de5
--- /dev/null
+++ b/src/main/java/dev/vality/anapi/v2/config/SecurityConfig.java
@@ -0,0 +1,52 @@
+package dev.vality.anapi.v2.config;
+
+import dev.vality.anapi.v2.security.converter.JwtAuthConverter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+@Configuration
+@EnableWebSecurity
+@RequiredArgsConstructor
+@ConditionalOnProperty(value = "auth.enabled", havingValue = "true")
+public class SecurityConfig {
+
+ private final JwtAuthConverter jwtAuthConverter;
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http.csrf(AbstractHttpConfigurer::disable);
+ http.authorizeHttpRequests(
+ (authorize) -> authorize
+ .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
+ .requestMatchers(HttpMethod.GET, "/*/health/liveness").permitAll()
+ .requestMatchers(HttpMethod.GET, "/*/health/readiness").permitAll()
+ .requestMatchers(HttpMethod.GET, "/*/actuator/prometheus").permitAll()
+ .anyRequest().authenticated());
+ http.oauth2ResourceServer(server -> server.jwt(token -> token.jwtAuthenticationConverter(jwtAuthConverter)));
+ http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
+ http.cors(c -> c.configurationSource(corsConfigurationSource()));
+ return http.build();
+ }
+
+ public CorsConfigurationSource corsConfigurationSource() {
+ CorsConfiguration configuration = new CorsConfiguration();
+ configuration.applyPermitDefaultValues();
+ configuration.addAllowedMethod(HttpMethod.PUT);
+ configuration.addAllowedMethod(HttpMethod.DELETE);
+ configuration.addAllowedMethod(HttpMethod.OPTIONS);
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/*", configuration);
+ return source;
+ }
+}
diff --git a/src/main/java/dev/vality/anapi/v2/config/WebConfig.java b/src/main/java/dev/vality/anapi/v2/config/WebConfig.java
index bee665e4..414a5d70 100644
--- a/src/main/java/dev/vality/anapi/v2/config/WebConfig.java
+++ b/src/main/java/dev/vality/anapi/v2/config/WebConfig.java
@@ -1,40 +1,38 @@
package dev.vality.anapi.v2.config;
import dev.vality.woody.api.flow.WFlow;
+import dev.vality.woody.api.trace.context.metadata.user.UserIdentityEmailExtensionKit;
+import dev.vality.woody.api.trace.context.metadata.user.UserIdentityIdExtensionKit;
+import dev.vality.woody.api.trace.context.metadata.user.UserIdentityRealmExtensionKit;
+import dev.vality.woody.api.trace.context.metadata.user.UserIdentityUsernameExtensionKit;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.jwt.JwtClaimNames;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.filter.OncePerRequestFilter;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import static dev.vality.anapi.v2.util.DeadlineUtil.*;
+import static dev.vality.woody.api.trace.ContextUtils.setCustomMetadataValue;
import static dev.vality.woody.api.trace.ContextUtils.setDeadline;
+@Slf4j
@Configuration
@SuppressWarnings({"ParameterName", "LocalVariableName"})
public class WebConfig {
- @Bean
- public WebMvcConfigurer corsConfigurer() {
- return new WebMvcConfigurer() {
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**")
- .allowedOriginPatterns("*");
- }
- };
- }
-
@Bean
public FilterRegistrationBean woodyFilter() {
WFlow woodyFlow = new WFlow();
@@ -43,17 +41,22 @@ public FilterRegistrationBean woodyFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
- FilterChain filterChain) throws ServletException, IOException {
+ FilterChain filterChain) {
woodyFlow.createServiceFork(
- () -> {
- try {
- setWoodyDeadline(request);
- filterChain.doFilter(request, response);
- } catch (IOException | ServletException e) {
- sneakyThrow(e);
- }
+ () -> {
+ try {
+ var auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth instanceof JwtAuthenticationToken) {
+ addWoodyContext((JwtAuthenticationToken) auth);
}
- )
+ setWoodyDeadline(request);
+
+ filterChain.doFilter(request, response);
+ } catch (IOException | ServletException e) {
+ sneakyThrow(e);
+ }
+ }
+ )
.run();
}
@@ -70,11 +73,28 @@ private T sneakyThrow(Throwable t) throws E {
return filterRegistrationBean;
}
+ private void addWoodyContext(JwtAuthenticationToken token) {
+ setCustomMetadataValue(UserIdentityIdExtensionKit.KEY, token.getToken().getClaimAsString(JwtClaimNames.SUB));
+ setCustomMetadataValue(UserIdentityUsernameExtensionKit.KEY,
+ ((Jwt)token.getPrincipal()).getClaimAsString("preferred_username"));
+ setCustomMetadataValue(UserIdentityEmailExtensionKit.KEY, token.getToken().getClaimAsString("email"));
+ setCustomMetadataValue(UserIdentityRealmExtensionKit.KEY, extractRealm(token.getToken()));
+ }
+
+ private String extractRealm(Jwt token) {
+ var iss = token.getClaimAsString("iss");
+ return iss.substring(iss.lastIndexOf("/"));
+ }
+
private void setWoodyDeadline(HttpServletRequest request) {
String xRequestDeadline = request.getHeader("X-Request-Deadline");
String xRequestId = request.getHeader("X-Request-ID");
if (xRequestDeadline != null) {
- setDeadline(getInstant(xRequestDeadline, xRequestId));
+ try {
+ setDeadline(getInstant(xRequestDeadline, xRequestId));
+ } catch (Exception e) {
+ log.warn("Unable to parse 'X-Request-Deadline' header value '{}'", xRequestDeadline);
+ }
}
}
diff --git a/src/main/java/dev/vality/anapi/v2/config/properties/BouncerProperties.java b/src/main/java/dev/vality/anapi/v2/config/properties/BouncerProperties.java
index e2415a07..6fac8d31 100644
--- a/src/main/java/dev/vality/anapi/v2/config/properties/BouncerProperties.java
+++ b/src/main/java/dev/vality/anapi/v2/config/properties/BouncerProperties.java
@@ -1,13 +1,12 @@
package dev.vality.anapi.v2.config.properties;
+import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
-import javax.validation.constraints.NotEmpty;
-
@Getter
@Setter
@Component
diff --git a/src/main/java/dev/vality/anapi/v2/controller/ErrorControllerAdvice.java b/src/main/java/dev/vality/anapi/v2/controller/ErrorControllerAdvice.java
index 2d290786..2a27f769 100644
--- a/src/main/java/dev/vality/anapi/v2/controller/ErrorControllerAdvice.java
+++ b/src/main/java/dev/vality/anapi/v2/controller/ErrorControllerAdvice.java
@@ -1,13 +1,18 @@
package dev.vality.anapi.v2.controller;
-import dev.vality.anapi.v2.exception.*;
+import dev.vality.anapi.v2.exception.AuthorizationException;
+import dev.vality.anapi.v2.exception.BadRequestException;
+import dev.vality.anapi.v2.exception.DeadlineException;
+import dev.vality.anapi.v2.exception.NotFoundException;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import jakarta.validation.ConstraintViolationException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.AccessDeniedException;
import org.springframework.util.CollectionUtils;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
@@ -19,7 +24,6 @@
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.context.request.WebRequest;
-import javax.validation.ConstraintViolationException;
import java.net.http.HttpTimeoutException;
import java.util.List;
import java.util.stream.Collectors;
@@ -45,7 +49,7 @@ public Object handleBadRequestException(BadRequestException e) {
public Object handleDeadlineException(DeadlineException e) {
log.warn("<- Res [400]: Not valid", e);
return new DefaultLogicError()
- .code(DefaultLogicError.CodeEnum.INVALIDDEADLINE)
+ .code(DefaultLogicError.CodeEnum.INVALID_DEADLINE)
.message(e.getMessage());
}
@@ -57,7 +61,7 @@ public Object handleConstraintViolationException(ConstraintViolationException e)
.map(violation -> violation.getPropertyPath() + ": " + violation.getMessage())
.collect(Collectors.joining(", "));
return new DefaultLogicError()
- .code(DefaultLogicError.CodeEnum.INVALIDREQUEST)
+ .code(DefaultLogicError.CodeEnum.INVALID_REQUEST)
.message(errorMessage);
}
@@ -66,7 +70,7 @@ public Object handleConstraintViolationException(ConstraintViolationException e)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.warn("<- Res [400]: MethodArgument not valid", e);
return new DefaultLogicError()
- .code(DefaultLogicError.CodeEnum.INVALIDREQUEST)
+ .code(DefaultLogicError.CodeEnum.INVALID_REQUEST)
.message(e.getMessage());
}
@@ -75,20 +79,20 @@ public Object handleMethodArgumentNotValidException(MethodArgumentNotValidExcept
public Object handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
log.warn("<- Res [400]: Missing ServletRequestParameter", e);
return new DefaultLogicError()
- .code(DefaultLogicError.CodeEnum.INVALIDREQUEST)
+ .code(DefaultLogicError.CodeEnum.INVALID_REQUEST)
.message(e.getMessage());
}
- @ExceptionHandler({TokenKeeperException.class})
+ @ExceptionHandler({AccessDeniedException.class})
@ResponseStatus(HttpStatus.FORBIDDEN)
- public void handleTokenKeeperException(TokenKeeperException e) {
+ public void handleAccessDeniedException(AccessDeniedException e) {
log.warn("<- Res [403]: Request denied access", e);
}
@ExceptionHandler({AuthorizationException.class})
@ResponseStatus(HttpStatus.FORBIDDEN)
- public void handleAuthorizationException(AuthorizationException e) {
+ public void handleAccessDeniedException(AuthorizationException e) {
log.warn("<- Res [403]: Request denied access", e);
}
diff --git a/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToInvoiceTemplateSearchQueryConverter.java b/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToInvoiceTemplateSearchQueryConverter.java
index 91983b8e..1871b4e5 100644
--- a/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToInvoiceTemplateSearchQueryConverter.java
+++ b/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToInvoiceTemplateSearchQueryConverter.java
@@ -1,8 +1,8 @@
package dev.vality.anapi.v2.converter.magista.request;
import dev.vality.anapi.v2.exception.BadRequestException;
-import dev.vality.geck.common.util.TypeUtil;
import dev.vality.anapi.v2.util.ConverterUtil;
+import dev.vality.geck.common.util.TypeUtil;
import dev.vality.magista.InvoiceTemplateSearchQuery;
import dev.vality.magista.InvoiceTemplateStatus;
import org.springframework.stereotype.Component;
diff --git a/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverter.java b/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverter.java
deleted file mode 100644
index 94bd796b..00000000
--- a/src/main/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package dev.vality.anapi.v2.converter.magista.request;
-
-import dev.vality.anapi.v2.exception.BadRequestException;
-import dev.vality.anapi.v2.util.ConverterUtil;
-import dev.vality.magista.PayoutSearchQuery;
-import dev.vality.magista.PayoutToolType;
-import org.springframework.stereotype.Component;
-
-import java.time.OffsetDateTime;
-import java.util.List;
-
-@Component
-public class ParamsToPayoutSearchQueryConverter {
-
- public PayoutSearchQuery convert(String partyID,
- OffsetDateTime fromTime,
- OffsetDateTime toTime,
- Integer limit,
- List shopIDs,
- String payoutID,
- String payoutToolType,
- String continuationToken) {
- return new PayoutSearchQuery()
- .setCommonSearchQueryParams(
- ConverterUtil.fillCommonParams(fromTime, toTime, limit, partyID, shopIDs, continuationToken))
- .setPayoutId(payoutID)
- .setPayoutType(payoutToolType != null ? mapPayoutToolType(payoutToolType) : null);
- }
-
- protected PayoutToolType mapPayoutToolType(String payoutToolType) {
- return switch (payoutToolType) {
- case "PayoutAccount" -> PayoutToolType.payout_account;
- case "Wallet" -> PayoutToolType.wallet;
- case "PaymentInstitutionAccount" -> PayoutToolType.payment_institution_account;
- default -> throw new BadRequestException(
- String.format("PayoutToolType %s cannot be processed", payoutToolType));
- };
- }
-}
diff --git a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatChargebackToChargebackConverter.java b/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatChargebackToChargebackConverter.java
index 7d8be0cf..ebfa0794 100644
--- a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatChargebackToChargebackConverter.java
+++ b/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatChargebackToChargebackConverter.java
@@ -39,7 +39,7 @@ protected ChargebackCategory mapCategory(InvoicePaymentChargebackCategory charge
case DISPUTE -> ChargebackCategory.DISPUTE;
case AUTHORISATION -> ChargebackCategory.AUTHORISATION;
case PROCESSING_ERROR -> ChargebackCategory.PROCESSING_ERROR;
- default -> throw new IllegalArgumentException();
+ case SYSTEM_SET -> ChargebackCategory.SYSTEM_SET;
};
} catch (Exception e) {
throw new IllegalArgumentException(
diff --git a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverter.java b/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverter.java
index 92d2ca85..6a4d6056 100644
--- a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverter.java
+++ b/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverter.java
@@ -1,5 +1,6 @@
package dev.vality.anapi.v2.converter.magista.response;
+import dev.vality.anapi.v2.model.*;
import dev.vality.anapi.v2.model.ClientInfo;
import dev.vality.anapi.v2.model.ContactInfo;
import dev.vality.anapi.v2.model.CustomerPayer;
@@ -7,7 +8,6 @@
import dev.vality.anapi.v2.model.PaymentResourcePayer;
import dev.vality.anapi.v2.model.RecurrentPayer;
import dev.vality.anapi.v2.model.TransactionInfo;
-import dev.vality.anapi.v2.model.*;
import dev.vality.anapi.v2.util.MaskUtil;
import dev.vality.damsel.domain.*;
import dev.vality.geck.common.util.TypeUtil;
@@ -56,10 +56,10 @@ protected PaymentFlow mapFlow(InvoicePaymentFlow flow) {
.heldUntil(TypeUtil.stringToInstant(hold.getHeldUntil()).atOffset(ZoneOffset.UTC))
.onHoldExpiration(
PaymentFlowHold.OnHoldExpirationEnum.fromValue(hold.getOnHoldExpiration().name()))
- .type(PaymentFlow.TypeEnum.PAYMENTFLOWHOLD);
+ .type(PaymentFlow.TypeEnum.PAYMENT_FLOW_HOLD);
} else {
return new PaymentFlowInstant()
- .type(PaymentFlow.TypeEnum.PAYMENTFLOWINSTANT);
+ .type(PaymentFlow.TypeEnum.PAYMENT_FLOW_INSTANT);
}
}
diff --git a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverter.java b/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverter.java
deleted file mode 100644
index c217548e..00000000
--- a/src/main/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverter.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package dev.vality.anapi.v2.converter.magista.response;
-
-import dev.vality.damsel.domain.CountryCode;
-import dev.vality.damsel.domain.PayoutToolInfo;
-import dev.vality.geck.common.util.TypeUtil;
-import dev.vality.magista.PayoutStatus;
-import dev.vality.magista.StatPayout;
-import dev.vality.anapi.v2.model.*;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Nullable;
-import java.time.ZoneOffset;
-
-@Component
-public class StatPayoutToPayoutConverter {
-
- public Payout convert(StatPayout payout) {
- return new Payout()
- .amount(payout.getAmount())
- .createdAt(TypeUtil.stringToInstant(payout.getCreatedAt()).atOffset(ZoneOffset.UTC))
- .currency(payout.getCurrencySymbolicCode())
- .fee(payout.getFee())
- .id(payout.getId())
- .payoutToolDetails(mapPayoutToolDetails(payout.getPayoutToolInfo()))
- .shopID(payout.getShopId())
- .status(mapStatus(payout.getStatus()))
- .cancellationDetails(
- payout.getStatus().isSetCancelled()
- ? payout.getStatus().getCancelled().getDetails()
- : null);
- }
-
- protected String mapStatus(PayoutStatus status) {
- try {
- var field = PayoutStatus._Fields.findByName(status.getSetField().getFieldName());
- return switch (field) {
- case UNPAID -> "Unpaid";
- case PAID -> "Paid";
- case CANCELLED -> "Cancelled";
- case CONFIRMED -> "Confirmed";
- default -> throw new IllegalArgumentException();
- };
- } catch (Exception e) {
- throw new IllegalArgumentException(
- String.format("Payout status %s cannot be processed", status));
- }
- }
-
- protected PayoutToolDetails mapPayoutToolDetails(PayoutToolInfo payoutToolInfo) {
- try {
- var field = PayoutToolInfo._Fields.findByName(payoutToolInfo.getSetField().getFieldName());
- switch (field) {
- case RUSSIAN_BANK_ACCOUNT -> {
- var account = payoutToolInfo.getRussianBankAccount();
- return new PayoutToolDetailsBankAccount()
- .account(account.getAccount())
- .bankBik(account.getBankBik())
- .bankName(account.getBankName())
- .bankPostAccount(account.getBankPostAccount())
- .detailsType("PayoutToolDetailsBankAccount");
- }
- case INTERNATIONAL_BANK_ACCOUNT -> {
- var account = payoutToolInfo.getInternationalBankAccount();
- return new PayoutToolDetailsInternationalBankAccount()
- .iban(account.getIban())
- .number(account.getNumber())
- .bankDetails(account.isSetBank()
- ? new InternationalBankDetails()
- .name(account.getBank().getName())
- .bic(account.getBank().getBic())
- .countryCode(mapCountryCode(account.getBank().getCountry()))
- .address(account.getBank().getAddress())
- .abartn(account.getBank().getAbaRtn())
- : null)
- .correspondentBankAccount(
- mapInternationalCorrespondentBankAccount(account.getCorrespondentAccount()))
- .detailsType("PayoutToolDetailsInternationalBankAccount");
- }
- case WALLET_INFO -> {
- return new PayoutToolDetailsWalletInfo()
- .walletID(payoutToolInfo.getWalletInfo().getWalletId())
- .detailsType("PayoutToolDetailsWalletInfo");
- }
- case PAYMENT_INSTITUTION_ACCOUNT -> {
- return new PayoutToolDetailsPaymentInstitutionAccount()
- .detailsType("PayoutToolDetailsPaymentInstitutionAccount");
- }
- default -> throw new IllegalArgumentException();
- }
- } catch (Exception e) {
- throw new IllegalArgumentException(
- String.format("PayoutToolInfo %s cannot be processed", payoutToolInfo));
- }
-
- }
-
- protected String mapCountryCode(@Nullable CountryCode countryCode) {
- if (countryCode == null) {
- return null;
- }
- return countryCode.name();
- }
-
- protected InternationalCorrespondentBankAccount mapInternationalCorrespondentBankAccount(
- dev.vality.damsel.domain.InternationalBankAccount account) {
- if (account == null) {
- return null;
- }
- var details = account.getBank();
- return new InternationalCorrespondentBankAccount()
- .bankDetails(details != null
- ? new InternationalBankDetails()
- .name(details.getName())
- .bic(details.getBic())
- .countryCode(details.getCountry().name())
- .address(details.getAddress())
- .abartn(details.getAbaRtn())
- : null)
- .iban(account.getIban())
- .number(account.getNumber())
- .correspondentBankAccount(account.isSetCorrespondentAccount()
- ? mapInternationalCorrespondentBankAccount(account.getCorrespondentAccount())
- : null);
- }
-}
diff --git a/src/main/java/dev/vality/anapi/v2/converter/reporter/request/ParamsToStatReportRequestConverter.java b/src/main/java/dev/vality/anapi/v2/converter/reporter/request/ParamsToStatReportRequestConverter.java
index 99429f00..d2f72629 100644
--- a/src/main/java/dev/vality/anapi/v2/converter/reporter/request/ParamsToStatReportRequestConverter.java
+++ b/src/main/java/dev/vality/anapi/v2/converter/reporter/request/ParamsToStatReportRequestConverter.java
@@ -37,10 +37,8 @@ public ReportRequest mapToReportRequest(String partyId, String shopId, OffsetDat
public String mapReportType(String requestReportType) {
Report.ReportTypeEnum inputType = Report.ReportTypeEnum.fromValue(requestReportType);
return switch (inputType) {
- case PAYMENTREGISTRY -> "payment_registry";
- case PROVISIONOFSERVICE -> "provision_of_service";
- case PAYMENTREGISTRYBYPAYOUT -> "payment_registry_by_payout";
- default -> throw new IllegalArgumentException("Unknown report type: " + inputType.getValue());
+ case PAYMENT_REGISTRY -> "payment_registry";
+ case PROVISION_OF_SERVICE -> "provision_of_service";
};
}
diff --git a/src/main/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverter.java b/src/main/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverter.java
index 9b3e910e..e2bf1c65 100644
--- a/src/main/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverter.java
+++ b/src/main/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverter.java
@@ -36,9 +36,8 @@ public Report convert(dev.vality.reporter.Report response) {
private Report.ReportTypeEnum mapReportType(String type) {
return switch (type) {
- case "provision_of_service" -> Report.ReportTypeEnum.PROVISIONOFSERVICE;
- case "payment_registry" -> Report.ReportTypeEnum.PAYMENTREGISTRY;
- case "payment_registry_by_payout" -> Report.ReportTypeEnum.PAYMENTREGISTRYBYPAYOUT;
+ case "provision_of_service" -> Report.ReportTypeEnum.PROVISION_OF_SERVICE;
+ case "payment_registry" -> Report.ReportTypeEnum.PAYMENT_REGISTRY;
default -> throw new IllegalArgumentException("Unknown report type: " + type);
};
}
diff --git a/src/main/java/dev/vality/anapi/v2/exception/BadRequestException.java b/src/main/java/dev/vality/anapi/v2/exception/BadRequestException.java
index 30462726..914a23c8 100644
--- a/src/main/java/dev/vality/anapi/v2/exception/BadRequestException.java
+++ b/src/main/java/dev/vality/anapi/v2/exception/BadRequestException.java
@@ -21,7 +21,7 @@ public BadRequestException(String message, Object response) {
public BadRequestException(String message) {
super(message);
this.response = new DefaultLogicError()
- .code(DefaultLogicError.CodeEnum.INVALIDREQUEST)
+ .code(DefaultLogicError.CodeEnum.INVALID_REQUEST)
.message(message);
}
}
\ No newline at end of file
diff --git a/src/main/java/dev/vality/anapi/v2/exception/DominantException.java b/src/main/java/dev/vality/anapi/v2/exception/DominantException.java
new file mode 100644
index 00000000..bedb8ff9
--- /dev/null
+++ b/src/main/java/dev/vality/anapi/v2/exception/DominantException.java
@@ -0,0 +1,12 @@
+package dev.vality.anapi.v2.exception;
+
+public class DominantException extends AnapiV25xxException {
+
+ public DominantException(String s) {
+ super(s);
+ }
+
+ public DominantException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/dev/vality/anapi/v2/exception/TokenKeeperException.java b/src/main/java/dev/vality/anapi/v2/exception/TokenKeeperException.java
deleted file mode 100644
index 930c036f..00000000
--- a/src/main/java/dev/vality/anapi/v2/exception/TokenKeeperException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package dev.vality.anapi.v2.exception;
-
-public class TokenKeeperException extends RuntimeException {
-
- public TokenKeeperException(String s) {
- super(s);
- }
-
- public TokenKeeperException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/src/main/java/dev/vality/anapi/v2/exception/VortigonException.java b/src/main/java/dev/vality/anapi/v2/exception/VortigonException.java
deleted file mode 100644
index cf78ee06..00000000
--- a/src/main/java/dev/vality/anapi/v2/exception/VortigonException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package dev.vality.anapi.v2.exception;
-
-public class VortigonException extends AnapiV25xxException {
-
- public VortigonException(String s) {
- super(s);
- }
-
- public VortigonException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/src/main/java/dev/vality/anapi/v2/security/AccessData.java b/src/main/java/dev/vality/anapi/v2/security/AccessData.java
index 945ef324..6010ff57 100644
--- a/src/main/java/dev/vality/anapi/v2/security/AccessData.java
+++ b/src/main/java/dev/vality/anapi/v2/security/AccessData.java
@@ -1,9 +1,9 @@
package dev.vality.anapi.v2.security;
+import jakarta.annotation.Nullable;
import lombok.Builder;
import lombok.Data;
-import javax.annotation.Nullable;
import java.util.List;
@Builder
diff --git a/src/main/java/dev/vality/anapi/v2/security/AccessService.java b/src/main/java/dev/vality/anapi/v2/security/AccessService.java
index 0aefd7e7..eccf4dde 100644
--- a/src/main/java/dev/vality/anapi/v2/security/AccessService.java
+++ b/src/main/java/dev/vality/anapi/v2/security/AccessService.java
@@ -3,15 +3,16 @@
import dev.vality.anapi.v2.exception.AuthorizationException;
import dev.vality.anapi.v2.exception.BouncerException;
import dev.vality.anapi.v2.service.BouncerService;
-import dev.vality.anapi.v2.service.TokenKeeperService;
-import dev.vality.anapi.v2.service.VortigonService;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.bouncer.base.Entity;
+import jakarta.annotation.Nullable;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Service;
-import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -22,9 +23,8 @@
@Service
public class AccessService {
- private final VortigonService vortigonService;
+ private final DominantService dominantService;
private final BouncerService bouncerService;
- private final TokenKeeperService tokenKeeperService;
@Value("${service.bouncer.auth.enabled}")
private boolean authEnabled;
@@ -34,7 +34,7 @@ public void checkUserAccess(AccessData accessData) {
}
public List getRestrictedShops(AccessData accessData) {
- var requestedShopIds = vortigonService.getShopIds(accessData.getPartyId(),
+ var requestedShopIds = dominantService.getShopIds(accessData.getPartyId(),
Objects.requireNonNullElse(accessData.getRealm(), "live"));
if (accessData.getShopIds() != null && !accessData.getShopIds().isEmpty()) {
requestedShopIds = accessData.getShopIds().stream()
@@ -86,13 +86,15 @@ private List getRestrictedShops(AccessData accessData, @Nullable List shopIds) {
+ var token = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
return AnapiBouncerContext.builder()
.operationId(accessData.getOperationId())
.partyId(accessData.getPartyId())
.shopIds(shopIds)
.fileId(accessData.getFileId())
.reportId(accessData.getReportId())
- .authData(tokenKeeperService.getAuthData())
+ .tokenId(token.getToken().getId())
+ .userId(token.getToken().getSubject())
.build();
}
}
diff --git a/src/main/java/dev/vality/anapi/v2/security/AnapiBouncerContext.java b/src/main/java/dev/vality/anapi/v2/security/AnapiBouncerContext.java
index b00f4eed..5e577af3 100644
--- a/src/main/java/dev/vality/anapi/v2/security/AnapiBouncerContext.java
+++ b/src/main/java/dev/vality/anapi/v2/security/AnapiBouncerContext.java
@@ -1,6 +1,5 @@
package dev.vality.anapi.v2.security;
-import dev.vality.token.keeper.AuthData;
import lombok.Builder;
import lombok.Data;
@@ -10,7 +9,6 @@
@Data
public class AnapiBouncerContext {
- private final long tokenExpiration;
private final String tokenId;
private final String userId;
private final String operationId;
@@ -18,6 +16,6 @@ public class AnapiBouncerContext {
private final List shopIds;
private final String reportId;
private final String fileId;
- private final AuthData authData;
+
}
diff --git a/src/main/java/dev/vality/anapi/v2/security/BouncerContextFactory.java b/src/main/java/dev/vality/anapi/v2/security/BouncerContextFactory.java
index 9a496bd4..83dec0ea 100644
--- a/src/main/java/dev/vality/anapi/v2/security/BouncerContextFactory.java
+++ b/src/main/java/dev/vality/anapi/v2/security/BouncerContextFactory.java
@@ -2,7 +2,6 @@
import dev.vality.anapi.v2.config.properties.BouncerProperties;
import dev.vality.anapi.v2.service.OrgManagerService;
-import dev.vality.anapi.v2.util.JwtUtil;
import dev.vality.bouncer.base.Entity;
import dev.vality.bouncer.context.v1.*;
import dev.vality.bouncer.ctx.ContextFragmentType;
@@ -11,10 +10,11 @@
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TSerializer;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;
import java.time.Instant;
-import java.util.Optional;
import java.util.Set;
@RequiredArgsConstructor
@@ -32,17 +32,11 @@ public Context buildContext(AnapiBouncerContext bouncerContext) {
var fragment = new dev.vality.bouncer.ctx.ContextFragment()
.setType(ContextFragmentType.v1_thrift_binary)
.setContent(serializer.serialize(contextFragment));
-
+ var userFragment = orgManagerService.getUserAuthContext(
+ bouncerContext.getUserId());
var context = new Context();
- context.putToFragments("anapi", fragment);
- context.putToFragments("token-keeper", bouncerContext.getAuthData().getContext());
-
- Optional subject = JwtUtil.getSubject(bouncerContext.getAuthData().getToken());
- if (subject.isPresent()) {
- log.debug("User context fragment will be added");
- var userFragment = orgManagerService.getUserAuthContext(subject.get());
- context.putToFragments("user", userFragment);
- }
+ context.putToFragments(bouncerProperties.getContextFragmentId(), fragment);
+ context.putToFragments("user", userFragment);
return context;
}
@@ -52,11 +46,21 @@ private ContextFragment buildContextFragment(AnapiBouncerContext bouncerContext)
var contextReports = buildReportContext(bouncerContext);
ContextFragment fragment = new ContextFragment();
return fragment
+ .setAuth(buildAuth())
.setEnv(env)
.setAnapi(contextAnalyticsApi)
.setReports(contextReports);
}
+ private Auth buildAuth() {
+ var auth = new Auth();
+ var token = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
+ return auth
+ .setToken(new Token().setId(token.getToken().getId()))
+ .setMethod(bouncerProperties.getAuthMethod())
+ .setExpiration(Instant.ofEpochSecond(token.getToken().getExpiresAt().getEpochSecond()).toString());
+ }
+
private Environment buildEnvironment() {
var deployment = new Deployment()
.setId(bouncerProperties.getDeploymentId());
@@ -72,7 +76,7 @@ private ContextAnalyticsAPI buildAnapiContext(AnapiBouncerContext ctx) {
.setParty(ctx.getPartyId() != null
? new Entity().setId(ctx.getPartyId()) : null)
.setShop(ctx.getShopIds() != null && ctx.getShopIds().size() == 1
- ? new Entity().setId(ctx.getShopIds().get(0)) : null)
+ ? new Entity().setId(ctx.getShopIds().getFirst()) : null)
.setFile(ctx.getFileId() != null
? new Entity().setId(ctx.getFileId()) : null)
.setReport(ctx.getReportId() != null
@@ -87,7 +91,7 @@ private ContextReports buildReportContext(AnapiBouncerContext ctx) {
.setParty(ctx.getPartyId() != null
? new Entity().setId(ctx.getPartyId()) : null)
.setShop(ctx.getShopIds() != null && ctx.getShopIds().size() == 1
- ? new Entity().setId(ctx.getShopIds().get(0)) : null)
+ ? new Entity().setId(ctx.getShopIds().getFirst()) : null)
.setFiles(ctx.getFileId() != null
? Set.of(new Entity().setId(ctx.getFileId())) : null));
}
diff --git a/src/main/java/dev/vality/anapi/v2/security/converter/JwtAuthConverter.java b/src/main/java/dev/vality/anapi/v2/security/converter/JwtAuthConverter.java
new file mode 100644
index 00000000..568aae6b
--- /dev/null
+++ b/src/main/java/dev/vality/anapi/v2/security/converter/JwtAuthConverter.java
@@ -0,0 +1,53 @@
+package dev.vality.anapi.v2.security.converter;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class JwtAuthConverter implements Converter {
+
+ private static final String principleAttribute = "preferred_username";
+ private static final String resourceAttribute = "resource_access";
+
+ @Override
+ public AbstractAuthenticationToken convert(Jwt jwt) {
+ return new JwtAuthenticationToken(
+ jwt,
+ new HashSet<>(extractResourceRoles(jwt)),
+ getPrincipleClaimName(jwt)
+ );
+ }
+
+ private Collection extends GrantedAuthority> extractResourceRoles(Jwt token) {
+ if (token.getClaim(resourceAttribute) == null) {
+ return Set.of();
+ }
+ Map resourceAccess = token.getClaim(resourceAttribute);
+ if (resourceAccess.isEmpty()) {
+ return Set.of();
+ }
+
+ return resourceAccess.values().stream()
+ .map(resourceAccessInfo -> (Map) resourceAccessInfo)
+ .flatMap(resourceAccessInfo -> ((Collection) resourceAccessInfo.get("roles")).stream())
+ .map(SimpleGrantedAuthority::new)
+ .collect(Collectors.toSet());
+ }
+
+ private String getPrincipleClaimName(Jwt jwt) {
+ return jwt.getClaim(principleAttribute);
+ }
+}
diff --git a/src/main/java/dev/vality/anapi/v2/service/AnalyticsService.java b/src/main/java/dev/vality/anapi/v2/service/AnalyticsService.java
index 1193b9b8..8ab60329 100644
--- a/src/main/java/dev/vality/anapi/v2/service/AnalyticsService.java
+++ b/src/main/java/dev/vality/anapi/v2/service/AnalyticsService.java
@@ -1,11 +1,11 @@
package dev.vality.anapi.v2.service;
import dev.vality.anapi.v2.exception.AnalytycsException;
+import dev.vality.anapi.v2.model.*;
import dev.vality.anapi.v2.model.OffsetAmount;
import dev.vality.anapi.v2.model.OffsetCount;
import dev.vality.anapi.v2.model.SplitUnit;
import dev.vality.anapi.v2.model.SubError;
-import dev.vality.anapi.v2.model.*;
import dev.vality.damsel.analytics.*;
import lombok.RequiredArgsConstructor;
import org.apache.thrift.TException;
@@ -19,10 +19,10 @@ public class AnalyticsService {
private final AnalyticsServiceSrv.Iface analyticsClient;
- public InlineResponse2006 getPaymentsToolDistribution(FilterRequest filterRequest) {
+ public GetPaymentsToolDistribution200Response getPaymentsToolDistribution(FilterRequest filterRequest) {
try {
var distribution = analyticsClient.getPaymentsToolDistribution(filterRequest);
- return new InlineResponse2006()
+ return new GetPaymentsToolDistribution200Response()
.result(distribution.getPaymentToolsDistributions().stream()
.map(o -> new PaymentsToolDistributionResult()
.name(o.getName())
@@ -33,10 +33,10 @@ public InlineResponse2006 getPaymentsToolDistribution(FilterRequest filterReques
}
}
- public InlineResponse200 getPaymentsAmount(FilterRequest filterRequest) {
+ public GetPaymentsAmount200Response getPaymentsAmount(FilterRequest filterRequest) {
try {
var paymentsAmount = analyticsClient.getPaymentsAmount(filterRequest);
- return new InlineResponse200()
+ return new GetPaymentsAmount200Response()
.result(paymentsAmount.getGroupsAmount().stream()
.map(o -> new AmountResult()
.amount(o.getAmount())
@@ -47,10 +47,10 @@ public InlineResponse200 getPaymentsAmount(FilterRequest filterRequest) {
}
}
- public InlineResponse200 getCreditingsAmount(FilterRequest filterRequest) {
+ public GetPaymentsAmount200Response getCreditingsAmount(FilterRequest filterRequest) {
try {
var creditingsAmount = analyticsClient.getCreditingsAmount(filterRequest);
- return new InlineResponse200()
+ return new GetPaymentsAmount200Response()
.result(creditingsAmount.getGroupsAmount().stream()
.map(o -> new AmountResult()
.amount(o.getAmount())
@@ -61,10 +61,10 @@ public InlineResponse200 getCreditingsAmount(FilterRequest filterRequest) {
}
}
- public InlineResponse200 getAveragePayment(FilterRequest filterRequest) {
+ public GetPaymentsAmount200Response getAveragePayment(FilterRequest filterRequest) {
try {
var averagePayment = analyticsClient.getAveragePayment(filterRequest);
- return new InlineResponse200()
+ return new GetPaymentsAmount200Response()
.result(averagePayment.getGroupsAmount().stream()
.map(o -> new AmountResult()
.amount(o.getAmount())
@@ -75,10 +75,10 @@ public InlineResponse200 getAveragePayment(FilterRequest filterRequest) {
}
}
- public InlineResponse2001 getPaymentsCount(FilterRequest filterRequest) {
+ public GetPaymentsCount200Response getPaymentsCount(FilterRequest filterRequest) {
try {
var paymentsCount = analyticsClient.getPaymentsCount(filterRequest);
- return new InlineResponse2001()
+ return new GetPaymentsCount200Response()
.result(paymentsCount.getGroupsCount().stream()
.map(o -> new CountResult()
.count(o.getCount())
@@ -89,10 +89,10 @@ public InlineResponse2001 getPaymentsCount(FilterRequest filterRequest) {
}
}
- public InlineResponse2002 getPaymentsErrorDistribution(FilterRequest filterRequest) {
+ public GetPaymentsErrorDistribution200Response getPaymentsErrorDistribution(FilterRequest filterRequest) {
try {
var distribution = analyticsClient.getPaymentsErrorDistribution(filterRequest);
- return new InlineResponse2002()
+ return new GetPaymentsErrorDistribution200Response()
.result(distribution.getErrorDistributions().stream()
.map(o -> new PaymentsErrorsDistributionResult()
.error(o.getName())
@@ -103,10 +103,10 @@ public InlineResponse2002 getPaymentsErrorDistribution(FilterRequest filterReque
}
}
- public InlineResponse2005 getPaymentsSubErrorDistribution(FilterRequest filterRequest) {
+ public GetPaymentsSubErrorDistribution200Response getPaymentsSubErrorDistribution(FilterRequest filterRequest) {
try {
var distribution = analyticsClient.getPaymentsSubErrorDistribution(filterRequest);
- return new InlineResponse2005()
+ return new GetPaymentsSubErrorDistribution200Response()
.result(distribution.getErrorDistributions().stream()
.map(o -> new PaymentsSubErrorsDistributionResult()
.error(getSubError(o.getError()))
@@ -117,10 +117,10 @@ public InlineResponse2005 getPaymentsSubErrorDistribution(FilterRequest filterRe
}
}
- public InlineResponse2003 getPaymentsSplitAmount(SplitFilterRequest splitFilterRequest) {
+ public GetPaymentsSplitAmount200Response getPaymentsSplitAmount(SplitFilterRequest splitFilterRequest) {
try {
var paymentsSplitAmount = analyticsClient.getPaymentsSplitAmount(splitFilterRequest);
- return new InlineResponse2003()
+ return new GetPaymentsSplitAmount200Response()
.result(paymentsSplitAmount.getGroupedCurrencyAmounts().stream()
.map(o -> createSplitAmountResult(o, paymentsSplitAmount.getResultSplitUnit()))
.collect(Collectors.toList()));
@@ -129,10 +129,10 @@ public InlineResponse2003 getPaymentsSplitAmount(SplitFilterRequest splitFilterR
}
}
- public InlineResponse2004 getPaymentsSplitCount(SplitFilterRequest splitFilterRequest) {
+ public GetPaymentsSplitCount200Response getPaymentsSplitCount(SplitFilterRequest splitFilterRequest) {
try {
var paymentsSplitCount = analyticsClient.getPaymentsSplitCount(splitFilterRequest);
- return new InlineResponse2004()
+ return new GetPaymentsSplitCount200Response()
.result(paymentsSplitCount.getPaymentToolsDestrobutions().stream()
.map(o -> createSplitCountResult(o, paymentsSplitCount.getResultSplitUnit()))
.collect(Collectors.toList()));
@@ -141,10 +141,10 @@ public InlineResponse2004 getPaymentsSplitCount(SplitFilterRequest splitFilterRe
}
}
- public InlineResponse200 getRefundsAmount(FilterRequest filterRequest) {
+ public GetPaymentsAmount200Response getRefundsAmount(FilterRequest filterRequest) {
try {
var refundsAmount = analyticsClient.getRefundsAmount(filterRequest);
- return new InlineResponse200()
+ return new GetPaymentsAmount200Response()
.result(refundsAmount.getGroupsAmount().stream()
.map(o -> new AmountResult()
.amount(o.getAmount())
@@ -155,10 +155,10 @@ public InlineResponse200 getRefundsAmount(FilterRequest filterRequest) {
}
}
- public InlineResponse200 getCurrentBalances(MerchantFilter merchantFilter) {
+ public GetPaymentsAmount200Response getCurrentBalances(MerchantFilter merchantFilter) {
try {
var refundsAmount = analyticsClient.getCurrentBalances(merchantFilter);
- return new InlineResponse200()
+ return new GetPaymentsAmount200Response()
.result(refundsAmount.getGroupsAmount().stream()
.map(o -> new AmountResult()
.amount(o.getAmount())
@@ -169,7 +169,7 @@ public InlineResponse200 getCurrentBalances(MerchantFilter merchantFilter) {
}
}
- public InlineResponse2007 getCurrentShopBalances(MerchantFilter merchantFilter) {
+ public GetCurrentShopBalances200Response getCurrentShopBalances(MerchantFilter merchantFilter) {
try {
var currentShopBalances = analyticsClient.getCurrentShopBalances(merchantFilter);
var shopAmountResults = currentShopBalances.getGroupsAmount().stream()
@@ -185,7 +185,7 @@ public InlineResponse2007 getCurrentShopBalances(MerchantFilter merchantFilter)
.id(entry.getKey())
.amountResults(entry.getValue()))
.collect(Collectors.toList());
- return new InlineResponse2007()
+ return new GetCurrentShopBalances200Response()
.result(shopAmountResults);
} catch (TException e) {
throw new AnalytycsException("Error while call analyticsClient.getCurrentShopBalances", e);
diff --git a/src/main/java/dev/vality/anapi/v2/service/DominantService.java b/src/main/java/dev/vality/anapi/v2/service/DominantService.java
new file mode 100644
index 00000000..10a9b2c7
--- /dev/null
+++ b/src/main/java/dev/vality/anapi/v2/service/DominantService.java
@@ -0,0 +1,54 @@
+package dev.vality.anapi.v2.service;
+
+import dev.vality.anapi.v2.exception.DominantException;
+import dev.vality.damsel.domain.*;
+import dev.vality.damsel.domain_config_v2.RepositoryClientSrv;
+import dev.vality.damsel.domain_config_v2.VersionReference;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.thrift.TException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DominantService {
+
+ private final RepositoryClientSrv.Iface dominantClient;
+
+ public List getShopIds(String partyId, String realm) {
+ try {
+ log.info("Looking for shops, partyId={}, realm={}", partyId, realm);
+ List shopsRefs = getShopConfigRefs(partyId);
+ List shopsObjects = getShopConfigObjects(shopsRefs);
+ var shopIds = shopsObjects.stream()
+ .filter(shopConfigObject -> realmMatches(realm, shopConfigObject))
+ .map(shopConfigObject -> shopConfigObject.getData().getId()).toList();
+ log.info("Found {} shops, partyId={}, realm={}", shopIds.size(), partyId, realm);
+ return shopIds;
+ } catch (TException e) {
+ throw new DominantException(String.format("Error while call dominant, partyId=%s", partyId), e);
+ }
+ }
+
+ private List getShopConfigRefs(String partyId) throws TException {
+ var partyReference = Reference.party_config(new PartyConfigRef(partyId));
+ var party = dominantClient.checkoutObject(new VersionReference(), partyReference);
+ return party.getObject().getPartyConfig().getData().getShops();
+ }
+
+ private List getShopConfigObjects(List shopConfigRefs) throws TException {
+ var shopConfigs = dominantClient.checkoutObjects(new VersionReference(),
+ shopConfigRefs.stream().map(Reference::shop_config).toList());
+ return shopConfigs.stream().map(domainObject -> domainObject.getObject().getShopConfig()).toList();
+ }
+
+ private boolean realmMatches(String expectedRealm, ShopConfigObject shopConfigObject) {
+ int realmId = shopConfigObject.getData().getPaymentInstitution().getId();
+ var paymentInstitutionRealm =
+ PaymentInstitutionRealm.findByValue(realmId);
+ return expectedRealm.equals(paymentInstitutionRealm.name());
+ }
+}
diff --git a/src/main/java/dev/vality/anapi/v2/service/MagistaService.java b/src/main/java/dev/vality/anapi/v2/service/MagistaService.java
index f0c2d8c6..69d30fdb 100644
--- a/src/main/java/dev/vality/anapi/v2/service/MagistaService.java
+++ b/src/main/java/dev/vality/anapi/v2/service/MagistaService.java
@@ -20,14 +20,13 @@ public class MagistaService {
private final StatPaymentToPaymentSearchResultConverter paymentResponseConverter;
private final StatChargebackToChargebackConverter chargebackResponseConverter;
private final StatInvoiceToInvoiceConverter invoiceResponseConverter;
- private final StatPayoutToPayoutConverter payoutResponseConverter;
private final StatRefundToRefundSearchResultConverter refundResponseConverter;
private final StatInvoiceTemplateToInvoiceTemplateConverter invoiceTemplateResponseConverter;
- public InlineResponse2008 searchInvoices(InvoiceSearchQuery query) {
+ public SearchInvoices200Response searchInvoices(InvoiceSearchQuery query) {
try {
StatInvoiceResponse magistaResponse = magistaClient.searchInvoices(query);
- return new InlineResponse2008()
+ return new SearchInvoices200Response()
.result(magistaResponse.getInvoices().stream()
.map(invoiceResponseConverter::convert)
.collect(Collectors.toList()))
@@ -59,10 +58,10 @@ public InlineResponse2008 searchInvoices(InvoiceSearchQuery query) {
}
}
- public InlineResponse2009 searchPayments(PaymentSearchQuery query) {
+ public SearchPayments200Response searchPayments(PaymentSearchQuery query) {
try {
StatPaymentResponse magistaResponse = magistaClient.searchPayments(query);
- return new InlineResponse2009()
+ return new SearchPayments200Response()
.result(magistaResponse.getPayments().stream()
.map(paymentResponseConverter::convert)
.collect(Collectors.toList()))
@@ -94,10 +93,10 @@ public InlineResponse2009 searchPayments(PaymentSearchQuery query) {
}
}
- public InlineResponse20010 searchRefunds(RefundSearchQuery query) {
+ public SearchRefunds200Response searchRefunds(RefundSearchQuery query) {
try {
StatRefundResponse magistaResponse = magistaClient.searchRefunds(query);
- return new InlineResponse20010()
+ return new SearchRefunds200Response()
.result(magistaResponse.getRefunds().stream()
.map(refundResponseConverter::convert)
.collect(Collectors.toList()))
@@ -129,10 +128,10 @@ public InlineResponse20010 searchRefunds(RefundSearchQuery query) {
}
}
- public InlineResponse20011 searchChargebacks(ChargebackSearchQuery query) {
+ public SearchChargebacks200Response searchChargebacks(ChargebackSearchQuery query) {
try {
StatChargebackResponse magistaResponse = magistaClient.searchChargebacks(query);
- return new InlineResponse20011()
+ return new SearchChargebacks200Response()
.result(magistaResponse.getChargebacks().stream()
.map(chargebackResponseConverter::convert)
.collect(Collectors.toList()))
@@ -164,45 +163,10 @@ public InlineResponse20011 searchChargebacks(ChargebackSearchQuery query) {
}
}
- public InlineResponse20012 searchPayouts(PayoutSearchQuery query) {
- try {
- StatPayoutResponse magistaResponse = magistaClient.searchPayouts(query);
- return new InlineResponse20012()
- .result(magistaResponse.getPayouts().stream()
- .map(payoutResponseConverter::convert)
- .collect(Collectors.toList()))
- .continuationToken(magistaResponse.getContinuationToken());
- } catch (BadContinuationToken e) {
- var message = String.format(
- "Bad token exceeded, partyId=%s, payoutId=%s",
- query.getCommonSearchQueryParams().getPartyId(),
- query.getPayoutId());
- throw badContinuationTokenException(e, message);
- } catch (LimitExceeded e) {
- var message = String.format(
- "Limit exceeded, partyId=%s, payoutId=%s",
- query.getCommonSearchQueryParams().getPartyId(),
- query.getPayoutId());
- throw limitExceededException(e, message);
- } catch (InvalidRequest e) {
- var message = String.format(
- "Invalid request, partyId=%s, payoutId=%s, errors=%s",
- query.getCommonSearchQueryParams().getPartyId(),
- query.getPayoutId(),
- String.join(", ", e.getErrors()));
- throw invalidRequestException(e, message);
- } catch (TException e) {
- throw new MagistaException(
- String.format("Error while call magistaClient.searchPayouts, partyId=%s, payoutId=%s",
- query.getCommonSearchQueryParams().getPartyId(), query.getPayoutId()),
- e);
- }
- }
-
- public InlineResponse20013 searchInvoiceTemplates(InvoiceTemplateSearchQuery query) {
+ public SearchInvoiceTemplates200Response searchInvoiceTemplates(InvoiceTemplateSearchQuery query) {
try {
StatInvoiceTemplateResponse magistaResponse = magistaClient.searchInvoiceTemplates(query);
- return new InlineResponse20013()
+ return new SearchInvoiceTemplates200Response()
.result(magistaResponse.getInvoiceTemplates().stream()
.map(invoiceTemplateResponseConverter::convert)
.collect(Collectors.toList()))
@@ -237,21 +201,21 @@ public InlineResponse20013 searchInvoiceTemplates(InvoiceTemplateSearchQuery que
private BadRequestException badContinuationTokenException(BadContinuationToken e, String message) {
var error = new SearchRequestError()
- .code(SearchRequestError.CodeEnum.BADCONTINUATIONTOKEN)
+ .code(SearchRequestError.CodeEnum.BAD_CONTINUATION_TOKEN)
.message(message);
return new BadRequestException(message, e, error);
}
private BadRequestException limitExceededException(LimitExceeded e, String message) {
var error = new SearchRequestError()
- .code(SearchRequestError.CodeEnum.LIMITEXCEEDED)
+ .code(SearchRequestError.CodeEnum.LIMIT_EXCEEDED)
.message(message);
return new BadRequestException(message, e, error);
}
private BadRequestException invalidRequestException(InvalidRequest e, String message) {
var error = new SearchRequestError()
- .code(SearchRequestError.CodeEnum.INVALIDREQUEST)
+ .code(SearchRequestError.CodeEnum.INVALID_REQUEST)
.message(message);
return new BadRequestException(message, e, error);
}
diff --git a/src/main/java/dev/vality/anapi/v2/service/ReporterService.java b/src/main/java/dev/vality/anapi/v2/service/ReporterService.java
index 68587250..58f56569 100644
--- a/src/main/java/dev/vality/anapi/v2/service/ReporterService.java
+++ b/src/main/java/dev/vality/anapi/v2/service/ReporterService.java
@@ -2,7 +2,9 @@
import dev.vality.anapi.v2.converter.reporter.response.ReporterResponseToReportConverter;
import dev.vality.anapi.v2.exception.ReporterException;
-import dev.vality.anapi.v2.model.*;
+import dev.vality.anapi.v2.model.Report;
+import dev.vality.anapi.v2.model.ReportLink;
+import dev.vality.anapi.v2.model.SearchReports200Response;
import dev.vality.reporter.ReportRequest;
import dev.vality.reporter.ReportingSrv;
import dev.vality.reporter.StatReportRequest;
@@ -59,10 +61,10 @@ public Report getReport(long reportId) {
}
}
- public InlineResponse20014 getReports(StatReportRequest request) {
+ public SearchReports200Response getReports(StatReportRequest request) {
try {
var response = reporterClient.getReports(request);
- return new InlineResponse20014()
+ return new SearchReports200Response()
.result(response.getReports().stream()
.map(reporterResponseToReportConverter::convert)
.collect(Collectors.toList()))
diff --git a/src/main/java/dev/vality/anapi/v2/service/TokenKeeperService.java b/src/main/java/dev/vality/anapi/v2/service/TokenKeeperService.java
deleted file mode 100644
index 1acc7a8e..00000000
--- a/src/main/java/dev/vality/anapi/v2/service/TokenKeeperService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package dev.vality.anapi.v2.service;
-
-import dev.vality.anapi.v2.exception.TokenKeeperException;
-import dev.vality.token.keeper.AuthData;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
-import dev.vality.token.keeper.TokenSourceContext;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.http.HttpHeaders;
-import org.apache.thrift.TException;
-import org.springframework.stereotype.Service;
-import org.springframework.util.ObjectUtils;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import java.util.Optional;
-
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class TokenKeeperService {
-
- private static final String bearerPrefix = "Bearer ";
- private final TokenAuthenticatorSrv.Iface tokenKeeperClient;
-
- public AuthData getAuthData() {
- log.debug("Retrieving auth info");
- try {
- var token = getBearerToken();
- return tokenKeeperClient.authenticate(
- token.orElseThrow(() -> new TokenKeeperException("Token not found!")), new TokenSourceContext());
- } catch (TException e) {
- throw new TokenKeeperException("Error while call token keeper: ", e);
- }
- }
-
- private Optional getBearerToken() {
- var attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- if (ObjectUtils.isEmpty(attributes)
- || ObjectUtils.isEmpty(attributes.getRequest().getHeader(HttpHeaders.AUTHORIZATION))) {
- return Optional.empty();
- }
- String token = attributes.getRequest().getHeader(HttpHeaders.AUTHORIZATION).substring(bearerPrefix.length());
- return Optional.of(token);
- }
-
-}
diff --git a/src/main/java/dev/vality/anapi/v2/service/VortigonService.java b/src/main/java/dev/vality/anapi/v2/service/VortigonService.java
deleted file mode 100644
index 50de7e03..00000000
--- a/src/main/java/dev/vality/anapi/v2/service/VortigonService.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package dev.vality.anapi.v2.service;
-
-import dev.vality.anapi.v2.exception.BadRequestException;
-import dev.vality.anapi.v2.exception.VortigonException;
-import dev.vality.damsel.vortigon.PaymentInstitutionRealm;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.thrift.TException;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class VortigonService {
-
- private final VortigonServiceSrv.Iface vortigonClient;
-
- public List getShopIds(String partyId, String realm) {
- try {
- List shops = vortigonClient.getShopsIds(partyId, mapRealm(realm));
- log.info("Received shops from vortigon: {}", shops);
- return shops;
- } catch (TException e) {
- throw new VortigonException(String.format("Error while call vortigon, partyId=%s", partyId), e);
- }
- }
-
- private PaymentInstitutionRealm mapRealm(String realm) {
- try {
- return PaymentInstitutionRealm.valueOf(realm);
- } catch (IllegalArgumentException e) {
- throw new BadRequestException(String.format("Realm %s cannot be processed", realm));
- }
- }
-}
diff --git a/src/main/java/dev/vality/anapi/v2/util/ConverterUtil.java b/src/main/java/dev/vality/anapi/v2/util/ConverterUtil.java
index 91a75190..30e3ee8a 100644
--- a/src/main/java/dev/vality/anapi/v2/util/ConverterUtil.java
+++ b/src/main/java/dev/vality/anapi/v2/util/ConverterUtil.java
@@ -2,9 +2,9 @@
import dev.vality.geck.common.util.TypeUtil;
import dev.vality.magista.CommonSearchQueryParams;
+import jakarta.annotation.Nullable;
import lombok.experimental.UtilityClass;
-import javax.annotation.Nullable;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/dev/vality/anapi/v2/util/DeadlineUtil.java b/src/main/java/dev/vality/anapi/v2/util/DeadlineUtil.java
index e3fa4c0b..f3a002c7 100644
--- a/src/main/java/dev/vality/anapi/v2/util/DeadlineUtil.java
+++ b/src/main/java/dev/vality/anapi/v2/util/DeadlineUtil.java
@@ -1,9 +1,9 @@
package dev.vality.anapi.v2.util;
import dev.vality.anapi.v2.exception.DeadlineException;
+import jakarta.annotation.Nullable;
import lombok.experimental.UtilityClass;
-import javax.annotation.Nullable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/dev/vality/anapi/v2/util/JwtUtil.java b/src/main/java/dev/vality/anapi/v2/util/JwtUtil.java
deleted file mode 100644
index c61b2f2c..00000000
--- a/src/main/java/dev/vality/anapi/v2/util/JwtUtil.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package dev.vality.anapi.v2.util;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.experimental.UtilityClass;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-@Slf4j
-@UtilityClass
-public class JwtUtil {
-
- private static final ObjectMapper objectMapper = new ObjectMapper();
- private static final String subjectFieldName = "sub";
-
- public static Optional getSubject(String token) {
- try {
- String[] chunks = token.split("\\.");
- Base64.Decoder decoder = Base64.getUrlDecoder();
- String payload = new String(decoder.decode(chunks[1]));
- Map parsedPayload = objectMapper.readValue(payload, HashMap.class);
- if (parsedPayload.containsKey(subjectFieldName)) {
- return Optional.of(String.valueOf(parsedPayload.get(subjectFieldName)));
- }
- } catch (Exception e) {
- log.warn("Unable to parse jwt token while looking for subject: ", e);
- }
- return Optional.empty();
- }
-}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 302f7c73..94745cf0 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,24 +1,24 @@
server:
- port: '@server.port@'
+ port: ${server.port}
management:
server:
- port: '@management.port@'
- metrics:
- export:
- prometheus:
- enabled: false
+ port: ${management.port}
endpoint:
health:
show-details: always
metrics:
- enabled: true
+ access: unrestricted
prometheus:
- enabled: true
+ access: unrestricted
endpoints:
web:
exposure:
include: health,info,prometheus
+ prometheus:
+ metrics:
+ export:
+ enabled: false
service:
magista:
@@ -27,15 +27,12 @@ service:
analytics:
url: http://localhost:8022/change_it
networkTimeout: 5000
- vortigon:
+ dominant:
url: http://localhost:8022/change_it
networkTimeout: 5000
orgManager:
url: http://localhost:8022/change_it
networkTimeout: 5000
- tokenKeeper:
- url: http://localhost:8022/change_it
- networkTimeout: 5000
bouncer:
url: http://localhost:8022/change_it
networkTimeout: 10000
@@ -57,6 +54,17 @@ spring:
output:
ansi:
enabled: always
+ security:
+ oauth2:
+ resourceserver:
+ url: https://auth.domain
+ jwt:
+ realm: internal
+ issuer-uri: >
+ ${spring.security.oauth2.resourceserver.url}/auth/realms/
+ ${spring.security.oauth2.resourceserver.jwt.realm}
info:
version: '@project.version@'
stage: dev
+
+auth.enabled: true
diff --git a/src/test/java/dev/vality/anapi/v2/AnalyticsTest.java b/src/test/java/dev/vality/anapi/v2/AnalyticsTest.java
index 8df6814a..b653a248 100644
--- a/src/test/java/dev/vality/anapi/v2/AnalyticsTest.java
+++ b/src/test/java/dev/vality/anapi/v2/AnalyticsTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.AnalyticsUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
import dev.vality.damsel.analytics.AnalyticsServiceSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -36,18 +34,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class AnalyticsTest extends AbstractConfig {
+class AnalyticsTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
+ @MockitoBean
private AnalyticsServiceSrv.Iface analyticsClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -59,8 +55,7 @@ class AnalyticsTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{analyticsClient, vortigonClient,
- orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{analyticsClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -72,23 +67,21 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void getAveragePaymentRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(analyticsClient.getAveragePayment(any())).thenReturn(AnalyticsUtil.createAveragePaymentRequiredResponse());
mvc.perform(get("/lk/v2/analytics/payments/average")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getAnalyticsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(analyticsClient, times(1)).getAveragePayment(any());
@@ -97,23 +90,21 @@ void getAveragePaymentRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void getAveragePaymentAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(analyticsClient.getAveragePayment(any())).thenReturn(AnalyticsUtil.createAveragePaymentAllResponse());
mvc.perform(get("/lk/v2/analytics/payments/average")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getAnalyticsAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(analyticsClient, times(1)).getAveragePayment(any());
@@ -126,36 +117,34 @@ void getAveragePaymentRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/analytics/payments/average")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void getAveragePaymentRequestServerUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(analyticsClient.getAveragePayment(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/analytics/payments/average")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getAnalyticsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(analyticsClient, times(1)).getAveragePayment(any());
diff --git a/src/test/java/dev/vality/anapi/v2/ReportsTest.java b/src/test/java/dev/vality/anapi/v2/ReportsTest.java
index 25084afb..25da8a5d 100644
--- a/src/test/java/dev/vality/anapi/v2/ReportsTest.java
+++ b/src/test/java/dev/vality/anapi/v2/ReportsTest.java
@@ -1,12 +1,12 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
import dev.vality.reporter.ReportingSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -14,23 +14,21 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static dev.vality.anapi.v2.testutil.OpenApiUtil.getReportsRequiredParams;
import static dev.vality.anapi.v2.testutil.RandomUtil.randomInt;
import static dev.vality.anapi.v2.testutil.RandomUtil.randomIntegerAsString;
import static dev.vality.anapi.v2.testutil.ReporterUtil.createReport;
import static dev.vality.anapi.v2.testutil.ReporterUtil.createSearchReportsResponse;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -39,18 +37,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class ReportsTest extends AbstractConfig {
+class ReportsTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
+ @MockitoBean
private ReportingSrv.Iface reporterClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -62,8 +58,7 @@ class ReportsTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[] {reporterClient, vortigonClient, orgManagerClient,
- bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[] {reporterClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -77,20 +72,18 @@ public void clean() throws Exception {
void cancelReportRequestSuccess() {
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
int reportId = randomInt(1, 1000);
mvc.perform(post("/lk/v2/reports/{reportId}/cancel", reportId)
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(getReportsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isAccepted())
.andExpect(jsonPath("$").doesNotExist());
verify(orgManagerClient, times(1)).getUserContext(any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).cancelReport(reportId);
}
@@ -100,21 +93,19 @@ void cancelReportRequestSuccess() {
void cancelReportRequestServerUnavailable() {
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
int reportId = randomInt(1, 1000);
doThrow(new TException()).when(reporterClient).cancelReport(reportId);
mvc.perform(post("/lk/v2/reports/{reportId}/cancel", reportId)
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(getReportsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$").doesNotExist());
verify(orgManagerClient, times(1)).getUserContext(any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).cancelReport(reportId);
}
@@ -124,22 +115,20 @@ void cancelReportRequestServerUnavailable() {
void createReportRequestSuccess() {
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
long reportId = randomInt(1, 1000);
when(reporterClient.createReport(any(), any())).thenReturn(reportId);
when(reporterClient.getReport(reportId)).thenReturn(createReport(reportId));
mvc.perform(post("/lk/v2/reports")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getCreateReportRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$").exists());
verify(orgManagerClient, times(1)).getUserContext(any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).createReport(any(), any());
verify(reporterClient, times(1)).getReport(reportId);
@@ -150,22 +139,20 @@ void createReportRequestSuccess() {
void downloadUrlRequestSuccess() {
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
String reportId = randomIntegerAsString(1, 1000);
String fileId = randomIntegerAsString(1, 1000);
when(reporterClient.generatePresignedUrl(eq(fileId), any())).thenReturn("www.google.ru");
mvc.perform(get("/lk/v2/reports/{reportID}/files/{fileID}/download", reportId, fileId)
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getReportsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists());
verify(orgManagerClient, times(1)).getUserContext(any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).generatePresignedUrl(eq(fileId), notNull());
}
@@ -175,21 +162,19 @@ void downloadUrlRequestSuccess() {
void getReportRequestSuccess() {
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
long reportId = randomInt(1, 1000);
when(reporterClient.getReport(reportId)).thenReturn(createReport(reportId));
mvc.perform(get("/lk/v2/reports/{reportID}", reportId)
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getCreateReportRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists());
verify(orgManagerClient, times(1)).getUserContext(any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).getReport(reportId);
}
@@ -197,23 +182,21 @@ void getReportRequestSuccess() {
@Test
@SneakyThrows
void getSearchReportsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(reporterClient.getReports(any())).thenReturn(createSearchReportsResponse());
mvc.perform(get("/lk/v2/reports")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchReportsRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(reporterClient, times(1)).getReports(notNull());
@@ -226,10 +209,10 @@ void getSearchReportsRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/reports")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isBadRequest())
diff --git a/src/test/java/dev/vality/anapi/v2/SearchChargebacksTest.java b/src/test/java/dev/vality/anapi/v2/SearchChargebacksTest.java
index 8252aeb1..cf5e457b 100644
--- a/src/test/java/dev/vality/anapi/v2/SearchChargebacksTest.java
+++ b/src/test/java/dev/vality/anapi/v2/SearchChargebacksTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -37,18 +35,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class SearchChargebacksTest extends AbstractConfig {
+class SearchChargebacksTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
+ @MockitoBean
public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -60,7 +56,7 @@ class SearchChargebacksTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{magistaClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -72,23 +68,21 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void searchChargebacksRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchChargebacks(any())).thenReturn(MagistaUtil.createSearchChargebackRequiredResponse());
mvc.perform(get("/lk/v2/chargebacks")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchChargebacks(any());
@@ -97,23 +91,21 @@ void searchChargebacksRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void searchChargebacksAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchChargebacks(any())).thenReturn(MagistaUtil.createSearchChargebackAllResponse());
mvc.perform(get("/lk/v2/chargebacks")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchChargebackAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchChargebacks(any());
@@ -126,36 +118,34 @@ void searchChargebacksRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/chargebacks")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void searchChargebacksRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchPayments(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/chargebacks")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchChargebacks(any());
diff --git a/src/test/java/dev/vality/anapi/v2/SearchInvoiceTemplatesTest.java b/src/test/java/dev/vality/anapi/v2/SearchInvoiceTemplatesTest.java
index 7e76009d..a63eb41d 100644
--- a/src/test/java/dev/vality/anapi/v2/SearchInvoiceTemplatesTest.java
+++ b/src/test/java/dev/vality/anapi/v2/SearchInvoiceTemplatesTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -36,18 +34,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class SearchInvoiceTemplatesTest extends AbstractConfig {
+class SearchInvoiceTemplatesTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
+ @MockitoBean
public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -59,7 +55,7 @@ class SearchInvoiceTemplatesTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{magistaClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -71,24 +67,22 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void searchInvoiceTemplatesRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoiceTemplates(any())).thenReturn(
MagistaUtil.createSearchInvoiceTemplateRequiredResponse());
mvc.perform(get("/lk/v2/invoice-templates")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoiceTemplates(any());
@@ -97,24 +91,22 @@ void searchInvoiceTemplatesRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void searchInvoiceTemplatesAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoiceTemplates(any())).thenReturn(
MagistaUtil.createSearchInvoiceTemplateAllResponse());
mvc.perform(get("/lk/v2/invoice-templates")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchInvoiceAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoiceTemplates(any());
@@ -127,36 +119,34 @@ void searchInvoiceTemplatesRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/invoice-templates")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void searchInvoiceTemplatesRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoiceTemplates(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/invoice-templates")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoiceTemplates(any());
diff --git a/src/test/java/dev/vality/anapi/v2/SearchInvoicesTest.java b/src/test/java/dev/vality/anapi/v2/SearchInvoicesTest.java
index 3cc9822b..662cb67a 100644
--- a/src/test/java/dev/vality/anapi/v2/SearchInvoicesTest.java
+++ b/src/test/java/dev/vality/anapi/v2/SearchInvoicesTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -36,17 +34,15 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class SearchInvoicesTest extends AbstractConfig {
+class SearchInvoicesTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
+ @MockitoBean
public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
@Autowired
@@ -59,7 +55,7 @@ class SearchInvoicesTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{magistaClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -71,23 +67,21 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void searchInvoicesRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoices(any())).thenReturn(MagistaUtil.createSearchInvoiceRequiredResponse());
mvc.perform(get("/lk/v2/invoices")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoices(any());
@@ -96,23 +90,21 @@ void searchInvoicesRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void searchInvoicesAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoices(any())).thenReturn(MagistaUtil.createSearchInvoiceAllResponse());
mvc.perform(get("/lk/v2/invoices")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchInvoiceAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoices(any());
@@ -125,36 +117,34 @@ void searchInvoicesRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/invoices")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void searchInvoicesRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchInvoices(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/invoices")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchInvoices(any());
diff --git a/src/test/java/dev/vality/anapi/v2/SearchPaymentsTest.java b/src/test/java/dev/vality/anapi/v2/SearchPaymentsTest.java
index d9285c49..99ca469b 100644
--- a/src/test/java/dev/vality/anapi/v2/SearchPaymentsTest.java
+++ b/src/test/java/dev/vality/anapi/v2/SearchPaymentsTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -36,18 +34,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class SearchPaymentsTest extends AbstractConfig {
+class SearchPaymentsTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
+ @MockitoBean
public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -59,7 +55,7 @@ class SearchPaymentsTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{magistaClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -71,23 +67,21 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void searchPaymentsRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchPayments(any())).thenReturn(MagistaUtil.createSearchPaymentRequiredResponse());
mvc.perform(get("/lk/v2/payments")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchPayments(any());
@@ -96,23 +90,21 @@ void searchPaymentsRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void searchPaymentsAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchPayments(any())).thenReturn(MagistaUtil.createSearchPaymentAllResponse());
mvc.perform(get("/lk/v2/payments")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchPaymentAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchPayments(any());
@@ -125,36 +117,34 @@ void searchPaymentsRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/payments")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void searchPaymentsRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchPayments(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/payments")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchPayments(any());
diff --git a/src/test/java/dev/vality/anapi/v2/SearchPayoutsTest.java b/src/test/java/dev/vality/anapi/v2/SearchPayoutsTest.java
deleted file mode 100644
index 0d05e881..00000000
--- a/src/test/java/dev/vality/anapi/v2/SearchPayoutsTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package dev.vality.anapi.v2;
-
-import dev.vality.anapi.v2.config.AbstractConfig;
-import dev.vality.anapi.v2.model.DefaultLogicError;
-import dev.vality.anapi.v2.testutil.MagistaUtil;
-import dev.vality.anapi.v2.testutil.OpenApiUtil;
-import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
-import dev.vality.magista.MerchantStatisticsServiceSrv;
-import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
-import lombok.SneakyThrows;
-import org.apache.thrift.TException;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.MockitoAnnotations;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.util.MultiValueMap;
-
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-import java.util.List;
-
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-class SearchPayoutsTest extends AbstractConfig {
-
- @MockBean
- public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
- public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
- public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
-
- @Autowired
- private MockMvc mvc;
-
- private AutoCloseable mocks;
-
- private Object[] preparedMocks;
-
- @BeforeEach
- public void init() {
- mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
- }
-
- @AfterEach
- public void clean() throws Exception {
- verifyNoMoreInteractions(preparedMocks);
- mocks.close();
- }
-
- @Test
- @SneakyThrows
- void searchPayoutsRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
- when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
- when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(magistaClient.searchPayouts(any())).thenReturn(MagistaUtil.createSearchPayoutRequiredResponse());
- mvc.perform(get("/lk/v2/payouts")
- .header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
- .header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
- .params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
- .content(""))
- .andDo(print())
- .andExpect(status().is2xxSuccessful())
- .andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
- verify(orgManagerClient, times(1)).getUserContext(any());
- verify(bouncerClient, times(1)).judge(any(), any());
- verify(magistaClient, times(1)).searchPayouts(any());
- }
-
- @Test
- @SneakyThrows
- void searchPayoutsAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
- when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
- when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(magistaClient.searchPayouts(any())).thenReturn(MagistaUtil.createSearchPayoutAllResponse());
- mvc.perform(get("/lk/v2/payouts")
- .header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
- .header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
- .params(OpenApiUtil.getSearchPayoutAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
- .content(""))
- .andDo(print())
- .andExpect(status().is2xxSuccessful())
- .andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
- verify(orgManagerClient, times(1)).getUserContext(any());
- verify(bouncerClient, times(1)).judge(any(), any());
- verify(magistaClient, times(1)).searchPayouts(any());
- }
-
- @Test
- @SneakyThrows
- void searchPayoutsRequestInvalid() {
- MultiValueMap params = OpenApiUtil.getSearchRequiredParams();
- params.remove("partyID");
- mvc.perform(get("/lk/v2/payouts")
- .header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
- .header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
- .params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
- .content(""))
- .andDo(print())
- .andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
- .andExpect(jsonPath("$.message").isNotEmpty());
- }
-
- @Test
- @SneakyThrows
- void searchPayoutsRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
- when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
- when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
- when(magistaClient.searchPayouts(any())).thenThrow(TException.class);
- mvc.perform(get("/lk/v2/payouts")
- .header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
- .header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
- .params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
- .content(""))
- .andDo(print())
- .andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
- verify(orgManagerClient, times(1)).getUserContext(any());
- verify(bouncerClient, times(1)).judge(any(), any());
- verify(magistaClient, times(1)).searchPayouts(any());
- }
-}
diff --git a/src/test/java/dev/vality/anapi/v2/SearchRefundsTest.java b/src/test/java/dev/vality/anapi/v2/SearchRefundsTest.java
index d52996de..eec3525e 100644
--- a/src/test/java/dev/vality/anapi/v2/SearchRefundsTest.java
+++ b/src/test/java/dev/vality/anapi/v2/SearchRefundsTest.java
@@ -1,14 +1,14 @@
package dev.vality.anapi.v2;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.magista.MerchantStatisticsServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import lombok.SneakyThrows;
import org.apache.thrift.TException;
import org.junit.jupiter.api.AfterEach;
@@ -16,8 +16,8 @@
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -25,10 +25,8 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createContextFragment;
+import static dev.vality.anapi.v2.testutil.MagistaUtil.createJudgementAllowed;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -36,18 +34,16 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class SearchRefundsTest extends AbstractConfig {
+class SearchRefundsTest extends AbstractKeycloakOpenIdAsWiremockConfig {
- @MockBean
+ @MockitoBean
public MerchantStatisticsServiceSrv.Iface magistaClient;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
@Autowired
private MockMvc mvc;
@@ -59,7 +55,7 @@ class SearchRefundsTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{magistaClient, vortigonClient, orgManagerClient, bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{magistaClient, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -71,23 +67,21 @@ public void clean() throws Exception {
@Test
@SneakyThrows
void searchRefundsRequiredParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchRefunds(any())).thenReturn(MagistaUtil.createSearchRefundRequiredResponse());
mvc.perform(get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchRefunds(any());
@@ -96,23 +90,21 @@ void searchRefundsRequiredParamsRequestSuccess() {
@Test
@SneakyThrows
void searchRefundsAllParamsRequestSuccess() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchRefunds(any())).thenReturn(MagistaUtil.createSearchRefundAllResponse());
mvc.perform(get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRefundAllParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("$").exists());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchRefunds(any());
@@ -125,36 +117,34 @@ void searchRefundsRequestInvalid() {
params.remove("partyID");
mvc.perform(get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is4xxClientError())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
@SneakyThrows
void searchRefundsRequestMagistaUnavailable() {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
when(magistaClient.searchRefunds(any())).thenThrow(TException.class);
mvc.perform(get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().is5xxServerError());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(magistaClient, times(1)).searchRefunds(any());
diff --git a/src/test/java/dev/vality/anapi/v2/auth/JwtTokenTestConfiguration.java b/src/test/java/dev/vality/anapi/v2/auth/JwtTokenTestConfiguration.java
index d9166329..f56da090 100644
--- a/src/test/java/dev/vality/anapi/v2/auth/JwtTokenTestConfiguration.java
+++ b/src/test/java/dev/vality/anapi/v2/auth/JwtTokenTestConfiguration.java
@@ -3,37 +3,17 @@
import dev.vality.anapi.v2.auth.utils.JwtTokenBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.core.io.ClassPathResource;
-import java.io.IOException;
-import java.security.*;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-import java.util.Properties;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
@Configuration
public class JwtTokenTestConfiguration {
- @Bean
- public static PropertySourcesPlaceholderConfigurer properties(KeyPair keyPair)
- throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
- KeyFactory fact = KeyFactory.getInstance("RSA");
- X509EncodedKeySpec spec = fact.getKeySpec(keyPair.getPublic(), X509EncodedKeySpec.class);
- String publicKey = Base64.getEncoder().encodeToString(spec.getEncoded());
- PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
- Properties properties = new Properties();
- properties.load(new ClassPathResource("application.yml").getInputStream());
- properties.setProperty("keycloak.realm-public-key", publicKey);
- pspc.setProperties(properties);
- pspc.setLocalOverride(true);
- return pspc;
- }
-
@Bean
public JwtTokenBuilder jwtTokenBuilder(KeyPair keyPair) {
- return new JwtTokenBuilder(keyPair.getPrivate());
+ return new JwtTokenBuilder(keyPair);
}
@Bean
diff --git a/src/test/java/dev/vality/anapi/v2/auth/KeycloakOpenIdTestConfiguration.java b/src/test/java/dev/vality/anapi/v2/auth/KeycloakOpenIdTestConfiguration.java
index 534454ea..190b51ba 100644
--- a/src/test/java/dev/vality/anapi/v2/auth/KeycloakOpenIdTestConfiguration.java
+++ b/src/test/java/dev/vality/anapi/v2/auth/KeycloakOpenIdTestConfiguration.java
@@ -2,6 +2,7 @@
import dev.vality.anapi.v2.auth.utils.JwtTokenBuilder;
import dev.vality.anapi.v2.auth.utils.KeycloakOpenIdStub;
+import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -10,7 +11,11 @@
public class KeycloakOpenIdTestConfiguration {
@Bean
- public KeycloakOpenIdStub keycloakOpenIdStub(JwtTokenBuilder jwtTokenBuilder) {
- return new KeycloakOpenIdStub(jwtTokenBuilder);
+ @SneakyThrows
+ public KeycloakOpenIdStub keycloakOpenIdStub(
+ @Value("${spring.security.oauth2.resourceserver.url}") String keycloakAuthServerUrl,
+ @Value("${spring.security.oauth2.resourceserver.jwt.realm}") String keycloakRealm,
+ JwtTokenBuilder jwtTokenBuilder) {
+ return new KeycloakOpenIdStub(keycloakAuthServerUrl + "/auth", keycloakRealm, jwtTokenBuilder);
}
}
diff --git a/src/test/java/dev/vality/anapi/v2/auth/utils/JwtTokenBuilder.java b/src/test/java/dev/vality/anapi/v2/auth/utils/JwtTokenBuilder.java
index f0be4b61..efd8fbc0 100644
--- a/src/test/java/dev/vality/anapi/v2/auth/utils/JwtTokenBuilder.java
+++ b/src/test/java/dev/vality/anapi/v2/auth/utils/JwtTokenBuilder.java
@@ -1,12 +1,14 @@
package dev.vality.anapi.v2.auth.utils;
import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.SneakyThrows;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import java.security.KeyPair;
import java.security.PrivateKey;
+import java.security.PublicKey;
import java.time.Instant;
import java.util.UUID;
@@ -24,15 +26,18 @@ public class JwtTokenBuilder {
private final PrivateKey privateKey;
- public JwtTokenBuilder(PrivateKey privateKey) {
- this(UUID.randomUUID().toString(), DEFAULT_USERNAME, DEFAULT_EMAIL, privateKey);
+ private final PublicKey publicKey;
+
+ public JwtTokenBuilder(KeyPair keyPair) {
+ this(UUID.randomUUID().toString(), DEFAULT_USERNAME, DEFAULT_EMAIL, keyPair.getPrivate(), keyPair.getPublic());
}
- public JwtTokenBuilder(String userId, String username, String email, PrivateKey privateKey) {
+ public JwtTokenBuilder(String userId, String username, String email, PrivateKey privateKey, PublicKey publicKey) {
this.userId = userId;
this.username = username;
this.email = email;
this.privateKey = privateKey;
+ this.publicKey = publicKey;
}
public String generateJwtWithRoles(String issuer, String... roles) {
@@ -42,12 +47,16 @@ public String generateJwtWithRoles(String issuer, String... roles) {
}
public String generateJwtWithRoles(long iat, long exp, String issuer, String... roles) {
+ return generateJwtWithRoles(privateKey, iat, exp, issuer, roles);
+ }
+
+ public String generateJwtWithRoles(PrivateKey privateKey, long iat, long exp, String issuer, String... roles) {
String payload;
try {
payload = new JSONObject()
.put("jti", UUID.randomUUID().toString())
.put("exp", exp)
- .put("nbf", "0")
+ .put("nbf", 0L)
.put("iat", iat)
.put("iss", issuer)
.put("aud", "private-api")
@@ -63,11 +72,20 @@ public String generateJwtWithRoles(long iat, long exp, String issuer, String...
throw new RuntimeException(e);
}
- String jwt = Jwts.builder()
- .setPayload(payload)
- .signWith(SignatureAlgorithm.RS256, privateKey)
+ return Jwts.builder()
+ .content(payload)
+ .signWith(privateKey, Jwts.SIG.RS256)
.compact();
- return jwt;
+ }
+
+ @SneakyThrows
+ public PublicKey getPublicKey() {
+ return this.publicKey;
+ }
+
+ @SneakyThrows
+ public PrivateKey getPrivateKey() {
+ return this.privateKey;
}
}
diff --git a/src/test/java/dev/vality/anapi/v2/auth/utils/KeycloakOpenIdStub.java b/src/test/java/dev/vality/anapi/v2/auth/utils/KeycloakOpenIdStub.java
index 0eeece9e..2cc136b8 100644
--- a/src/test/java/dev/vality/anapi/v2/auth/utils/KeycloakOpenIdStub.java
+++ b/src/test/java/dev/vality/anapi/v2/auth/utils/KeycloakOpenIdStub.java
@@ -1,16 +1,93 @@
package dev.vality.anapi.v2.auth.utils;
+import dev.vality.anapi.v2.testutil.GenerateSelfSigned;
+import dev.vality.anapi.v2.testutil.PublicKeyUtil;
+import lombok.SneakyThrows;
+
+import java.security.KeyPair;
+import java.util.Base64;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+
public class KeycloakOpenIdStub {
+ private final String keycloakRealm;
private final String issuer;
+ private final String openidConfig;
+ private final String jwkConfig;
private final JwtTokenBuilder jwtTokenBuilder;
- public KeycloakOpenIdStub(JwtTokenBuilder jwtTokenBuilder) {
+ @SneakyThrows
+ public KeycloakOpenIdStub(String keycloakAuthServerUrl, String keycloakRealm, JwtTokenBuilder jwtTokenBuilder) {
+ this.keycloakRealm = keycloakRealm;
this.jwtTokenBuilder = jwtTokenBuilder;
- this.issuer = "test/realms/test";
+ this.issuer = keycloakAuthServerUrl + "/realms/" + keycloakRealm;
+ this.openidConfig = "{\n" +
+ " \"issuer\": \"" + issuer + "\",\n" +
+ " \"authorization_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/auth\",\n" +
+ " \"token_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/token\",\n" +
+ " \"token_introspection_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/token/introspect\",\n" +
+ " \"userinfo_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/userinfo\",\n" +
+ " \"end_session_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/logout\",\n" +
+ " \"jwks_uri\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/certs\",\n" +
+ " \"check_session_iframe\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/login-status-iframe.html\",\n" +
+ " \"registration_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/clients-registrations/openid-connect\",\n" +
+ " \"introspection_endpoint\": \"" + keycloakAuthServerUrl + "/realms/" + keycloakRealm +
+ "/protocol/openid-connect/token/introspect\"\n" +
+ "}";
+ this.jwkConfig = """
+ {
+ "keys": [
+ {
+ "alg": "RS256",
+ "e": "%s",
+ "kid": "BZdHlAdlt3F1XatlYtZg3f1Cfpk5IpEINuIgviUW59s",
+ "kty": "RSA",
+ "n": "%s",
+ "use": "sig",
+ "x5c": [
+ "%s"
+ ],
+ "x5t": "9APiqOME1mVmyv8hak6HB_PTezA",
+ "x5t#S256": "kweH93DnMHKD_NrAZF-mgpAM3Njv_8-oxaDAzki4t48"
+ }
+ ]
+ }
+ """.formatted(
+ PublicKeyUtil.getExponent(jwtTokenBuilder.getPublicKey()),
+ PublicKeyUtil.getModulus(jwtTokenBuilder.getPublicKey()),
+ Base64.getEncoder().encodeToString(
+ GenerateSelfSigned.generateCertificate(new KeyPair(jwtTokenBuilder.getPublicKey(),
+ jwtTokenBuilder.getPrivateKey())).getEncoded()));
+ }
+
+ public void givenStub() {
+ stubFor(get(urlEqualTo(String.format("/auth/realms/%s/.well-known/openid-configuration", keycloakRealm)))
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody(openidConfig)
+ )
+ );
+ stubFor(get(urlEqualTo(String.format("/auth/realms/%s/protocol/openid-connect/certs", keycloakRealm)))
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody(jwkConfig)
+ ));
}
public String generateJwt(String... roles) {
return jwtTokenBuilder.generateJwtWithRoles(issuer, roles);
}
+
+ public String generateJwt(long iat, long exp, String... roles) {
+ return jwtTokenBuilder.generateJwtWithRoles(iat, exp, issuer, roles);
+ }
}
diff --git a/src/test/java/dev/vality/anapi/v2/config/AbstractConfig.java b/src/test/java/dev/vality/anapi/v2/config/AbstractKeycloakOpenIdAsWiremockConfig.java
similarity index 56%
rename from src/test/java/dev/vality/anapi/v2/config/AbstractConfig.java
rename to src/test/java/dev/vality/anapi/v2/config/AbstractKeycloakOpenIdAsWiremockConfig.java
index ba4cef9e..d5228228 100644
--- a/src/test/java/dev/vality/anapi/v2/config/AbstractConfig.java
+++ b/src/test/java/dev/vality/anapi/v2/config/AbstractKeycloakOpenIdAsWiremockConfig.java
@@ -2,6 +2,7 @@
import dev.vality.anapi.v2.AnapiV2Application;
import dev.vality.anapi.v2.auth.utils.KeycloakOpenIdStub;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
@@ -9,18 +10,28 @@
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+@SuppressWarnings("LineLength")
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = {AnapiV2Application.class},
- properties = {"wiremock.server.baseUrl=http://localhost:${wiremock.server.port}"})
+ properties = {
+ "wiremock.server.baseUrl=http://localhost:${wiremock.server.port}",
+ "spring.security.oauth2.resourceserver.url=http://localhost:${wiremock.server.port}",
+ "spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:${wiremock.server.port}/auth/realms/" +
+ "${spring.security.oauth2.resourceserver.jwt.realm}"})
@AutoConfigureMockMvc
@AutoConfigureWireMock(port = 0)
@ExtendWith(SpringExtension.class)
-public abstract class AbstractConfig {
+public abstract class AbstractKeycloakOpenIdAsWiremockConfig {
@Autowired
private KeycloakOpenIdStub keycloakOpenIdStub;
+ @BeforeAll
+ public static void setUp(@Autowired KeycloakOpenIdStub keycloakOpenIdStub) throws Exception {
+ keycloakOpenIdStub.givenStub();
+ }
+
protected String generateSimpleJwt() {
return keycloakOpenIdStub.generateJwt();
}
diff --git a/src/test/java/dev/vality/anapi/v2/controller/ErrorControllerTest.java b/src/test/java/dev/vality/anapi/v2/controller/ErrorControllerTest.java
index 8167e534..c572af58 100644
--- a/src/test/java/dev/vality/anapi/v2/controller/ErrorControllerTest.java
+++ b/src/test/java/dev/vality/anapi/v2/controller/ErrorControllerTest.java
@@ -1,22 +1,23 @@
package dev.vality.anapi.v2.controller;
-import dev.vality.anapi.v2.config.AbstractConfig;
+import dev.vality.anapi.v2.config.AbstractKeycloakOpenIdAsWiremockConfig;
import dev.vality.anapi.v2.converter.magista.request.ParamsToRefundSearchQueryConverter;
import dev.vality.anapi.v2.exception.BadRequestException;
import dev.vality.anapi.v2.model.DefaultLogicError;
+import dev.vality.anapi.v2.service.DominantService;
+import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.OpenApiUtil;
+import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.bouncer.decisions.ArbiterSrv;
-import dev.vality.damsel.vortigon.VortigonServiceSrv;
import dev.vality.orgmanagement.AuthContextProviderSrv;
-import dev.vality.token.keeper.TokenAuthenticatorSrv;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.MultiValueMap;
@@ -24,10 +25,6 @@
import java.time.temporal.ChronoUnit;
import java.util.List;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createJudgementAllowed;
-import static dev.vality.anapi.v2.testutil.TokenKeeperUtil.createAuthData;
-import static java.util.UUID.randomUUID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -35,20 +32,18 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-class ErrorControllerTest extends AbstractConfig {
+class ErrorControllerTest extends AbstractKeycloakOpenIdAsWiremockConfig {
@Autowired
private MockMvc mockMvc;
- @MockBean
+ @MockitoBean
private ParamsToRefundSearchQueryConverter refundSearchConverter;
- @MockBean
- public VortigonServiceSrv.Iface vortigonClient;
- @MockBean
+ @MockitoBean
+ public DominantService dominantService;
+ @MockitoBean
public AuthContextProviderSrv.Iface orgManagerClient;
- @MockBean
+ @MockitoBean
public ArbiterSrv.Iface bouncerClient;
- @MockBean
- public TokenAuthenticatorSrv.Iface tokenKeeperClient;
private AutoCloseable mocks;
@@ -57,8 +52,7 @@ class ErrorControllerTest extends AbstractConfig {
@BeforeEach
public void init() {
mocks = MockitoAnnotations.openMocks(this);
- preparedMocks = new Object[]{refundSearchConverter, vortigonClient, orgManagerClient,
- bouncerClient, tokenKeeperClient};
+ preparedMocks = new Object[]{refundSearchConverter, dominantService, orgManagerClient, bouncerClient};
}
@AfterEach
@@ -75,23 +69,22 @@ void testConstraintViolationException() throws Exception {
mockMvc.perform(
get("/lk/v2/payments")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isBadRequest())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
void testBadRequestException() throws Exception {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
- when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
- when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
+ when(orgManagerClient.getUserContext(any())).thenReturn(MagistaUtil.createContextFragment());
+ when(bouncerClient.judge(any(), any())).thenReturn(MagistaUtil.createJudgementAllowed());
String message = "Error!";
Mockito.doThrow(new BadRequestException(message)).when(refundSearchConverter)
.convert(any(), any(), any(), any(),
@@ -103,17 +96,16 @@ void testBadRequestException() throws Exception {
mockMvc.perform(
get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isBadRequest())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").value(message));
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(refundSearchConverter, times(1))
@@ -131,14 +123,14 @@ void testMissingServletRequestParameterException() throws Exception {
mockMvc.perform(
get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isBadRequest())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDREQUEST.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_REQUEST.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@@ -147,23 +139,22 @@ void testDeadlineException() throws Exception {
mockMvc.perform(
get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", "fail")
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isBadRequest())
- .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALIDDEADLINE.getValue()))
+ .andExpect(jsonPath("$.code").value(DefaultLogicError.CodeEnum.INVALID_DEADLINE.getValue()))
.andExpect(jsonPath("$.message").isNotEmpty());
}
@Test
void testInternalException() throws Exception {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
- when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData(generateSimpleJwt()));
- when(orgManagerClient.getUserContext(any())).thenReturn(createContextFragment());
- when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
+ when(dominantService.getShopIds(any(), any())).thenReturn(List.of("1", "2", "3"));
+ when(orgManagerClient.getUserContext(any())).thenReturn(MagistaUtil.createContextFragment());
+ when(bouncerClient.judge(any(), any())).thenReturn(MagistaUtil.createJudgementAllowed());
doThrow(new RuntimeException()).when(refundSearchConverter)
.convert(any(), any(), any(), any(),
any(), any(), any(), any(),
@@ -174,16 +165,15 @@ void testInternalException() throws Exception {
mockMvc.perform(
get("/lk/v2/refunds")
.header("Authorization", "Bearer " + generateSimpleJwt())
- .header("X-Request-ID", randomUUID())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
.header("X-Request-Deadline", Instant.now().plus(1, ChronoUnit.DAYS).toString())
.params(params)
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$").doesNotExist());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
- verify(tokenKeeperClient, times(1)).authenticate(any(), any());
+ verify(dominantService, times(1)).getShopIds(any(), any());
verify(orgManagerClient, times(1)).getUserContext(any());
verify(bouncerClient, times(1)).judge(any(), any());
verify(refundSearchConverter, times(1))
@@ -194,19 +184,16 @@ void testInternalException() throws Exception {
@Test
void testUnauthorizedException() throws Exception {
- when(vortigonClient.getShopsIds(any(), any())).thenReturn(List.of("1", "2", "3"));
mockMvc.perform(
get("/lk/v2/refunds")
- .header("X-Request-ID", randomUUID())
- .header("X-Request-Deadline",
- Instant.now().plus(1, ChronoUnit.DAYS).toString())
+ .header("X-Request-ID", RandomUtil.randomRequestId())
+ .header("X-Request-Deadline", "fail")
.params(OpenApiUtil.getSearchRequiredParams())
- .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .contentType(MediaType.APPLICATION_JSON)
.content(""))
.andDo(print())
- .andExpect(status().isForbidden())
+ .andExpect(status().isUnauthorized())
.andExpect(jsonPath("$").doesNotExist());
- verify(vortigonClient, times(1)).getShopsIds(any(), any());
}
}
diff --git a/src/test/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverterTest.java b/src/test/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverterTest.java
deleted file mode 100644
index c18b69b1..00000000
--- a/src/test/java/dev/vality/anapi/v2/converter/magista/request/ParamsToPayoutSearchQueryConverterTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package dev.vality.anapi.v2.converter.magista.request;
-
-import dev.vality.anapi.v2.exception.BadRequestException;
-import dev.vality.magista.PayoutSearchQuery;
-import dev.vality.magista.PayoutToolType;
-import org.junit.jupiter.api.Test;
-
-import java.time.OffsetDateTime;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class ParamsToPayoutSearchQueryConverterTest {
-
- private static final ParamsToPayoutSearchQueryConverter converter = new ParamsToPayoutSearchQueryConverter();
-
- @Test
- void convert() {
- PayoutSearchQuery query = converter.convert("1",
- OffsetDateTime.MIN,
- OffsetDateTime.MAX,
- 10,
- List.of("1", "2", "3"),
- "1",
- "Wallet",
- "test");
- assertNotNull(query);
- }
-
- @Test
- void mapPayoutToolType() {
- assertEquals(PayoutToolType.payout_account, converter.mapPayoutToolType("PayoutAccount"));
- assertEquals(PayoutToolType.wallet, converter.mapPayoutToolType("Wallet"));
- assertEquals(PayoutToolType.payment_institution_account,
- converter.mapPayoutToolType("PaymentInstitutionAccount"));
- assertThrows(BadRequestException.class, () -> converter.mapPayoutToolType("unexpected"));
- }
-}
\ No newline at end of file
diff --git a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverterTest.java b/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverterTest.java
index 9603baba..b89e111e 100644
--- a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverterTest.java
+++ b/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPaymentToPaymentSearchResultConverterTest.java
@@ -4,18 +4,18 @@
import dev.vality.anapi.v2.testutil.MagistaUtil;
import dev.vality.anapi.v2.testutil.RandomUtil;
import dev.vality.anapi.v2.util.MaskUtil;
+import dev.vality.damsel.domain.*;
import dev.vality.damsel.domain.ClientInfo;
import dev.vality.damsel.domain.ContactInfo;
import dev.vality.damsel.domain.InvoicePaymentStatus;
import dev.vality.damsel.domain.PaymentResourcePayer;
import dev.vality.damsel.domain.RecurrentPayer;
-import dev.vality.damsel.domain.*;
import dev.vality.geck.common.util.TypeUtil;
+import dev.vality.magista.*;
import dev.vality.magista.CustomerPayer;
import dev.vality.magista.InvoicePaymentFlow;
import dev.vality.magista.InvoicePaymentFlowInstant;
import dev.vality.magista.Payer;
-import dev.vality.magista.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -44,7 +44,7 @@ void convert() {
() -> assertEquals(magistaPayment.getCurrencySymbolicCode(), result.getCurrency()),
() -> assertEquals(magistaPayment.getExternalId(), result.getExternalID()),
() -> assertEquals(magistaPayment.getFee(), result.getFee()),
- () -> assertEquals(PaymentFlow.TypeEnum.PAYMENTFLOWINSTANT, result.getFlow().getType()),
+ () -> assertEquals(PaymentFlow.TypeEnum.PAYMENT_FLOW_INSTANT, result.getFlow().getType()),
() -> assertEquals(magistaPayment.getStatusChangedAt(), result.getStatusChangedAt().toString()),
() -> assertEquals(magistaPayment.getId(), result.getId()),
() -> assertEquals(magistaPayment.getInvoiceId(), result.getInvoiceID()),
@@ -104,9 +104,9 @@ void mapPayer() {
assertAll(
() -> assertEquals("1111", paymentResourcePayer.getPaymentToolToken()),
() -> assertEquals("1111", paymentResourcePayer.getPaymentSession()),
- () -> assertEquals("print", paymentResourcePayer.getClientInfo().get().getFingerprint()),
- () -> assertTrue(paymentResourcePayer.getClientInfo().isPresent()),
- () -> assertEquals("127.0.0.1", paymentResourcePayer.getClientInfo().get().getIp()),
+ () -> assertEquals("print", paymentResourcePayer.getClientInfo().getFingerprint()),
+ () -> assertNotNull(paymentResourcePayer.getClientInfo()),
+ () -> assertEquals("127.0.0.1", paymentResourcePayer.getClientInfo().getIp()),
() -> assertEquals("mail@mail.com", paymentResourcePayer.getContactInfo().getEmail()),
() -> assertEquals("88005553535", paymentResourcePayer.getContactInfo().getPhoneNumber()),
() -> assertEquals("1234", resourcePayerPaymentToolDetails.getBin()),
@@ -170,12 +170,12 @@ void mapStatus() {
void mapFlow() {
InvoicePaymentFlow flow = InvoicePaymentFlow.instant(new InvoicePaymentFlowInstant());
PaymentFlow instantFlow = converter.mapFlow(flow);
- assertEquals(PaymentFlow.TypeEnum.PAYMENTFLOWINSTANT, instantFlow.getType());
+ assertEquals(PaymentFlow.TypeEnum.PAYMENT_FLOW_INSTANT, instantFlow.getType());
InvoicePaymentFlow magistaFlow = MagistaUtil.createInvoicePaymentFlowHold();
var holdFlow = (PaymentFlowHold) converter.mapFlow(magistaFlow);
assertAll(
- () -> assertEquals(PaymentFlow.TypeEnum.PAYMENTFLOWHOLD, holdFlow.getType()),
+ () -> assertEquals(PaymentFlow.TypeEnum.PAYMENT_FLOW_HOLD, holdFlow.getType()),
() -> assertEquals(magistaFlow.getHold().getHeldUntil(), holdFlow.getHeldUntil().toString()),
() -> assertEquals(magistaFlow.getHold().getOnHoldExpiration().name(),
holdFlow.getOnHoldExpiration().getValue())
diff --git a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverterTest.java b/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverterTest.java
deleted file mode 100644
index 24266ed6..00000000
--- a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatPayoutToPayoutConverterTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-package dev.vality.anapi.v2.converter.magista.response;
-
-import dev.vality.anapi.v2.model.*;
-import dev.vality.anapi.v2.testutil.MagistaUtil;
-import dev.vality.anapi.v2.testutil.RandomUtil;
-import dev.vality.damsel.domain.InternationalBankAccount;
-import dev.vality.damsel.domain.InternationalBankDetails;
-import dev.vality.damsel.domain.*;
-import dev.vality.magista.*;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class StatPayoutToPayoutConverterTest {
-
- private static final StatPayoutToPayoutConverter converter = new StatPayoutToPayoutConverter();
-
- @Test
- void convert() {
- StatPayoutResponse magistaResponse = MagistaUtil.createSearchPayoutAllResponse();
- StatPayout magistaPayout = magistaResponse.getPayouts().get(0);
- Payout result = converter.convert(magistaPayout);
- assertAll(
- () -> assertEquals(magistaPayout.getAmount(), result.getAmount()),
- () -> assertEquals(magistaPayout.getCreatedAt(), result.getCreatedAt().toString()),
- () -> assertEquals(magistaPayout.getCurrencySymbolicCode(), result.getCurrency()),
- () -> assertEquals(magistaPayout.getFee(), result.getFee()),
- () -> assertEquals(magistaPayout.getId(), result.getId()),
- () -> assertEquals(magistaPayout.getShopId(), result.getShopID())
- );
-
- }
-
- @Test
- void mapPayoutStatus() {
- assertAll(
- () -> assertEquals("Cancelled", converter.mapStatus(PayoutStatus.cancelled(new PayoutCancelled()))),
- () -> assertEquals("Paid", converter.mapStatus(PayoutStatus.paid(new PayoutPaid()))),
- () -> assertEquals("Confirmed", converter.mapStatus(PayoutStatus.confirmed(new PayoutConfirmed()))),
- () -> assertEquals("Unpaid", converter.mapStatus(PayoutStatus.unpaid(new PayoutUnpaid()))),
- () -> assertThrows(IllegalArgumentException.class, () -> converter.mapStatus(new PayoutStatus()))
- );
- }
-
- @Test
- void mapPayoutToolDetails() {
- //RussianBankAccount
- PayoutToolInfo toolInfo = new PayoutToolInfo();
- toolInfo.setRussianBankAccount(new RussianBankAccount()
- .setAccount(RandomUtil.randomString(10))
- .setBankBik(RandomUtil.randomString(10))
- .setBankName(RandomUtil.randomString(10))
- .setBankPostAccount(RandomUtil.randomString(10)));
-
- PayoutToolDetailsBankAccount actualRussianBankAccount =
- (PayoutToolDetailsBankAccount) converter.mapPayoutToolDetails(toolInfo);
- RussianBankAccount expectedRussianBankAccount = toolInfo.getRussianBankAccount();
- assertAll(
- () -> assertEquals(expectedRussianBankAccount.getAccount(), actualRussianBankAccount.getAccount()),
- () -> assertEquals(expectedRussianBankAccount.getBankBik(), actualRussianBankAccount.getBankBik()),
- () -> assertEquals(expectedRussianBankAccount.getBankName(), actualRussianBankAccount.getBankName()),
- () -> assertEquals(expectedRussianBankAccount.getBankPostAccount(),
- actualRussianBankAccount.getBankPostAccount())
- );
-
- //WalletInfo
- toolInfo = new PayoutToolInfo();
- toolInfo.setWalletInfo(new WalletInfo()
- .setWalletId(RandomUtil.randomString(10)));
-
- PayoutToolDetailsWalletInfo walletActual =
- (PayoutToolDetailsWalletInfo) converter.mapPayoutToolDetails(toolInfo);
- WalletInfo walletExpected = toolInfo.getWalletInfo();
- assertEquals(walletExpected.getWalletId(), walletActual.getWalletID());
-
- //PaymentInstitutionAccount
- toolInfo = new PayoutToolInfo();
- toolInfo.setPaymentInstitutionAccount(new PaymentInstitutionAccount());
-
- PayoutToolDetailsPaymentInstitutionAccount actualPaymentInstitutionAccount =
- (PayoutToolDetailsPaymentInstitutionAccount) converter.mapPayoutToolDetails(toolInfo);
- PaymentInstitutionAccount expectedPaymentInstitutionAccount = toolInfo.getPaymentInstitutionAccount();
- assertNotNull(expectedPaymentInstitutionAccount);
-
- //InternationalBankAccount
- toolInfo = new PayoutToolInfo();
- toolInfo.setInternationalBankAccount(new InternationalBankAccount()
- .setAccountHolder(RandomUtil.randomString(10))
- .setIban(RandomUtil.randomString(10))
- .setNumber(RandomUtil.randomString(10))
- .setBank(new InternationalBankDetails()
- .setName(RandomUtil.randomString(10))
- .setAbaRtn(RandomUtil.randomString(10))
- .setAddress(RandomUtil.randomString(10))
- .setBic(RandomUtil.randomString(10))
- .setCountry(CountryCode.ABW)));
-
- PayoutToolDetailsInternationalBankAccount actualInternationalBankAccount =
- (PayoutToolDetailsInternationalBankAccount) converter.mapPayoutToolDetails(toolInfo);
- InternationalBankAccount expectedInternationalBankAccount = toolInfo.getInternationalBankAccount();
-
- assertAll(
- () -> assertEquals(expectedInternationalBankAccount.getIban(),
- actualInternationalBankAccount.getIban()),
- () -> assertEquals(expectedInternationalBankAccount.getNumber(),
- actualInternationalBankAccount.getNumber()),
- () -> assertEquals(expectedInternationalBankAccount.getBank().getAbaRtn(),
- actualInternationalBankAccount.getBankDetails().getAbartn()),
- () -> assertEquals(expectedInternationalBankAccount.getBank().getAddress(),
- actualInternationalBankAccount.getBankDetails().getAddress()),
- () -> assertEquals(expectedInternationalBankAccount.getBank().getBic(),
- actualInternationalBankAccount.getBankDetails().getBic()),
- () -> assertEquals(expectedInternationalBankAccount.getBank().getName(),
- actualInternationalBankAccount.getBankDetails().getName()),
- () -> assertEquals(expectedInternationalBankAccount.getBank().getCountry().name(),
- actualInternationalBankAccount.getBankDetails().getCountryCode()),
- //tested via mapInternationalCorrespondentBankAccount test
- () -> assertNull(actualInternationalBankAccount.getCorrespondentBankAccount())
- );
-
- //Some missing type
- assertThrows(IllegalArgumentException.class, () -> converter.mapPayoutToolDetails(new PayoutToolInfo()));
-
- }
-
- @Test
- void mapCountryCode() {
- CountryCode countryCode = CountryCode.ABH;
- assertEquals("ABH", converter.mapCountryCode(countryCode));
- assertNull(converter.mapCountryCode(null));
- }
-
- @Test
- void mapInternationalCorrespondentBankAccount() {
- InternationalBankAccount expected = new InternationalBankAccount()
- .setAccountHolder(RandomUtil.randomString(10))
- .setIban(RandomUtil.randomString(10))
- .setNumber(RandomUtil.randomString(10))
- .setBank(new InternationalBankDetails()
- .setName(RandomUtil.randomString(10))
- .setAbaRtn(RandomUtil.randomString(10))
- .setAddress(RandomUtil.randomString(10))
- .setBic(RandomUtil.randomString(10))
- .setCountry(CountryCode.ABW))
- .setCorrespondentAccount(new InternationalBankAccount()
- .setAccountHolder(RandomUtil.randomString(5))
- .setIban(RandomUtil.randomString(5))
- .setNumber(RandomUtil.randomString(5))
- .setBank(new InternationalBankDetails()
- .setName(RandomUtil.randomString(5))
- .setAbaRtn(RandomUtil.randomString(5))
- .setAddress(RandomUtil.randomString(5))
- .setBic(RandomUtil.randomString(5))
- .setCountry(CountryCode.RUS)));
-
- InternationalCorrespondentBankAccount actual = converter.mapInternationalCorrespondentBankAccount(expected);
-
- assertAll(
- () -> assertEquals(expected.getIban(),
- actual.getIban()),
- () -> assertEquals(expected.getNumber(),
- actual.getNumber()),
- () -> assertEquals(expected.getBank().getAbaRtn(),
- actual.getBankDetails().getAbartn()),
- () -> assertEquals(expected.getBank().getAddress(),
- actual.getBankDetails().getAddress()),
- () -> assertEquals(expected.getBank().getBic(),
- actual.getBankDetails().getBic()),
- () -> assertEquals(expected.getBank().getName(),
- actual.getBankDetails().getName()),
- () -> assertEquals(expected.getBank().getCountry().name(),
- actual.getBankDetails().getCountryCode()),
- () -> assertEquals(expected.getCorrespondentAccount().getIban(),
- actual.getCorrespondentBankAccount().getIban()),
- () -> assertEquals(expected.getCorrespondentAccount().getNumber(),
- actual.getCorrespondentBankAccount().getNumber()),
- () -> assertEquals(expected.getCorrespondentAccount().getBank().getAbaRtn(),
- actual.getCorrespondentBankAccount().getBankDetails().getAbartn()),
- () -> assertEquals(expected.getCorrespondentAccount().getBank().getAddress(),
- actual.getCorrespondentBankAccount().getBankDetails().getAddress()),
- () -> assertEquals(expected.getCorrespondentAccount().getBank().getBic(),
- actual.getCorrespondentBankAccount().getBankDetails().getBic()),
- () -> assertEquals(expected.getCorrespondentAccount().getBank().getName(),
- actual.getCorrespondentBankAccount().getBankDetails().getName()),
- () -> assertEquals(expected.getCorrespondentAccount().getBank().getCountry().name(),
- actual.getCorrespondentBankAccount().getBankDetails().getCountryCode()),
- () -> assertNull(actual.getCorrespondentBankAccount().getCorrespondentBankAccount())
- );
- }
-}
\ No newline at end of file
diff --git a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatRefundToRefundSearchResultConverterTest.java b/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatRefundToRefundSearchResultConverterTest.java
index 2705039d..2d8976ca 100644
--- a/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatRefundToRefundSearchResultConverterTest.java
+++ b/src/test/java/dev/vality/anapi/v2/converter/magista/response/StatRefundToRefundSearchResultConverterTest.java
@@ -20,7 +20,7 @@ class StatRefundToRefundSearchResultConverterTest {
@Test
void convert() {
StatRefundResponse magistaResponse = MagistaUtil.createSearchRefundAllResponse();
- StatRefund magistaRefund = magistaResponse.getRefunds().get(0);
+ StatRefund magistaRefund = magistaResponse.getRefunds().getFirst();
RefundSearchResult result = converter.convert(magistaRefund);
assertAll(
() -> assertEquals(magistaRefund.getAmount(), result.getAmount()),
diff --git a/src/test/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverterTest.java b/src/test/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverterTest.java
index 82eb1f4c..bd96e1e7 100644
--- a/src/test/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverterTest.java
+++ b/src/test/java/dev/vality/anapi/v2/converter/reporter/response/ReporterResponseToReportConverterTest.java
@@ -5,7 +5,7 @@
import dev.vality.reporter.StatReportResponse;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
class ReporterResponseToReportConverterTest {
@@ -14,7 +14,7 @@ class ReporterResponseToReportConverterTest {
@Test
void convert() {
StatReportResponse response = ReporterUtil.createSearchReportsResponse();
- Report report = converter.convert(response.getReports().get(0));
+ Report report = converter.convert(response.getReports().getFirst());
assertNotNull(report);
}
}
\ No newline at end of file
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/BouncerUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/BouncerUtil.java
deleted file mode 100644
index 327dea62..00000000
--- a/src/test/java/dev/vality/anapi/v2/testutil/BouncerUtil.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package dev.vality.anapi.v2.testutil;
-
-import dev.vality.bouncer.ctx.ContextFragment;
-import dev.vality.bouncer.decisions.Judgement;
-import dev.vality.bouncer.decisions.Resolution;
-import dev.vality.bouncer.decisions.ResolutionAllowed;
-import lombok.SneakyThrows;
-import lombok.experimental.UtilityClass;
-import org.apache.thrift.TSerializer;
-
-@UtilityClass
-public class BouncerUtil {
-
- @SneakyThrows
- public static ContextFragment createContextFragment() {
- ContextFragment fragment = DamselUtil.fillRequiredTBaseObject(new ContextFragment(), ContextFragment.class);
- fragment.setContent(new TSerializer().serialize(new dev.vality.bouncer.context.v1.ContextFragment()));
- return fragment;
- }
-
- public static Judgement createJudgementAllowed() {
- Resolution resolution = new Resolution();
- resolution.setAllowed(new ResolutionAllowed());
- return new Judgement().setResolution(resolution);
- }
-}
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/GenerateSelfSigned.java b/src/test/java/dev/vality/anapi/v2/testutil/GenerateSelfSigned.java
new file mode 100644
index 00000000..f40a81c6
--- /dev/null
+++ b/src/test/java/dev/vality/anapi/v2/testutil/GenerateSelfSigned.java
@@ -0,0 +1,37 @@
+package dev.vality.anapi.v2.testutil;
+
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.Date;
+
+public class GenerateSelfSigned {
+
+ public static X509Certificate generateCertificate(KeyPair keyPair) throws CertificateException,
+ OperatorCreationException {
+ X500Name x500Name = new X500Name("CN=***.com, OU=Security&Defense, O=*** Crypto., L=Ottawa, ST=Ontario, C=CA");
+ SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
+ final Date start = new Date();
+ final Date until = Date.from(LocalDate.now().plusDays(365).atStartOfDay().toInstant(ZoneOffset.UTC));
+ final X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(x500Name,
+ new BigInteger(10, new SecureRandom()), start, until, x500Name, pubKeyInfo
+ );
+ ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate());
+ return new JcaX509CertificateConverter()
+ .setProvider(new BouncyCastleProvider())
+ .getCertificate(certificateBuilder.build(contentSigner));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/MagistaUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/MagistaUtil.java
index 9117454d..88327936 100644
--- a/src/test/java/dev/vality/anapi/v2/testutil/MagistaUtil.java
+++ b/src/test/java/dev/vality/anapi/v2/testutil/MagistaUtil.java
@@ -1,17 +1,23 @@
package dev.vality.anapi.v2.testutil;
+import dev.vality.bouncer.ctx.ContextFragment;
+import dev.vality.bouncer.decisions.Judgement;
+import dev.vality.bouncer.decisions.Resolution;
+import dev.vality.bouncer.decisions.ResolutionAllowed;
import dev.vality.damsel.base.Content;
+import dev.vality.damsel.domain.*;
import dev.vality.damsel.domain.InvoicePaymentRefundStatus;
import dev.vality.damsel.domain.InvoicePaymentStatus;
import dev.vality.damsel.domain.InvoiceStatus;
-import dev.vality.damsel.domain.*;
+import dev.vality.magista.*;
import dev.vality.magista.CustomerPayer;
import dev.vality.magista.InvoicePaymentFlow;
import dev.vality.magista.InvoicePaymentFlowHold;
import dev.vality.magista.InvoicePaymentFlowInstant;
import dev.vality.magista.Payer;
-import dev.vality.magista.*;
+import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
+import org.apache.thrift.TSerializer;
import java.time.Instant;
import java.util.HashMap;
@@ -113,24 +119,6 @@ public static StatInvoiceResponse createSearchInvoiceAllResponse() {
);
}
- public static StatPayoutResponse createSearchPayoutRequiredResponse() {
- return DamselUtil.fillRequiredTBaseObject(new StatPayoutResponse(), StatPayoutResponse.class);
- }
-
- public static StatPayoutResponse createSearchPayoutAllResponse() {
- var payout = DamselUtil.fillRequiredTBaseObject(new StatPayout(), StatPayout.class);
- var toolInfo = DamselUtil.fillRequiredTBaseObject(new PayoutToolInfo(), PayoutToolInfo.class);
- var bank = DamselUtil.fillRequiredTBaseObject(new RussianBankAccount(), RussianBankAccount.class);
- var status = DamselUtil.fillRequiredTBaseObject(new PayoutStatus(), PayoutStatus.class);
- var response = DamselUtil.fillRequiredTBaseObject(new StatPayoutResponse(), StatPayoutResponse.class);
- toolInfo.setRussianBankAccount(bank);
- return response.setPayouts(
- List.of(payout
- .setPayoutToolInfo(toolInfo)
- .setStatus(status))
- );
- }
-
public static StatInvoiceTemplateResponse createSearchInvoiceTemplateAllResponse() {
var invoiceTemplate = DamselUtil.fillRequiredTBaseObject(new StatInvoiceTemplate(), StatInvoiceTemplate.class);
var cash = DamselUtil.fillRequiredTBaseObject(new Cash(), Cash.class);
@@ -163,6 +151,19 @@ public static StatInvoiceTemplateResponse createSearchInvoiceTemplateRequiredRes
return DamselUtil.fillRequiredTBaseObject(new StatInvoiceTemplateResponse(), StatInvoiceTemplateResponse.class);
}
+ @SneakyThrows
+ public static ContextFragment createContextFragment() {
+ ContextFragment fragment = DamselUtil.fillRequiredTBaseObject(new ContextFragment(), ContextFragment.class);
+ fragment.setContent(new TSerializer().serialize(new dev.vality.bouncer.context.v1.ContextFragment()));
+ return fragment;
+ }
+
+ public static Judgement createJudgementAllowed() {
+ Resolution resolution = new Resolution();
+ resolution.setAllowed(new ResolutionAllowed());
+ return new Judgement().setResolution(resolution);
+ }
+
public static InvoicePaymentFlow createInvoicePaymentFlowHold() {
return InvoicePaymentFlow.hold(
DamselUtil.fillRequiredTBaseObject(new InvoicePaymentFlowHold(), InvoicePaymentFlowHold.class));
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/OpenApiUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/OpenApiUtil.java
index 9ceb2d32..ff87ccf1 100644
--- a/src/test/java/dev/vality/anapi/v2/testutil/OpenApiUtil.java
+++ b/src/test/java/dev/vality/anapi/v2/testutil/OpenApiUtil.java
@@ -111,21 +111,6 @@ public static MultiValueMap getSearchInvoiceAllParams() {
return params;
}
- public static MultiValueMap getSearchPayoutAllParams() {
- MultiValueMap params = getSearchRequiredParams();
- params.add("shopID", randomIntegerAsString(1, 3));
- params.add("shopIDs", randomIntegerAsString(11, 20));
- params.add("shopIDs", randomIntegerAsString(21, 30));
- params.add("paymentInstitutionRealm", PaymentInstitutionRealm.live.name());
- params.add("offset", randomIntegerAsString(1, 10));
- params.add("payoutID", randomIntegerAsString(1, 1000));
- params.add("payoutToolType", "PayoutAccount");
- params.add("excludedShops", randomIntegerAsString(1, 10));
- params.add("excludedShops", randomIntegerAsString(11, 20));
- params.add("continuationToken", "test");
- return params;
- }
-
public static MultiValueMap getAnalyticsRequiredParams() {
MultiValueMap params = new LinkedMultiValueMap<>();
params.add("partyID", randomIntegerAsString(1, 1000));
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/PublicKeyUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/PublicKeyUtil.java
new file mode 100644
index 00000000..62517415
--- /dev/null
+++ b/src/test/java/dev/vality/anapi/v2/testutil/PublicKeyUtil.java
@@ -0,0 +1,25 @@
+package dev.vality.anapi.v2.testutil;
+
+import lombok.SneakyThrows;
+import lombok.experimental.UtilityClass;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Base64;
+
+@UtilityClass
+public class PublicKeyUtil {
+
+ @SneakyThrows
+ public String getModulus(PublicKey publicKey) {
+ BigInteger publicKeyModulus = ((RSAPublicKey) (publicKey)).getModulus();
+ return Base64.getUrlEncoder().encodeToString(publicKeyModulus.toByteArray());
+ }
+
+ @SneakyThrows
+ public String getExponent(PublicKey publicKey) {
+ BigInteger publicKeyExponent = ((RSAPublicKey) (publicKey)).getPublicExponent();
+ return Base64.getUrlEncoder().encodeToString(publicKeyExponent.toByteArray());
+ }
+}
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/RandomUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/RandomUtil.java
index 40aae493..ca6d1359 100644
--- a/src/test/java/dev/vality/anapi/v2/testutil/RandomUtil.java
+++ b/src/test/java/dev/vality/anapi/v2/testutil/RandomUtil.java
@@ -5,6 +5,8 @@
import java.nio.charset.StandardCharsets;
import java.util.Random;
+import static java.util.UUID.randomUUID;
+
@UtilityClass
public class RandomUtil {
@@ -28,4 +30,8 @@ public static byte[] randomBytes(int length) {
return array;
}
+ public static String randomRequestId() {
+ return randomUUID().toString().substring(0, 32);
+ }
+
}
diff --git a/src/test/java/dev/vality/anapi/v2/testutil/TokenKeeperUtil.java b/src/test/java/dev/vality/anapi/v2/testutil/TokenKeeperUtil.java
deleted file mode 100644
index 1891d94c..00000000
--- a/src/test/java/dev/vality/anapi/v2/testutil/TokenKeeperUtil.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package dev.vality.anapi.v2.testutil;
-
-import dev.vality.token.keeper.AuthData;
-import dev.vality.token.keeper.AuthDataStatus;
-import lombok.experimental.UtilityClass;
-
-import java.util.UUID;
-
-import static dev.vality.anapi.v2.testutil.BouncerUtil.createContextFragment;
-
-@UtilityClass
-public class TokenKeeperUtil {
-
- public static AuthData createAuthData(String token) {
- return new AuthData()
- .setId(UUID.randomUUID().toString())
- .setAuthority(UUID.randomUUID().toString())
- .setToken(token)
- .setStatus(AuthDataStatus.active)
- .setContext(createContextFragment());
- }
-
-
-}
diff --git a/src/test/java/dev/vality/anapi/v2/util/DeadlineUtilTest.java b/src/test/java/dev/vality/anapi/v2/util/DeadlineUtilTest.java
index 9f43b246..e0f61ec7 100644
--- a/src/test/java/dev/vality/anapi/v2/util/DeadlineUtilTest.java
+++ b/src/test/java/dev/vality/anapi/v2/util/DeadlineUtilTest.java
@@ -7,7 +7,8 @@
import java.time.Instant;
import java.time.temporal.ChronoUnit;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
class DeadlineUtilTest {