From 6cccaafe9d36d74f4000d3061d13480b72cba511 Mon Sep 17 00:00:00 2001 From: xuelianhan007 <148412906+xuelianhan007@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:46:26 +0800 Subject: [PATCH] feat(sdk): added company id and name in activity log list (#65) --- .../kraken/operator/auth/dto/JwtTokenDto.java | 23 +++ .../operator/auth/jwt/JwtDecoderToolkit.java | 33 ++++ .../controller/UserMgmtControllerTest.java | 2 +- .../auth/helper/JwtDecoderToolkitTest.java | 39 ++++ .../controller/service/BuyerService.java | 2 +- .../controller/ApiActivityLogCreator.java | 28 +++ .../controller/BuyerControllerTest.java | 49 ++--- .../operator/controller/BuyerCreator.java | 45 +++++ .../EnvAPIActivityControllerTest.java | 187 ++++++++++-------- .../operator/controller/EnvCreator.java | 1 - .../operator/core/dto/ApiActivityLog.java | 2 + .../core/entity/ApiActivityLogEntity.java | 3 + .../exception/KrakenExceptionHandler.java | 3 + .../core/service/ApiActivityLogService.java | 94 ++++++--- .../service/ApiActivityLogServiceTest.java | 126 ++++++++++++ .../filter/ApiLogInputGlobalFilter.java | 19 +- 16 files changed, 505 insertions(+), 151 deletions(-) create mode 100644 kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/dto/JwtTokenDto.java create mode 100644 kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/helper/JwtDecoderToolkitTest.java create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ApiActivityLogCreator.java create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerCreator.java create mode 100644 kraken-java-sdk/kraken-java-sdk-core/src/test/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogServiceTest.java diff --git a/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/dto/JwtTokenDto.java b/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/dto/JwtTokenDto.java new file mode 100644 index 00000000..43b39014 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/dto/JwtTokenDto.java @@ -0,0 +1,23 @@ +package com.consoleconnect.kraken.operator.auth.dto; + +import lombok.Data; + +@Data +public class JwtTokenDto { + private Header header; + private Payload payload; + + @Data + public static class Header { + private String kid; + private String alg; + } + + @Data + public static class Payload { + private String sub; + private String iat; + private String exp; + private String iss; + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/jwt/JwtDecoderToolkit.java b/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/jwt/JwtDecoderToolkit.java index 5b008c5b..27838899 100644 --- a/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/jwt/JwtDecoderToolkit.java +++ b/kraken-java-sdk/kraken-java-sdk-auth/src/main/java/com/consoleconnect/kraken/operator/auth/jwt/JwtDecoderToolkit.java @@ -1,14 +1,19 @@ package com.consoleconnect.kraken.operator.auth.jwt; +import com.consoleconnect.kraken.operator.auth.dto.JwtTokenDto; import com.consoleconnect.kraken.operator.auth.model.AuthDataProperty; import com.consoleconnect.kraken.operator.auth.security.JwtTokenVerifier; +import com.consoleconnect.kraken.operator.core.toolkit.JsonToolkit; +import com.fasterxml.jackson.core.type.TypeReference; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; import java.security.spec.X509EncodedKeySpec; +import java.util.Optional; import javax.crypto.spec.SecretKeySpec; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; import org.springframework.security.oauth2.jwt.JwtValidators; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; @@ -64,4 +69,32 @@ public static NimbusJwtDecoder createJwtDecoderInstance( log.info("jwtDecoderInstance created,issuer:{}", decodeConfig.getIssuer()); return nimbusJwtDecoder; } + + public static Optional decodeJWTToken(String tokenStr) { + if (StringUtils.isBlank(tokenStr)) { + return Optional.empty(); + } + String token = tokenStr.replaceAll("^.*\\s+", ""); + String[] chunks = token.split("\\."); + if (chunks.length < 2) { + return Optional.empty(); + } + java.util.Base64.Decoder decoder = java.util.Base64.getUrlDecoder(); + try { + String headerStr = new String(decoder.decode(chunks[0])); + String payloadStr = new String(decoder.decode(chunks[1])); + + JwtTokenDto.Header header = + JsonToolkit.fromJson(headerStr, new TypeReference() {}); + JwtTokenDto.Payload payload = + JsonToolkit.fromJson(payloadStr, new TypeReference() {}); + JwtTokenDto jwtTokenDto = new JwtTokenDto(); + jwtTokenDto.setHeader(header); + jwtTokenDto.setPayload(payload); + return Optional.of(jwtTokenDto); + } catch (Exception e) { + log.error("Failed to decode token", e); + } + return Optional.empty(); + } } diff --git a/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/controller/UserMgmtControllerTest.java b/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/controller/UserMgmtControllerTest.java index 61bdeb83..dff99503 100644 --- a/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/controller/UserMgmtControllerTest.java +++ b/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/controller/UserMgmtControllerTest.java @@ -427,7 +427,7 @@ void givenUserCreated_whenSearch_thenReturnOk() { Assertions.assertNotNull(bodyStr); assertThat(bodyStr, hasJsonPath("$.data.data", notNullValue())); assertThat(bodyStr, hasJsonPath("$.data.data", hasSize(greaterThanOrEqualTo(1)))); - assertThat(bodyStr, hasJsonPath("$.data.data[0].email", is("abc@test.com"))); + assertThat(bodyStr, hasJsonPath("$.data.data[0].email", equalTo("abc@test.com"))); }); } diff --git a/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/helper/JwtDecoderToolkitTest.java b/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/helper/JwtDecoderToolkitTest.java new file mode 100644 index 00000000..6c439a34 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-auth/src/test/java/com/consoleconnect/kraken/operator/auth/helper/JwtDecoderToolkitTest.java @@ -0,0 +1,39 @@ +package com.consoleconnect.kraken.operator.auth.helper; + +import com.consoleconnect.kraken.operator.auth.dto.JwtTokenDto; +import com.consoleconnect.kraken.operator.auth.jwt.JwtDecoderToolkit; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@Slf4j +class JwtDecoderToolkitTest { + public static String[] illegalDataSetForDecoding() { + return new String[] {"", " ", "xxswewwew.sssss", "xxswewwew"}; + } + + public static String[] legalDataSetForDecoding() { + return new String[] { + "bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXN1YmplY3QiLCJzY3AiOlsibWVzc2FnZTpyZWFkIl0sImV4cCI6NDY4Mzg5Nzc3Nn0.LtMVtIiRIwSyc3aX35Zl0JVwLTcQZAB3dyBOMHNaHCKUljwMrf20a_gT79LfhjDzE_fUVUmFiAO32W1vFnYpZSVaMDUgeIOIOpxfoe9shj_uYenAwIS-_UxqGVIJiJoXNZh_MK80ShNpvsQwamxWEEOAMBtpWNiVYNDMdfgho9n3o5_Z7Gjy8RLBo1tbDREbO9kTFwGIxm_EYpezmRCRq4w1DdS6UDW321hkwMxPnCMSWOvp-hRpmgY2yjzLgPJ6Aucmg9TJ8jloAP1DjJoF1gRR7NTAk8LOGkSjTzVYDYMbCF51YdpojhItSk80YzXiEsv1mTz4oMM49jXBmfXFMA", + "bearer eyJhbGciOiJSUzUxMiJ9.eyJzdWIiOiJ0ZXN0LXN1YmplY3QiLCJleHAiOjE5NzQzMjYxMTl9.LKAx-60EBfD7jC1jb1eKcjO4uLvf3ssISV-8tN-qp7gAjSvKvj4YA9-V2mIb6jcS1X_xGmNy6EIimZXpWaBR3nJmeu-jpe85u4WaW2Ztr8ecAi-dTO7ZozwdtljKuBKKvj4u1nF70zyCNl15AozSG0W1ASrjUuWrJtfyDG6WoZ8VfNMuhtU-xUYUFvscmeZKUYQcJ1KS-oV5tHeF8aNiwQoiPC_9KXCOZtNEJFdq6-uzFdHxvOP2yex5Gbmg5hXonauIFXG2ZPPGdXzm-5xkhBpgM8U7A_6wb3So8wBvLYYm2245QUump63AJRAy8tQpwt4n9MvQxQgS3z9R-NK92A" + }; + } + + @ParameterizedTest + @MethodSource(value = "illegalDataSetForDecoding") + void givenIllegalToken_whenDecode_thenReturnEmpty(String token) { + Optional result = JwtDecoderToolkit.decodeJWTToken(token); + Assertions.assertTrue(result.isEmpty()); + } + + @ParameterizedTest + @MethodSource(value = "legalDataSetForDecoding") + void givenLegalJwtToken_whenDecode_thenReturnOK(String token) { + Optional result = JwtDecoderToolkit.decodeJWTToken(token); + Assertions.assertTrue(result.isPresent()); + Assertions.assertNotNull(result.get().getHeader()); + Assertions.assertNotNull(result.get().getPayload()); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/BuyerService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/BuyerService.java index d77b493b..c2ac58c8 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/BuyerService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/BuyerService.java @@ -66,7 +66,7 @@ public BuyerAssetDto create(String productId, CreateBuyerRequest buyerOnboard, S PRODUCT_BUYER.getKind(), buyerOnboard.getEnvId(), buyerOnboard.getBuyerId(), - AssetStatusEnum.ACTIVATED.getKind(), + null, null, PageRequest.of(0, 1)); if (CollectionUtils.isNotEmpty(exist.getContent())) { diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ApiActivityLogCreator.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ApiActivityLogCreator.java new file mode 100644 index 00000000..2ffd8154 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ApiActivityLogCreator.java @@ -0,0 +1,28 @@ +package com.consoleconnect.kraken.operator.controller; + +import com.consoleconnect.kraken.operator.core.entity.ApiActivityLogEntity; +import com.consoleconnect.kraken.operator.core.repo.ApiActivityLogRepository; +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.UUID; + +public interface ApiActivityLogCreator { + + ApiActivityLogRepository getApiActivityLogRepository(); + + default ApiActivityLogEntity createApiActivityLog(String buyerId, String envId) { + ApiActivityLogEntity apiActivityLogEntity = new ApiActivityLogEntity(); + apiActivityLogEntity.setRequestId(UUID.randomUUID().toString()); + apiActivityLogEntity.setPath("/123"); + apiActivityLogEntity.setUri("localhost"); + apiActivityLogEntity.setMethod("GET"); + apiActivityLogEntity.setEnv(envId); + Map headers = Maps.newHashMap(); + headers.put("acces_token", "2334"); + apiActivityLogEntity.setHeaders(headers); + apiActivityLogEntity.setBuyer(buyerId); + apiActivityLogEntity.setCallSeq(0); + apiActivityLogEntity = getApiActivityLogRepository().save(apiActivityLogEntity); + return apiActivityLogEntity; + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerControllerTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerControllerTest.java index 08570852..966fff98 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerControllerTest.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerControllerTest.java @@ -7,17 +7,17 @@ import com.consoleconnect.kraken.operator.config.TestApplication; import com.consoleconnect.kraken.operator.controller.dto.BuyerAssetDto; import com.consoleconnect.kraken.operator.controller.dto.CreateBuyerRequest; +import com.consoleconnect.kraken.operator.controller.model.Environment; +import com.consoleconnect.kraken.operator.controller.service.EnvironmentService; import com.consoleconnect.kraken.operator.core.dto.Tuple2; import com.consoleconnect.kraken.operator.core.dto.UnifiedAssetDto; import com.consoleconnect.kraken.operator.core.enums.AssetKindEnum; -import com.consoleconnect.kraken.operator.core.model.HttpResponse; import com.consoleconnect.kraken.operator.core.service.UnifiedAssetService; import com.consoleconnect.kraken.operator.core.toolkit.AssetsConstants; -import com.consoleconnect.kraken.operator.core.toolkit.JsonToolkit; import com.consoleconnect.kraken.operator.core.toolkit.LabelConstants; import com.consoleconnect.kraken.operator.test.AbstractIntegrationTest; import com.consoleconnect.kraken.operator.test.MockIntegrationTest; -import com.fasterxml.jackson.core.type.TypeReference; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.hamcrest.Matchers; import org.junit.jupiter.api.MethodOrderer; @@ -36,13 +36,11 @@ @ContextConfiguration(classes = {TestApplication.class}) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @ActiveProfiles("test-rs256") -class BuyerControllerTest extends AbstractIntegrationTest { - private static final String PRODUCT_ID = "product.mef.sonata.api"; - public static final String BASE_URL = String.format("/products/%s/buyers", PRODUCT_ID); - public static final String BUYER_ID = "consolecore-poping-company"; +class BuyerControllerTest extends AbstractIntegrationTest implements EnvCreator, BuyerCreator { - private final WebTestClientHelper webTestClient; + @Getter private final WebTestClientHelper webTestClient; @Autowired private UnifiedAssetService unifiedAssetService; + @Getter @Autowired EnvironmentService environmentService; @Autowired public BuyerControllerTest(WebTestClient webTestClient) { @@ -52,26 +50,9 @@ public BuyerControllerTest(WebTestClient webTestClient) { @Test @Order(2) void givenBuyer_whenCreate_thenOK() { - CreateBuyerRequest requestEntity = new CreateBuyerRequest(); - requestEntity.setBuyerId(BUYER_ID); - requestEntity.setEnvId("stage"); - requestEntity.setCompanyName("console connect"); - - String resp = - webTestClient.requestAndVerify( - HttpMethod.POST, - uriBuilder -> uriBuilder.path(BASE_URL).build(), - HttpStatus.OK.value(), - requestEntity, - bodyStr -> { - assertThat(bodyStr, hasJsonPath("$.data", notNullValue())); - assertThat(bodyStr, hasJsonPath("$.data.buyerToken", notNullValue())); - assertThat(bodyStr, hasJsonPath("$.data.buyerToken.accessToken", notNullValue())); - }); - HttpResponse buyerCreatedResp = - JsonToolkit.fromJson(resp, new TypeReference>() {}); - BuyerAssetDto buyerCreated = buyerCreatedResp.getData(); - String refreshAccessTokenUrl = BASE_URL + "/" + buyerCreated.getId() + "/access-tokens"; + Environment envStage = createStage(PRODUCT_ID); + BuyerAssetDto buyerCreated = createBuyer(BUYER_ID, envStage.getId(), COMPANY_NAME); + String refreshAccessTokenUrl = BUYER_BASE_URL + "/" + buyerCreated.getId() + "/access-tokens"; webTestClient.requestAndVerify( HttpMethod.POST, uriBuilder -> @@ -93,7 +74,7 @@ void givenBuyer_whenCreate_thenOK() { void givenBuyer_whenSearch_thenOK() { webTestClient.requestAndVerify( HttpMethod.GET, - uriBuilder -> uriBuilder.path(BASE_URL).build(), + uriBuilder -> uriBuilder.path(BUYER_BASE_URL).build(), HttpStatus.OK.value(), null, bodyStr -> { @@ -107,15 +88,17 @@ void givenBuyer_whenSearch_thenOK() { void givenDuplicatedBuyer_whenCreate_thenNot200() { CreateBuyerRequest requestEntity = new CreateBuyerRequest(); requestEntity.setBuyerId(BUYER_ID); - requestEntity.setEnvId("stage"); + Environment envStage = createStage(PRODUCT_ID); + requestEntity.setEnvId(envStage.getId()); requestEntity.setCompanyName("console connect"); webTestClient.requestAndVerify( HttpMethod.POST, - uriBuilder -> uriBuilder.path(BASE_URL).build(), + uriBuilder -> uriBuilder.path(BUYER_BASE_URL).build(), HttpStatus.BAD_REQUEST.value(), requestEntity, bodyStr -> { + log.info(bodyStr); assertThat(bodyStr, hasJsonPath("$.code", not(200))); }); } @@ -129,7 +112,7 @@ void givenBlankBuyer_whenCreate_thenNot200() { requestEntity.setCompanyName("console connect"); webTestClient.requestAndVerify( HttpMethod.POST, - uriBuilder -> uriBuilder.path(BASE_URL).build(), + uriBuilder -> uriBuilder.path(BUYER_BASE_URL).build(), HttpStatus.BAD_REQUEST.value(), requestEntity, bodyStr -> { @@ -146,7 +129,7 @@ void givenBlankEnv_whenCreateBuyer_thenNot200() { requestEntity.setCompanyName("console connect"); webTestClient.requestAndVerify( HttpMethod.POST, - uriBuilder -> uriBuilder.path(BASE_URL).build(), + uriBuilder -> uriBuilder.path(BUYER_BASE_URL).build(), HttpStatus.BAD_REQUEST.value(), requestEntity, bodyStr -> { diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerCreator.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerCreator.java new file mode 100644 index 00000000..24b7631a --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/BuyerCreator.java @@ -0,0 +1,45 @@ +package com.consoleconnect.kraken.operator.controller; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +import com.consoleconnect.kraken.operator.controller.dto.BuyerAssetDto; +import com.consoleconnect.kraken.operator.controller.dto.CreateBuyerRequest; +import com.consoleconnect.kraken.operator.core.model.HttpResponse; +import com.consoleconnect.kraken.operator.core.toolkit.JsonToolkit; +import com.fasterxml.jackson.core.type.TypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; + +public interface BuyerCreator { + String PRODUCT_ID = "product.mef.sonata.api"; + String BUYER_BASE_URL = String.format("/products/%s/buyers", PRODUCT_ID); + String BUYER_ID = "testing-company"; + String COMPANY_NAME = "testing-company-name"; + + WebTestClientHelper getWebTestClient(); + + default BuyerAssetDto createBuyer(String buyerId, String envId, String companyName) { + CreateBuyerRequest requestEntity = new CreateBuyerRequest(); + requestEntity.setBuyerId(buyerId); + requestEntity.setEnvId(envId); + requestEntity.setCompanyName(companyName); + + String resp = + getWebTestClient() + .requestAndVerify( + HttpMethod.POST, + uriBuilder -> uriBuilder.path(BUYER_BASE_URL).build(), + HttpStatus.OK.value(), + requestEntity, + bodyStr -> { + assertThat(bodyStr, hasJsonPath("$.data", notNullValue())); + assertThat(bodyStr, hasJsonPath("$.data.buyerToken", notNullValue())); + assertThat(bodyStr, hasJsonPath("$.data.buyerToken.accessToken", notNullValue())); + }); + HttpResponse buyerCreatedResp = + JsonToolkit.fromJson(resp, new TypeReference>() {}); + return buyerCreatedResp.getData(); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvAPIActivityControllerTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvAPIActivityControllerTest.java index c6ef3c07..9b71b677 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvAPIActivityControllerTest.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvAPIActivityControllerTest.java @@ -1,123 +1,136 @@ package com.consoleconnect.kraken.operator.controller; +import static com.jayway.jsonassert.impl.matcher.IsCollectionWithSize.hasSize; +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; import com.consoleconnect.kraken.operator.config.TestApplication; +import com.consoleconnect.kraken.operator.controller.dto.BuyerAssetDto; +import com.consoleconnect.kraken.operator.controller.model.Environment; +import com.consoleconnect.kraken.operator.controller.service.EnvironmentService; import com.consoleconnect.kraken.operator.core.entity.ApiActivityLogEntity; -import com.consoleconnect.kraken.operator.core.model.AppProperty; +import com.consoleconnect.kraken.operator.core.model.UnifiedAsset; +import com.consoleconnect.kraken.operator.core.model.facet.BuyerOnboardFacets; import com.consoleconnect.kraken.operator.core.repo.ApiActivityLogRepository; import com.consoleconnect.kraken.operator.core.toolkit.IpUtils; +import com.consoleconnect.kraken.operator.core.toolkit.JsonToolkit; import com.consoleconnect.kraken.operator.test.AbstractIntegrationTest; import com.consoleconnect.kraken.operator.test.MockIntegrationTest; -import com.google.common.collect.Maps; -import java.time.Duration; import java.time.ZonedDateTime; import java.util.*; -import org.hamcrest.Matchers; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.reactive.server.WebTestClient; +@Slf4j +@Getter @MockIntegrationTest @ContextConfiguration(classes = {TestApplication.class}) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class EnvAPIActivityControllerTest extends AbstractIntegrationTest { - @Autowired WebTestClient webTestClient; - @Autowired AppProperty appProperty; - @Autowired ApiActivityLogRepository repository; +@ActiveProfiles("test-rs256") +class EnvAPIActivityControllerTest extends AbstractIntegrationTest + implements ApiActivityLogCreator, EnvCreator, BuyerCreator { + WebTestClientHelper webTestClient; + @Autowired ApiActivityLogRepository apiActivityLogRepository; + @Autowired EnvironmentService environmentService; - public static final String PRODUCT_ID = "mef.sonata"; - public static final String DEV_ENV = "dev"; - public static final String BASE_URL = - String.format("/products/%s/envs/%s/api-activities", PRODUCT_ID, DEV_ENV); + private String requestId; + + @Autowired + public EnvAPIActivityControllerTest(WebTestClient webTestClient) { + this.webTestClient = new WebTestClientHelper(webTestClient); + } @Test - void testSearch() { - webTestClient - .mutate() - .responseTimeout(Duration.ofSeconds(600)) - .build() - .get() - .uri( - uriBuilder -> - uriBuilder - .path(BASE_URL) - .queryParam( - "requestStartTime", - ZonedDateTime.now().minusDays(1).toInstant().toEpochMilli()) - .queryParam( - "requestEndTime", - ZonedDateTime.now().plusDays(10).toInstant().toEpochMilli()) - .queryParam("requestId", "1001") - .build()) - .exchange() - .expectBody() - .consumeWith( - response -> { - String bodyStr = new String(Objects.requireNonNull(response.getResponseBody())); - System.out.println(bodyStr); - IpUtils.getIP(MockServerHttpRequest.get("/123").build()); - }); + @Order(1) + void givenFakedActivityId_whenSearchActivityDetail_thenReturnEmpty() { + Environment envStage = createStage(PRODUCT_ID); + String activityBaseUrl = + String.format("/products/%s/envs/%s/api-activities", PRODUCT_ID, envStage.getId()); + webTestClient.requestAndVerify( + HttpMethod.GET, + uriBuilder -> uriBuilder.path(activityBaseUrl + "/{activityId}").build("11"), + HttpStatus.OK.value(), + null, + bodyStr -> { + log.info(bodyStr); + assertThat(bodyStr, hasJsonPath("$.message", notNullValue())); + IpUtils.getIP(MockServerHttpRequest.get("/123").build()); + }); } @Test - void testSearchDetailEmpty() { - webTestClient - .mutate() - .responseTimeout(Duration.ofSeconds(600)) - .build() - .get() - .uri(uriBuilder -> uriBuilder.path(BASE_URL + "/{activityId}").build("11")) - .exchange() - .expectBody() - .consumeWith( - response -> { - String bodyStr = new String(Objects.requireNonNull(response.getResponseBody())); - System.out.println(bodyStr); - IpUtils.getIP(MockServerHttpRequest.get("/123").build()); - }); + @Order(2) + void givenExistedActivityId_whenSearchDetail_thenReturnOK() { + Environment envStage = createStage(PRODUCT_ID); + String activityBaseUrl = + String.format("/products/%s/envs/%s/api-activities", PRODUCT_ID, envStage.getId()); + BuyerAssetDto buyerAssetDto = + createBuyer(BUYER_ID + "-" + System.currentTimeMillis(), envStage.getId(), COMPANY_NAME); + BuyerOnboardFacets buyerFacets = + UnifiedAsset.getFacets(buyerAssetDto, BuyerOnboardFacets.class); + ApiActivityLogEntity apiActivityLogEntity = + createApiActivityLog(buyerFacets.getBuyerInfo().getBuyerId(), envStage.getId()); + log.info("activity log created:{}", JsonToolkit.toJson(apiActivityLogEntity)); + requestId = apiActivityLogEntity.getRequestId(); + webTestClient.requestAndVerify( + HttpMethod.GET, + uriBuilder -> + uriBuilder + .path(activityBaseUrl + "/{activityId}") + .build(apiActivityLogEntity.getRequestId()), + HttpStatus.OK.value(), + null, + bodyStr -> { + log.info(bodyStr); + assertThat(bodyStr, hasJsonPath("$.data", notNullValue())); + assertThat(bodyStr, hasJsonPath("$.data.main.buyer", notNullValue())); + }); } @Test - void testSearchDetailExisted() { - ApiActivityLogEntity apiActivityLogEntity = new ApiActivityLogEntity(); - apiActivityLogEntity.setRequestId(UUID.randomUUID().toString()); - apiActivityLogEntity.setPath("/123"); - apiActivityLogEntity.setUri("localhost"); - apiActivityLogEntity.setMethod("GET"); - apiActivityLogEntity.setEnv("dev"); - Map headers = Maps.newHashMap(); - headers.put("acces_token", "2334"); - apiActivityLogEntity.setHeaders(headers); - repository.save(apiActivityLogEntity); - webTestClient - .mutate() - .responseTimeout(Duration.ofSeconds(600)) - .build() - .get() - .uri( - uriBuilder -> - uriBuilder - .path(BASE_URL + "/{activityId}") - .build( - PRODUCT_ID, - DEV_ENV, - apiActivityLogEntity.getRequestId(), - apiActivityLogEntity.getRequestId())) - .exchange() - .expectBody() - .consumeWith( - response -> { - String bodyStr = new String(Objects.requireNonNull(response.getResponseBody())); - System.out.println(bodyStr); - IpUtils.getIP(MockServerHttpRequest.get("/123").build()); - }); + @Order(3) + void givenTimeRange_whenSearchActivities_thenReturnOK() { + Environment envStage = createStage(PRODUCT_ID); + log.info("envId:{}", envStage.getId()); + String activityBaseUrl = + String.format("/products/%s/envs/%s/api-activities", PRODUCT_ID, envStage.getId()); + webTestClient.requestAndVerify( + HttpMethod.GET, + uriBuilder -> + uriBuilder + .path(activityBaseUrl) + .queryParam("envId", envStage.getId()) + .queryParam("path", "/123") + .queryParam("method", "GET") + .queryParam( + "requestStartTime", ZonedDateTime.now().minusDays(1).toInstant().toEpochMilli()) + .queryParam( + "requestEndTime", ZonedDateTime.now().plusDays(10).toInstant().toEpochMilli()) + .build(), + HttpStatus.OK.value(), + null, + bodyStr -> { + log.info(bodyStr); + assertThat(bodyStr, hasJsonPath("$.data", notNullValue())); + assertThat(bodyStr, hasJsonPath("$.data.data", hasSize(1))); + assertThat( + bodyStr, hasJsonPath("$.data.data[0].buyerName", equalTo("testing-company-name"))); + }); } @Test + @Order(4) void testGetIP() { MockServerHttpRequest mockServerHttpRequest = MockServerHttpRequest.get("/123").build(); ServerHttpRequest serverHttpRequest = @@ -126,6 +139,6 @@ void testGetIP() { .header("x-forwarded-for", "192.168.1.11,192.16.1.10") .build(); String ip = IpUtils.getIP(serverHttpRequest); - assertThat(ip, Matchers.notNullValue()); + assertThat(ip, notNullValue()); } } diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvCreator.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvCreator.java index 159fe641..537e098a 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvCreator.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/EnvCreator.java @@ -9,7 +9,6 @@ import org.springframework.data.domain.PageRequest; public interface EnvCreator { - EnvironmentService getEnvironmentService(); default Environment createStage(String productIdOrKey) { diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/dto/ApiActivityLog.java b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/dto/ApiActivityLog.java index 927f44f2..1a3cb84e 100644 --- a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/dto/ApiActivityLog.java +++ b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/dto/ApiActivityLog.java @@ -21,4 +21,6 @@ public class ApiActivityLog extends AbstractHttpModel { private SyncStatusEnum syncStatus; private String clientId; + private String buyer; + private String buyerName; } diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/entity/ApiActivityLogEntity.java b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/entity/ApiActivityLogEntity.java index 169ac2d0..0d0eaea5 100644 --- a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/entity/ApiActivityLogEntity.java +++ b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/entity/ApiActivityLogEntity.java @@ -38,4 +38,7 @@ public class ApiActivityLogEntity extends AbstractHttpEntity { @Enumerated(EnumType.STRING) @Column(name = "sync_status", nullable = true, unique = false) private SyncStatusEnum syncStatus; + + @Column(name = "buyer", nullable = true, unique = false) + private String buyer; } diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/exception/KrakenExceptionHandler.java b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/exception/KrakenExceptionHandler.java index 6ee736dc..a385bbf0 100644 --- a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/exception/KrakenExceptionHandler.java +++ b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/exception/KrakenExceptionHandler.java @@ -4,6 +4,7 @@ import com.consoleconnect.kraken.operator.core.toolkit.StringUtils; import java.util.*; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.function.TriConsumer; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; @@ -22,6 +23,7 @@ import org.springframework.web.server.ResponseStatusException; import reactor.core.publisher.Mono; +@Slf4j @Component @Order(Integer.MIN_VALUE) public class KrakenExceptionHandler extends AbstractErrorWebExceptionHandler { @@ -92,6 +94,7 @@ private HttpStatusCode determineHttpStatus(Throwable throwable) { } else if (throwable instanceof KrakenException krakenException) { return HttpStatus.valueOf(krakenException.getCode()); } else { + log.error("Internal Server Error", throwable); return HttpStatus.INTERNAL_SERVER_ERROR; } } diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogService.java b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogService.java index cdfb0bf9..8f5e729b 100644 --- a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogService.java +++ b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogService.java @@ -1,10 +1,18 @@ package com.consoleconnect.kraken.operator.core.service; +import static com.consoleconnect.kraken.operator.core.enums.AssetKindEnum.PRODUCT_BUYER; +import static com.consoleconnect.kraken.operator.core.toolkit.LabelConstants.LABEL_BUYER_ID; + import com.consoleconnect.kraken.operator.core.dto.ApiActivityLog; import com.consoleconnect.kraken.operator.core.dto.ComposedHttpRequest; +import com.consoleconnect.kraken.operator.core.dto.UnifiedAssetDto; import com.consoleconnect.kraken.operator.core.entity.ApiActivityLogEntity; +import com.consoleconnect.kraken.operator.core.entity.UnifiedAssetEntity; import com.consoleconnect.kraken.operator.core.mapper.ApiActivityLogMapper; +import com.consoleconnect.kraken.operator.core.model.UnifiedAsset; +import com.consoleconnect.kraken.operator.core.model.facet.BuyerOnboardFacets; import com.consoleconnect.kraken.operator.core.repo.ApiActivityLogRepository; +import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository; import com.consoleconnect.kraken.operator.core.request.LogSearchRequest; import com.consoleconnect.kraken.operator.core.toolkit.Paging; import com.consoleconnect.kraken.operator.core.toolkit.PagingHelper; @@ -12,14 +20,17 @@ import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import java.util.*; +import java.util.stream.Collectors; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @AllArgsConstructor @@ -27,37 +38,68 @@ public class ApiActivityLogService { public static final String CREATED_AT = "createdAt"; private final ApiActivityLogRepository repository; + private final UnifiedAssetRepository unifiedAssetRepository; + @Transactional(readOnly = true) public Paging search(LogSearchRequest logSearchRequest, Pageable pageable) { + Specification spec = buildSearchQuery(logSearchRequest); + Page page = repository.findAll(spec, pageable); - Specification spec = - (root, query, criteriaBuilder) -> { - List predicateList = new ArrayList<>(); - addEq("env", logSearchRequest.getEnv(), predicateList, criteriaBuilder, root); - addEq("requestId", logSearchRequest.getRequestId(), predicateList, criteriaBuilder, root); - addEq("method", logSearchRequest.getMethod(), predicateList, criteriaBuilder, root); - addEq("path", logSearchRequest.getPath(), predicateList, criteriaBuilder, root); - addEq("callSeq", "0", predicateList, criteriaBuilder, root); - if (logSearchRequest.getQueryStart() != null) { - predicateList.add( - criteriaBuilder.greaterThan( - root.get(CREATED_AT), logSearchRequest.getQueryStart())); - } - if (logSearchRequest.getQueryEnd() != null) { - predicateList.add( - criteriaBuilder.lessThan(root.get(CREATED_AT), logSearchRequest.getQueryEnd())); + Map buyerIdEntityMap = searchBuyers(logSearchRequest.getEnv()); + return PagingHelper.toPaging( + page, + entity -> { + ApiActivityLog apiActivityLog = ApiActivityLogMapper.INSTANCE.map(entity); + UnifiedAssetDto buyerAssetDto = + buyerIdEntityMap.getOrDefault(apiActivityLog.getBuyer(), null); + if (Objects.nonNull(buyerAssetDto)) { + BuyerOnboardFacets facets = + UnifiedAsset.getFacets(buyerAssetDto, BuyerOnboardFacets.class); + apiActivityLog.setBuyerName( + facets.getBuyerInfo() == null ? "" : facets.getBuyerInfo().getCompanyName()); } - if (logSearchRequest.getStatusCode() != null) { - predicateList.add( - criteriaBuilder.equal( - root.get("httpStatusCode"), logSearchRequest.getStatusCode())); - } - Predicate[] predicateListArray = predicateList.toArray(new Predicate[0]); - return query.where(predicateListArray).getRestriction(); - }; - Page page = repository.findAll(spec, pageable); + return apiActivityLog; + }); + } + + private Specification buildSearchQuery(LogSearchRequest logSearchRequest) { + return (root, query, criteriaBuilder) -> { + List predicateList = new ArrayList<>(); + addEq("env", logSearchRequest.getEnv(), predicateList, criteriaBuilder, root); + addEq("requestId", logSearchRequest.getRequestId(), predicateList, criteriaBuilder, root); + addEq("method", logSearchRequest.getMethod(), predicateList, criteriaBuilder, root); + addEq("path", logSearchRequest.getPath(), predicateList, criteriaBuilder, root); + addEq("callSeq", "0", predicateList, criteriaBuilder, root); + if (logSearchRequest.getQueryStart() != null) { + predicateList.add( + criteriaBuilder.greaterThan(root.get(CREATED_AT), logSearchRequest.getQueryStart())); + } + if (logSearchRequest.getQueryEnd() != null) { + predicateList.add( + criteriaBuilder.lessThan(root.get(CREATED_AT), logSearchRequest.getQueryEnd())); + } + if (logSearchRequest.getStatusCode() != null) { + predicateList.add( + criteriaBuilder.equal(root.get("httpStatusCode"), logSearchRequest.getStatusCode())); + } + Predicate[] predicateListArray = predicateList.toArray(new Predicate[0]); + return query.where(predicateListArray).getRestriction(); + }; + } - return PagingHelper.toPaging(page, ApiActivityLogMapper.INSTANCE::map); + public Map searchBuyers(String envId) { + Page buyerPage = + unifiedAssetRepository.findBuyers( + null, PRODUCT_BUYER.getKind(), envId, null, null, null, PageRequest.of(0, 100)); + Map buyerIdAssetMap = new HashMap<>(); + if (CollectionUtils.isEmpty(buyerPage.getContent())) { + return buyerIdAssetMap; + } + return buyerPage.getContent().stream() + .collect( + Collectors.toMap( + entity -> entity.getLabels().get(LABEL_BUYER_ID), + entity -> UnifiedAssetService.toAsset(entity, true))); } private void addEq( diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/test/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogServiceTest.java b/kraken-java-sdk/kraken-java-sdk-core/src/test/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogServiceTest.java new file mode 100644 index 00000000..66f16837 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-core/src/test/java/com/consoleconnect/kraken/operator/core/service/ApiActivityLogServiceTest.java @@ -0,0 +1,126 @@ +package com.consoleconnect.kraken.operator.core.service; + +import static com.consoleconnect.kraken.operator.core.enums.AssetKindEnum.PRODUCT_BUYER; +import static com.consoleconnect.kraken.operator.core.toolkit.LabelConstants.*; + +import com.consoleconnect.kraken.operator.core.CustomConfig; +import com.consoleconnect.kraken.operator.core.dto.ApiActivityLog; +import com.consoleconnect.kraken.operator.core.dto.ComposedHttpRequest; +import com.consoleconnect.kraken.operator.core.entity.ApiActivityLogEntity; +import com.consoleconnect.kraken.operator.core.enums.AssetStatusEnum; +import com.consoleconnect.kraken.operator.core.event.IngestionDataResult; +import com.consoleconnect.kraken.operator.core.model.SyncMetadata; +import com.consoleconnect.kraken.operator.core.model.UnifiedAsset; +import com.consoleconnect.kraken.operator.core.model.facet.BuyerOnboardFacets; +import com.consoleconnect.kraken.operator.core.repo.ApiActivityLogRepository; +import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository; +import com.consoleconnect.kraken.operator.core.request.LogSearchRequest; +import com.consoleconnect.kraken.operator.core.toolkit.DateTime; +import com.consoleconnect.kraken.operator.core.toolkit.JsonToolkit; +import com.consoleconnect.kraken.operator.core.toolkit.Paging; +import com.consoleconnect.kraken.operator.test.AbstractIntegrationTest; +import com.consoleconnect.kraken.operator.test.MockIntegrationTest; +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.common.collect.Maps; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.data.domain.PageRequest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@MockIntegrationTest +@ContextConfiguration(classes = CustomConfig.class) +class ApiActivityLogServiceTest extends AbstractIntegrationTest { + + @Autowired private ApiActivityLogRepository apiActivityLogRepository; + @Autowired private UnifiedAssetRepository unifiedAssetRepository; + @Autowired private UnifiedAssetService unifiedAssetService; + + @SpyBean private ApiActivityLogService apiActivityLogService; + + private static final String STAGE_ENV = "stage"; + + @Test + @Order(1) + void givenExistedActivityId_whenSearchDetail_thenReturnOK() { + String buyerId = "test-log" + System.currentTimeMillis(); + createBuyer(buyerId, STAGE_ENV, "test-company-name-" + System.currentTimeMillis()); + ApiActivityLogEntity entity = createApiActivityLog(buyerId, STAGE_ENV); + Optional optional = apiActivityLogService.getDetail(entity.getRequestId()); + Assertions.assertTrue(optional.isPresent()); + Assertions.assertNotNull(optional.get()); + log.info("result:{}", JsonToolkit.toJson(optional.get())); + } + + @Test + @Order(2) + void givenTimeRange_whenSearchActivities_thenReturnOK() { + String buyerId = "test-log" + System.currentTimeMillis(); + createBuyer(buyerId, STAGE_ENV, "test-company-name-" + System.currentTimeMillis()); + ApiActivityLogEntity entity = createApiActivityLog(buyerId, STAGE_ENV); + LogSearchRequest logSearchRequest = + LogSearchRequest.builder() + .env(STAGE_ENV) + .requestId(entity.getRequestId()) + .queryStart(ZonedDateTime.now().minusDays(1)) + .queryEnd(ZonedDateTime.now().plusDays(10)) + .build(); + Paging pages = + apiActivityLogService.search(logSearchRequest, PageRequest.of(0, 10)); + log.info("pages:{}", JsonToolkit.toJson(pages)); + Assertions.assertNotNull(pages.getData()); + Assertions.assertFalse(pages.getData().isEmpty()); + } + + public ApiActivityLogEntity createApiActivityLog(String buyerId, String envId) { + ApiActivityLogEntity apiActivityLogEntity = new ApiActivityLogEntity(); + apiActivityLogEntity.setRequestId(UUID.randomUUID().toString()); + apiActivityLogEntity.setPath("/123"); + apiActivityLogEntity.setUri("localhost"); + apiActivityLogEntity.setMethod("GET"); + apiActivityLogEntity.setEnv(envId); + Map headers = Maps.newHashMap(); + headers.put("acces_token", "2334"); + apiActivityLogEntity.setHeaders(headers); + apiActivityLogEntity.setBuyer(buyerId); + apiActivityLogEntity.setCallSeq(0); + apiActivityLogEntity = apiActivityLogRepository.save(apiActivityLogEntity); + return apiActivityLogEntity; + } + + private IngestionDataResult createBuyer(String buyerId, String envId, String companyName) { + String key = "mef.sonata.buyer" + System.currentTimeMillis(); + UnifiedAsset unifiedAsset = UnifiedAsset.of(PRODUCT_BUYER.getKind(), key, "Buyer"); + unifiedAsset.getMetadata().setDescription("Onboard buyer information"); + unifiedAsset.getMetadata().getLabels().put(LABEL_ENV_ID, envId); + unifiedAsset.getMetadata().getLabels().put(LABEL_BUYER_ID, buyerId); + unifiedAsset + .getMetadata() + .getLabels() + .put(LABEL_ISSUE_AT, DateTimeFormatter.ISO_INSTANT.format(Instant.now())); + unifiedAsset.getMetadata().setStatus(AssetStatusEnum.ACTIVATED.getKind()); + BuyerOnboardFacets facets = new BuyerOnboardFacets(); + BuyerOnboardFacets.BuyerInfo buyerInfo = new BuyerOnboardFacets.BuyerInfo(); + buyerInfo.setBuyerId(buyerId); + buyerInfo.setEnvId(envId); + buyerInfo.setCompanyName(companyName); + facets.setBuyerInfo(buyerInfo); + + unifiedAsset.setFacets( + JsonToolkit.fromJson( + JsonToolkit.toJson(facets), new TypeReference>() {})); + SyncMetadata syncMetadata = new SyncMetadata("", "", DateTime.nowInUTCString(), "unit-test"); + return unifiedAssetService.syncAsset( + "product.mef.sonata.api", unifiedAsset, syncMetadata, true); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-gateway/src/main/java/com/consoleconnect/kraken/operator/gateway/filter/ApiLogInputGlobalFilter.java b/kraken-java-sdk/kraken-java-sdk-gateway/src/main/java/com/consoleconnect/kraken/operator/gateway/filter/ApiLogInputGlobalFilter.java index 9894b189..814fe745 100644 --- a/kraken-java-sdk/kraken-java-sdk-gateway/src/main/java/com/consoleconnect/kraken/operator/gateway/filter/ApiLogInputGlobalFilter.java +++ b/kraken-java-sdk/kraken-java-sdk-gateway/src/main/java/com/consoleconnect/kraken/operator/gateway/filter/ApiLogInputGlobalFilter.java @@ -3,12 +3,15 @@ import static com.consoleconnect.kraken.operator.gateway.filter.KrakenFilterConstants.GATEWAY_SERVICE; import static org.springframework.core.io.buffer.DataBufferUtils.join; +import com.consoleconnect.kraken.operator.auth.jwt.JwtDecoderToolkit; +import com.consoleconnect.kraken.operator.auth.model.AuthDataProperty; import com.consoleconnect.kraken.operator.core.entity.ApiActivityLogEntity; import com.consoleconnect.kraken.operator.core.model.AppProperty; import com.consoleconnect.kraken.operator.core.repo.ApiActivityLogRepository; import com.consoleconnect.kraken.operator.core.toolkit.IpUtils; import com.consoleconnect.kraken.operator.gateway.service.FilterHeaderService; import java.nio.charset.Charset; +import java.util.Map; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -24,11 +27,15 @@ @Slf4j public class ApiLogInputGlobalFilter extends AbstractGlobalFilter { + private final AuthDataProperty.ResourceServer resourceServer; + public ApiLogInputGlobalFilter( AppProperty appProperty, + AuthDataProperty.ResourceServer resourceServer, ApiActivityLogRepository apiActivityLogRepository, FilterHeaderService filterHeaderService) { super(appProperty, apiActivityLogRepository, filterHeaderService); + this.resourceServer = resourceServer; } @Override @@ -52,11 +59,12 @@ private void recordRequestParameter(ServerWebExchange exchange) { try { ApiActivityLogEntity entity = generateHttpRequestEntity(exchange); entity.setQueryParameters(exchange.getRequest().getQueryParams().toSingleValueMap()); - entity.setHeaders( - filterHeaderService.filterHeaders(exchange.getRequest().getHeaders().toSingleValueMap())); + Map headers = exchange.getRequest().getHeaders().toSingleValueMap(); + entity.setHeaders(filterHeaderService.filterHeaders(headers)); entity.setQueryParameters(exchange.getRequest().getQueryParams().toSingleValueMap()); entity.setRequestIp(IpUtils.getIP(exchange.getRequest())); entity.setResponseIp(GATEWAY_SERVICE); + entity.setBuyer(readBuyer(headers)); apiActivityLogRepository.save(entity); log.info("createdEntity:{}", entity.getId()); exchange @@ -67,6 +75,13 @@ private void recordRequestParameter(ServerWebExchange exchange) { } } + private String readBuyer(Map headers) { + String token = headers.getOrDefault(resourceServer.getBearerTokenHeaderName(), ""); + return JwtDecoderToolkit.decodeJWTToken(token) + .map(dto -> dto.getPayload().getSub()) + .orElse(null); + } + private void recordRequestBody(ServerWebExchange exchange, DataBuffer db) { try { String entityId =