From 34394c6322123888b08f570f06dadbfa3f4f01cb Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Tue, 12 Aug 2025 15:59:48 +0800 Subject: [PATCH 1/7] list api availability --- .../api/ComponentMgmtController.java | 8 ++++++ .../dto/ApiMapperDeploymentDTO.java | 2 ++ .../ApiAvailabilityChangeHistoryEntity.java | 19 ++++++++++++++ .../mapper/ApiAvailabilityMapper.java | 13 ++++++++++ .../model/ApiAvailabilityChangeHistory.java | 13 ++++++++++ .../model/UpdateAipAvailabilityRequest.java | 1 + ...piAvailabilityChangeHistoryRepository.java | 17 +++++++++++++ .../service/ApiComponentService.java | 25 +++++++++++++++++++ .../service/ProductDeploymentService.java | 24 ++++++++++++++++++ 9 files changed, 122 insertions(+) create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/mapper/ApiAvailabilityMapper.java create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/ApiAvailabilityChangeHistory.java create mode 100644 kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/ComponentMgmtController.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/ComponentMgmtController.java index 8bf4fd3b2..5f95712c0 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/ComponentMgmtController.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/ComponentMgmtController.java @@ -2,6 +2,7 @@ import com.consoleconnect.kraken.operator.auth.security.UserContext; import com.consoleconnect.kraken.operator.controller.dto.*; +import com.consoleconnect.kraken.operator.controller.model.ApiAvailabilityChangeHistory; import com.consoleconnect.kraken.operator.controller.model.ComponentTagFacet; import com.consoleconnect.kraken.operator.controller.model.StandardComponentInfo; import com.consoleconnect.kraken.operator.controller.model.UpdateAipAvailabilityRequest; @@ -130,6 +131,13 @@ public Mono updateApiAvailability( .map(userId -> apiComponentService.updateApiAvailability(request, userId)); } + @Operation(summary = "api use case availability change history") + @GetMapping("/components/apiAvailability/change-history") + public HttpResponse> listApiAvailabilityChangeHistory( + @RequestParam("mapperKey") String mapperKey, @RequestParam("env") String env) { + return HttpResponse.ok(apiComponentService.getApiAvailabilityChangeHistory(mapperKey, env)); + } + @Operation(summary = "update workflow template)") @PatchMapping("/components/{id}/workflow") @AuditAction( diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/ApiMapperDeploymentDTO.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/ApiMapperDeploymentDTO.java index 44937e613..211f0e5ef 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/ApiMapperDeploymentDTO.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/ApiMapperDeploymentDTO.java @@ -27,4 +27,6 @@ public class ApiMapperDeploymentDTO extends ComponentExpandDTO.TargetMappingDeta private String verifiedAt; private boolean verifiedStatus; private boolean productionEnable; + private boolean stageAvailable = true; + private boolean prodAvailable = true; } diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java new file mode 100644 index 000000000..7a62d3dfb --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java @@ -0,0 +1,19 @@ +package com.consoleconnect.kraken.operator.controller.entity; + +import com.consoleconnect.kraken.operator.core.entity.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Getter +@Setter +@Table(name = "kraken_mgmt_api_availability_change_history") +public class ApiAvailabilityChangeHistoryEntity extends AbstractEntity { + private String action; + private String mapperKey; + private String version; + private String env; + private boolean available; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/mapper/ApiAvailabilityMapper.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/mapper/ApiAvailabilityMapper.java new file mode 100644 index 000000000..112f6022f --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/mapper/ApiAvailabilityMapper.java @@ -0,0 +1,13 @@ +package com.consoleconnect.kraken.operator.controller.mapper; + +import com.consoleconnect.kraken.operator.controller.entity.ApiAvailabilityChangeHistoryEntity; +import com.consoleconnect.kraken.operator.controller.model.ApiAvailabilityChangeHistory; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper() +public interface ApiAvailabilityMapper { + ApiAvailabilityMapper INSTANCE = Mappers.getMapper(ApiAvailabilityMapper.class); + + ApiAvailabilityChangeHistory toChangeHistory(ApiAvailabilityChangeHistoryEntity entity); +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/ApiAvailabilityChangeHistory.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/ApiAvailabilityChangeHistory.java new file mode 100644 index 000000000..6125d72f3 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/ApiAvailabilityChangeHistory.java @@ -0,0 +1,13 @@ +package com.consoleconnect.kraken.operator.controller.model; + +import lombok.Data; + +@Data +public class ApiAvailabilityChangeHistory { + private String mapperKey; + private String updatedAt; + private String updatedBy; + private boolean available; + private String version; + private String env; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/UpdateAipAvailabilityRequest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/UpdateAipAvailabilityRequest.java index 8263204fc..a4a2b6877 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/UpdateAipAvailabilityRequest.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/model/UpdateAipAvailabilityRequest.java @@ -7,4 +7,5 @@ public class UpdateAipAvailabilityRequest { private String mapperKey; private boolean disabled; private String envName; + private String version; } diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java new file mode 100644 index 000000000..fa3c72ea4 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java @@ -0,0 +1,17 @@ +package com.consoleconnect.kraken.operator.controller.repo; + +import com.consoleconnect.kraken.operator.controller.entity.ApiAvailabilityChangeHistoryEntity; +import java.util.List; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.PagingAndSortingRepository; + +public interface ApiAvailabilityChangeHistoryRepository + extends PagingAndSortingRepository, + JpaRepository, + JpaSpecificationExecutor { + + List findAllByMapperKeyAndEnvOOrderByCreatedAtDesc( + String mapperKey, String env); +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java index 8baf65caf..6697f5d6d 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java @@ -9,7 +9,10 @@ import com.consoleconnect.kraken.operator.controller.dto.ComponentProductCategoryDTO; import com.consoleconnect.kraken.operator.controller.dto.EndPointUsageDTO; import com.consoleconnect.kraken.operator.controller.dto.SaveWorkflowTemplateRequest; +import com.consoleconnect.kraken.operator.controller.entity.ApiAvailabilityChangeHistoryEntity; +import com.consoleconnect.kraken.operator.controller.mapper.ApiAvailabilityMapper; import com.consoleconnect.kraken.operator.controller.model.*; +import com.consoleconnect.kraken.operator.controller.repo.ApiAvailabilityChangeHistoryRepository; import com.consoleconnect.kraken.operator.controller.tools.VersionHelper; import com.consoleconnect.kraken.operator.core.dto.ApiUseCaseDto; import com.consoleconnect.kraken.operator.core.dto.Tuple2; @@ -63,6 +66,7 @@ public class ApiComponentService @Getter private final EnvironmentService environmentService; private final UnifiedAssetRepository unifiedAssetRepository; private final AssetFacetRepository assetFacetRepository; + private final ApiAvailabilityChangeHistoryRepository changeHistoryRepository; private final AppProperty appProperty; @Transactional @@ -646,9 +650,30 @@ public IngestionDataResult updateApiAvailability( facets.getProdDisableApiList(), request.getMapperKey(), request.isDisabled()); } asset.setFacets(JsonToolkit.convertToMap(facets)); + recordChangeHistory(request, userId); return unifiedAssetService.syncAsset(MEF_SONATA, asset, syncMetadata, true); } + private void recordChangeHistory(UpdateAipAvailabilityRequest request, String userId) { + // record history + ApiAvailabilityChangeHistoryEntity changeHistory = new ApiAvailabilityChangeHistoryEntity(); + changeHistory.setMapperKey(request.getMapperKey()); + changeHistory.setEnv(request.getEnvName()); + changeHistory.setVersion(request.getVersion()); + changeHistory.setUpdatedBy(userId); + changeHistory.setAvailable(!request.isDisabled()); + changeHistoryRepository.save(changeHistory); + } + + public List getApiAvailabilityChangeHistory( + String mapperKey, String env) { + return changeHistoryRepository + .findAllByMapperKeyAndEnvOOrderByCreatedAtDesc(mapperKey, env) + .stream() + .map(ApiAvailabilityMapper.INSTANCE::toChangeHistory) + .toList(); + } + private void performDisableList(Set set, String key, boolean disabled) { if (disabled) { set.add(key); diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java index 764786b1a..e57749db5 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java @@ -24,6 +24,7 @@ import com.consoleconnect.kraken.operator.core.event.IngestionDataResult; import com.consoleconnect.kraken.operator.core.exception.KrakenException; import com.consoleconnect.kraken.operator.core.model.*; +import com.consoleconnect.kraken.operator.core.model.facet.ComponentAPIAvailabilityFacets; import com.consoleconnect.kraken.operator.core.model.facet.ComponentAPITargetFacets; import com.consoleconnect.kraken.operator.core.repo.EnvironmentClientRepository; import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository; @@ -687,10 +688,33 @@ public Paging retrieveApiMapperDeployments( List result = getApiMapperDeploymentDTOS(deployments, mapperAssetMap, mapper2Component, envId); + fillAvailabilityState(result); return PagingHelper.toPageNoSubList( result, deployments.getPage(), deployments.getSize(), deployments.getTotal()); } + private void fillAvailabilityState(List result) { + List assetDtoList = + unifiedAssetService.findByKind(AssetKindEnum.COMPONENT_API_AVAILABILITY.getKind()); + if (CollectionUtils.isNotEmpty(assetDtoList)) { + UnifiedAssetDto assetDto = assetDtoList.get(0); + ComponentAPIAvailabilityFacets facets = + UnifiedAsset.getFacets(assetDto, ComponentAPIAvailabilityFacets.class); + Set stageDisableApiList = + facets.getStageDisableApiList() == null + ? new HashSet<>() + : facets.getStageDisableApiList(); + Set prodDisableApiList = + facets.getProdDisableApiList() == null ? new HashSet<>() : facets.getProdDisableApiList(); + result.stream() + .forEach( + dto -> { + dto.setStageAvailable(stageDisableApiList.contains(dto.getTargetMapperKey())); + dto.setProdAvailable(prodDisableApiList.contains(dto.getTargetMapperKey())); + }); + } + } + private @NotNull List getApiMapperDeploymentDTOS( Paging allDeploymentsPage, Map mapperAssetMap, From ff11c5e0076c32828d0f6798a552aaa0c76d1a0b Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Thu, 14 Aug 2025 10:22:03 +0800 Subject: [PATCH 2/7] record api availability change history --- .../ApiAvailabilityChangeHistoryEntity.java | 5 ++ ...piAvailabilityChangeHistoryRepository.java | 2 +- .../service/ApiComponentService.java | 2 +- .../service/ProductDeploymentService.java | 76 ++++++++++--------- .../ComponentMgmtControllerTest.java | 23 ++++++ 5 files changed, 69 insertions(+), 39 deletions(-) diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java index 7a62d3dfb..0dab39253 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/entity/ApiAvailabilityChangeHistoryEntity.java @@ -1,6 +1,7 @@ package com.consoleconnect.kraken.operator.controller.entity; import com.consoleconnect.kraken.operator.core.entity.AbstractEntity; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Table; import lombok.Getter; @@ -11,8 +12,12 @@ @Setter @Table(name = "kraken_mgmt_api_availability_change_history") public class ApiAvailabilityChangeHistoryEntity extends AbstractEntity { + private String action; + + @Column(name = "mapper_key", nullable = false) private String mapperKey; + private String version; private String env; private boolean available; diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java index fa3c72ea4..2a7d2a5ae 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/repo/ApiAvailabilityChangeHistoryRepository.java @@ -12,6 +12,6 @@ public interface ApiAvailabilityChangeHistoryRepository JpaRepository, JpaSpecificationExecutor { - List findAllByMapperKeyAndEnvOOrderByCreatedAtDesc( + List findAllByMapperKeyAndEnvOrderByCreatedAtDesc( String mapperKey, String env); } diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java index 6697f5d6d..f392fa293 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java @@ -668,7 +668,7 @@ private void recordChangeHistory(UpdateAipAvailabilityRequest request, String us public List getApiAvailabilityChangeHistory( String mapperKey, String env) { return changeHistoryRepository - .findAllByMapperKeyAndEnvOOrderByCreatedAtDesc(mapperKey, env) + .findAllByMapperKeyAndEnvOrderByCreatedAtDesc(mapperKey, env) .stream() .map(ApiAvailabilityMapper.INSTANCE::toChangeHistory) .toList(); diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java index e57749db5..2b7e51289 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java @@ -688,7 +688,6 @@ public Paging retrieveApiMapperDeployments( List result = getApiMapperDeploymentDTOS(deployments, mapperAssetMap, mapper2Component, envId); - fillAvailabilityState(result); return PagingHelper.toPageNoSubList( result, deployments.getPage(), deployments.getSize(), deployments.getTotal()); } @@ -967,41 +966,44 @@ public List listRunningApiMapperDeploymentV3(String envI Map tagEntityMap = unifiedAssetService.findAllByIdIn(tagIds).stream() .collect(Collectors.toMap(t -> t.getId().toString(), t -> t)); - return mapper2PayLoadMap.entrySet().stream() - .map( - entry -> { - String mapperKey = entry.getKey(); - ClientMapperVersionPayloadDto payload = entry.getValue(); - UnifiedAssetEntity tagEntity = tagEntityMap.get(payload.getTagId()); - UnifiedAssetDto tagAsset = UnifiedAssetService.toAsset(tagEntity, false); - Map labels = tagAsset.getMetadata().getLabels(); - UnifiedAssetDto mapperAsset = mapperAssetMap.get(mapperKey); - ComponentAPITargetFacets componentAPITargetFacets = - UnifiedAsset.getFacets(mapperAsset, ComponentAPITargetFacets.class); - ComponentAPITargetFacets.Trigger trigger = componentAPITargetFacets.getTrigger(); - ApiMapperDeploymentDTO deploymentDTO = new ApiMapperDeploymentDTO(); - if (trigger != null) { - BeanUtils.copyProperties(trigger, deploymentDTO); - ComponentExpandDTO.MappingMatrix mappingMatrix = - new ComponentExpandDTO.MappingMatrix(); - BeanUtils.copyProperties(trigger, mappingMatrix); - deploymentDTO.setMappingMatrix(mappingMatrix); - } - deploymentDTO.setCreateAt(tagAsset.getCreatedAt()); - deploymentDTO.setCreateBy(tagAsset.getCreatedBy()); - setUserName(deploymentDTO); - deploymentDTO.setStatus(DeployStatusEnum.SUCCESS.name()); - deploymentDTO.setTargetMapperKey(mapperKey); - deploymentDTO.setVersion(labels.get(LABEL_VERSION_NAME)); - deploymentDTO.setSubVersion(labels.get(LABEL_SUB_VERSION_NAME)); - deploymentDTO.setTagId(payload.getTagId()); - deploymentDTO.setEnvId(environment.getId()); - deploymentDTO.setEnvName(environment.getName()); - deploymentDTO.setComponentKey(mapper2Component.get(mapperKey).getKey()); - deploymentDTO.setComponentName(mapper2Component.get(mapperKey).getValue()); - return deploymentDTO; - }) - .sorted(Comparator.comparing(ApiMapperDeploymentDTO::getCreateAt).reversed()) - .toList(); + List result = + mapper2PayLoadMap.entrySet().stream() + .map( + entry -> { + String mapperKey = entry.getKey(); + ClientMapperVersionPayloadDto payload = entry.getValue(); + UnifiedAssetEntity tagEntity = tagEntityMap.get(payload.getTagId()); + UnifiedAssetDto tagAsset = UnifiedAssetService.toAsset(tagEntity, false); + Map labels = tagAsset.getMetadata().getLabels(); + UnifiedAssetDto mapperAsset = mapperAssetMap.get(mapperKey); + ComponentAPITargetFacets componentAPITargetFacets = + UnifiedAsset.getFacets(mapperAsset, ComponentAPITargetFacets.class); + ComponentAPITargetFacets.Trigger trigger = componentAPITargetFacets.getTrigger(); + ApiMapperDeploymentDTO deploymentDTO = new ApiMapperDeploymentDTO(); + if (trigger != null) { + BeanUtils.copyProperties(trigger, deploymentDTO); + ComponentExpandDTO.MappingMatrix mappingMatrix = + new ComponentExpandDTO.MappingMatrix(); + BeanUtils.copyProperties(trigger, mappingMatrix); + deploymentDTO.setMappingMatrix(mappingMatrix); + } + deploymentDTO.setCreateAt(tagAsset.getCreatedAt()); + deploymentDTO.setCreateBy(tagAsset.getCreatedBy()); + setUserName(deploymentDTO); + deploymentDTO.setStatus(DeployStatusEnum.SUCCESS.name()); + deploymentDTO.setTargetMapperKey(mapperKey); + deploymentDTO.setVersion(labels.get(LABEL_VERSION_NAME)); + deploymentDTO.setSubVersion(labels.get(LABEL_SUB_VERSION_NAME)); + deploymentDTO.setTagId(payload.getTagId()); + deploymentDTO.setEnvId(environment.getId()); + deploymentDTO.setEnvName(environment.getName()); + deploymentDTO.setComponentKey(mapper2Component.get(mapperKey).getKey()); + deploymentDTO.setComponentName(mapper2Component.get(mapperKey).getValue()); + return deploymentDTO; + }) + .sorted(Comparator.comparing(ApiMapperDeploymentDTO::getCreateAt).reversed()) + .toList(); + fillAvailabilityState(result); + return result; } } diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java index 97583e070..a935f621b 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java @@ -62,6 +62,9 @@ public class ComponentMgmtControllerTest extends AbstractIntegrationTest "/products/kraken.component.api-target-mapper/components/{id}/targetMapper"; public static final String DISABLE_TARGET_MAPPER = "/products/kraken.component.api-target-mapper/components/disableTargetMapper"; + public static final String API_AVAILABILITY_CHANGE_HISTORY = + "/products/mef.sonata/components/apiAvailability/change-history"; + public static final String UPDATE_WORKFLOW = "/products/kraken.component.api-target-mapper/components/{id}/workflow"; public static final String LIST_API_USE_CASES = @@ -510,4 +513,24 @@ void givenUpdateDisablePayload3_whenUpdateApiAvailability_thenThrowException() { assertThat(bodyStr, notNullValue()); }); } + + @Test + @Order(15) + void givenEnv_whenGetApiAvailabilityChangeHistory_thenReturnOK() { + getTestClientHelper() + .requestAndVerify( + HttpMethod.GET, + uriBuilder -> + uriBuilder + .path(API_AVAILABILITY_CHANGE_HISTORY) + .queryParam("env", "production") + .queryParam("mapperKey", "mef.sonata.api-target-mapper.order.eline.add") + .build(), + 200, + null, + bodyStr -> { + log.info(bodyStr); + assertThat(bodyStr, notNullValue()); + }); + } } From 42ca4ea5556bac83f26eaa860bbb4a567137627d Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Thu, 14 Aug 2025 11:01:47 +0800 Subject: [PATCH 3/7] set user name --- .../service/ApiComponentService.java | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java index f392fa293..bd7544386 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ApiComponentService.java @@ -4,11 +4,10 @@ import static com.consoleconnect.kraken.operator.core.toolkit.AssetsConstants.*; import static com.consoleconnect.kraken.operator.core.toolkit.LabelConstants.*; +import com.consoleconnect.kraken.operator.auth.entity.UserEntity; +import com.consoleconnect.kraken.operator.auth.repo.UserRepository; import com.consoleconnect.kraken.operator.auth.security.UserContext; -import com.consoleconnect.kraken.operator.controller.dto.ComponentExpandDTO; -import com.consoleconnect.kraken.operator.controller.dto.ComponentProductCategoryDTO; -import com.consoleconnect.kraken.operator.controller.dto.EndPointUsageDTO; -import com.consoleconnect.kraken.operator.controller.dto.SaveWorkflowTemplateRequest; +import com.consoleconnect.kraken.operator.controller.dto.*; import com.consoleconnect.kraken.operator.controller.entity.ApiAvailabilityChangeHistoryEntity; import com.consoleconnect.kraken.operator.controller.mapper.ApiAvailabilityMapper; import com.consoleconnect.kraken.operator.controller.model.*; @@ -68,6 +67,7 @@ public class ApiComponentService private final AssetFacetRepository assetFacetRepository; private final ApiAvailabilityChangeHistoryRepository changeHistoryRepository; private final AppProperty appProperty; + private final UserRepository userRepository; @Transactional public IngestionDataResult updateApiTargetMapper( @@ -665,12 +665,34 @@ private void recordChangeHistory(UpdateAipAvailabilityRequest request, String us changeHistoryRepository.save(changeHistory); } + private String getUserName(String id) { + String userName = UserContext.ANONYMOUS; + if (StringUtils.isNotBlank(id)) { + try { + UUID uuid = UUID.fromString(id); + Optional optionalUserEntity = userRepository.findById(uuid); + if (optionalUserEntity.isPresent()) { + return optionalUserEntity.get().getName(); + } + } catch (Exception e) { + log.error("failed to find user name"); + } + } + return userName; + } + public List getApiAvailabilityChangeHistory( String mapperKey, String env) { return changeHistoryRepository .findAllByMapperKeyAndEnvOrderByCreatedAtDesc(mapperKey, env) .stream() - .map(ApiAvailabilityMapper.INSTANCE::toChangeHistory) + .map( + entity -> { + ApiAvailabilityChangeHistory changeHistory = + ApiAvailabilityMapper.INSTANCE.toChangeHistory(entity); + changeHistory.setUpdatedBy(getUserName(entity.getCreatedBy())); + return changeHistory; + }) .toList(); } From 9b4ea15039e34c953f39ec884f62209a24b737e4 Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Thu, 14 Aug 2025 11:30:17 +0800 Subject: [PATCH 4/7] add unit test --- .../ComponentMgmtControllerTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java index a935f621b..15b2b6ce1 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/ComponentMgmtControllerTest.java @@ -3,13 +3,19 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; +import com.consoleconnect.kraken.operator.auth.entity.UserEntity; +import com.consoleconnect.kraken.operator.auth.repo.UserRepository; import com.consoleconnect.kraken.operator.auth.security.UserContext; import com.consoleconnect.kraken.operator.config.TestApplication; import com.consoleconnect.kraken.operator.controller.dto.ComponentExpandDTO; import com.consoleconnect.kraken.operator.controller.dto.SaveWorkflowTemplateRequest; +import com.consoleconnect.kraken.operator.controller.entity.ApiAvailabilityChangeHistoryEntity; import com.consoleconnect.kraken.operator.controller.model.Environment; import com.consoleconnect.kraken.operator.controller.model.UpdateAipAvailabilityRequest; +import com.consoleconnect.kraken.operator.controller.repo.ApiAvailabilityChangeHistoryRepository; import com.consoleconnect.kraken.operator.controller.service.EnvironmentService; import com.consoleconnect.kraken.operator.core.client.ClientEvent; import com.consoleconnect.kraken.operator.core.client.ClientEventTypeEnum; @@ -36,9 +42,11 @@ import org.apache.commons.lang3.StringUtils; import org.hamcrest.Matchers; import org.junit.jupiter.api.*; +import org.mockito.ArgumentMatchers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.test.context.ContextConfiguration; @@ -71,6 +79,8 @@ public class ComponentMgmtControllerTest extends AbstractIntegrationTest "/products/kraken.component.api-target-mapper/api-use-cases"; @Autowired UnifiedAssetService unifiedAssetService; @Getter @Autowired EnvironmentService environmentService; + @MockBean UserRepository userRepository; + @MockBean ApiAvailabilityChangeHistoryRepository changeHistoryRepository; @Autowired public ComponentMgmtControllerTest(WebTestClient webTestClient) { @@ -517,6 +527,16 @@ void givenUpdateDisablePayload3_whenUpdateApiAvailability_thenThrowException() { @Test @Order(15) void givenEnv_whenGetApiAvailabilityChangeHistory_thenReturnOK() { + UserEntity userEntity = new UserEntity(); + userEntity.setName("mock-user"); + when(userRepository.findById(ArgumentMatchers.any())).thenReturn(Optional.of(userEntity)); + ApiAvailabilityChangeHistoryEntity changeHistory = new ApiAvailabilityChangeHistoryEntity(); + changeHistory.setCreatedBy(UUID.randomUUID().toString()); + ApiAvailabilityChangeHistoryEntity changeHistory1 = new ApiAvailabilityChangeHistoryEntity(); + changeHistory1.setCreatedBy("user-id"); + when(changeHistoryRepository.findAllByMapperKeyAndEnvOrderByCreatedAtDesc( + anyString(), anyString())) + .thenReturn(List.of(changeHistory, changeHistory1)); getTestClientHelper() .requestAndVerify( HttpMethod.GET, From c048b402a224a52340ad78e2cbf8265543de2b67 Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Thu, 14 Aug 2025 14:28:22 +0800 Subject: [PATCH 5/7] fix configuration --- .../kraken-app-controller/src/main/resources/application.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kraken-app/kraken-app-controller/src/main/resources/application.yaml b/kraken-app/kraken-app-controller/src/main/resources/application.yaml index 380829a33..0b18aa757 100644 --- a/kraken-app/kraken-app-controller/src/main/resources/application.yaml +++ b/kraken-app/kraken-app-controller/src/main/resources/application.yaml @@ -127,7 +127,7 @@ app: exclude-keys: - mef.sonata.api-target.order.notification.state.change token-storage: - enabled: fase + enabled: false engine: postgres vault: namespace: secret/data From aee5923eb211260a07c7376d9773d86da9d3c5d9 Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Thu, 14 Aug 2025 16:06:49 +0800 Subject: [PATCH 6/7] disable use case page --- .../src/hooks/product/index.ts | 34 +++++++++++++++++-- .../components/RunningAPIMapping/index.tsx | 28 +++++++++++++-- .../src/services/products.ts | 29 ++++++++++++++++ .../src/utils/types/env.type.ts | 11 ++++++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/kraken-app/kraken-app-portal/src/hooks/product/index.ts b/kraken-app/kraken-app-portal/src/hooks/product/index.ts index 6ae19e8a7..fb4e769fd 100644 --- a/kraken-app/kraken-app-portal/src/hooks/product/index.ts +++ b/kraken-app/kraken-app-portal/src/hooks/product/index.ts @@ -46,7 +46,7 @@ import { getValidateServerName, editContactInformation, getProductTypes, - rotateApiKey, + rotateApiKey, disableApiUseCase, getAPIUscCaseChangeHistory, } from "@/services/products"; import { STALE_TIME } from "@/utils/constants/common"; import { @@ -71,7 +71,7 @@ import { import { IActivityDetail, IActivityLog, - IApiKeyDetail, + IApiKeyDetail, IApiUseCaseChangeHistory, IDataPlaneDetail, IEnv, IMapperDetails, @@ -146,6 +146,8 @@ export const PRODUCT_CACHE_KEYS = { verify_product: "verify_product", edit_contact_information: "edit_contact_information", get_product_type_list: "get_product_type_list", + disable_api_use_case: "disable_api_use_case", + get_api_use_case_change_history: "get_api_use_case_change_history", }; export const useCreateNewComponent = () => { @@ -616,6 +618,34 @@ export const useGetRunningAPIList = ( }); }; +export const useDisableApiUseCase = ( + productId: string, + params: Record +) => { + return useMutation({ + mutationKey: [PRODUCT_CACHE_KEYS.disable_api_use_case], + mutationFn: ({ productId, mapperKey, envName, checked, version}: any) => + disableApiUseCase(productId, mapperKey, envName, version, checked), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [PRODUCT_CACHE_KEYS.get_running_api_list], + }); + }, + }); +}; + +export const useGetApiUseCaseChangeHistory = ( + productId: string, + params: Record +) => { + return useQuery({ + queryKey: [PRODUCT_CACHE_KEYS.get_api_use_case_change_history, productId, params], + queryFn: () => getAPIUscCaseChangeHistory(productId, params), + enabled: Boolean(productId) && Boolean(params.mapperKey), + select: (data) => data?.data, + }); +}; + export const useGetAPIDeployments = ( productId: string, params: Record diff --git a/kraken-app/kraken-app-portal/src/pages/EnvironmentOverview/components/RunningAPIMapping/index.tsx b/kraken-app/kraken-app-portal/src/pages/EnvironmentOverview/components/RunningAPIMapping/index.tsx index 93ed7fe6d..aed9a56fe 100644 --- a/kraken-app/kraken-app-portal/src/pages/EnvironmentOverview/components/RunningAPIMapping/index.tsx +++ b/kraken-app/kraken-app-portal/src/pages/EnvironmentOverview/components/RunningAPIMapping/index.tsx @@ -1,13 +1,14 @@ import { ApiCard } from "@/components/ApiMapping"; import { Text } from "@/components/Text"; -import { useGetRunningAPIList } from "@/hooks/product"; +import {useDisableApiUseCase, useGetRunningAPIList} from "@/hooks/product"; import { useAppStore } from "@/stores/app.store"; import { IEnv, IRunningMapping } from "@/utils/types/env.type"; -import { Flex, Table, Tag, Typography } from "antd"; +import {Badge, Flex, Switch, Table, Tag, Typography} from "antd"; import { useMemo } from "react"; import { ColumnsType } from "antd/es/table"; import { toDateTime } from "@/libs/dayjs"; import styles from './index.module.scss' +import {ClockCircleOutlined, HistoryOutlined} from "@ant-design/icons"; type Props = { scrollHeight: number; @@ -24,6 +25,15 @@ const RunningAPIMapping = ({ scrollHeight, env }: Props) => { direction: "DESC", }); + const onStatusChange = (checked, item: GroupedMapping) => { + useDisableApiUseCase(currentProduct, { + mapperKey: item.targetMapperKey, + envName: env?.name, + checked, + version: item.version, + }); + } + const mappings = useMemo(() => { if (!data) return [] @@ -87,6 +97,20 @@ const RunningAPIMapping = ({ scrollHeight, env }: Props) => { ), }, + { + title: "Status", + width: 120, + render: (item: GroupedMapping) => ( + {onStatusChange(checked, item)}} /> + ), + }, + { + title: "History", + width: 90, + render: (item: GroupedMapping) => ( + + ), + }, ]; return ( diff --git a/kraken-app/kraken-app-portal/src/services/products.ts b/kraken-app/kraken-app-portal/src/services/products.ts index 7aaf2945d..2d8660081 100644 --- a/kraken-app/kraken-app-portal/src/services/products.ts +++ b/kraken-app/kraken-app-portal/src/services/products.ts @@ -257,6 +257,35 @@ export const getRunningAPIMappingList = ( }); }; +export const disableApiUseCase = ( + productId: string, + mapperKey: string, + envName: string, + version: string, + checked: boolean, +) => { + return request(`/products/${productId}/components/disableTargetMapper`, { + method: "PATCH", + data: { + mapperKey, + envName, + version, + disable: !checked + } + }); +}; + +export const getAPIUscCaseChangeHistory = ( + productId: string, + params +) => { + return request(`/v3${PRODUCT}/${productId}/components/apiAvailability/change-history`, { + method: "GET", + params, + }); +}; + + export const getAPIMapperDeployments = ( productId: string, params: Record diff --git a/kraken-app/kraken-app-portal/src/utils/types/env.type.ts b/kraken-app/kraken-app-portal/src/utils/types/env.type.ts index 0a56d7a3e..76d27ab0e 100644 --- a/kraken-app/kraken-app-portal/src/utils/types/env.type.ts +++ b/kraken-app/kraken-app-portal/src/utils/types/env.type.ts @@ -92,6 +92,17 @@ export interface IRunningMapping { version: string; status: string; mappingStatus: string; + stageAvailable?: boolean; + prodAvailable?: boolean; +} + +export interface IApiUseCaseChangeHistory { + mapperKey: string; + updatedAt: string; + updatedBy: string; + available: boolean; + version: string; + env: string; } export interface IRunningComponentItem { From 9240346720130510e7a2ce99af24a4e96d2f6789 Mon Sep 17 00:00:00 2001 From: zhiyaoPCCW Date: Fri, 15 Aug 2025 17:06:06 +0800 Subject: [PATCH 7/7] disable use case --- .../operator/controller/service/ProductDeploymentService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java index 2b7e51289..7e2720e37 100644 --- a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/ProductDeploymentService.java @@ -708,8 +708,8 @@ private void fillAvailabilityState(List result) { result.stream() .forEach( dto -> { - dto.setStageAvailable(stageDisableApiList.contains(dto.getTargetMapperKey())); - dto.setProdAvailable(prodDisableApiList.contains(dto.getTargetMapperKey())); + dto.setStageAvailable(!stageDisableApiList.contains(dto.getTargetMapperKey())); + dto.setProdAvailable(!prodDisableApiList.contains(dto.getTargetMapperKey())); }); } }