From 1d3610f6f0565c4fdd55b8a0457ebb93c1d5d4fa Mon Sep 17 00:00:00 2001 From: ds-ext-sceronik Date: Wed, 8 Nov 2023 14:49:18 +0100 Subject: [PATCH 1/6] feature: TRACEFOSS-2796 count query temp --- .../mapper/AssetAsBuiltFieldMapper.java | 3 +- .../common/model/SearchCriteriaStrategy.java | 3 +- .../common/repository/BaseSpecification.java | 23 +++++++++ .../alert/model/AlertEntity.java | 2 +- .../AssetAsBuiltControllerFilteringIT.java | 48 ++++++++++++++++++- 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java index 2a048551b9..3ae2c6b67d 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java @@ -48,7 +48,8 @@ public class AssetAsBuiltFieldMapper extends BaseRequestFieldMapper { Map.entry("semanticDataModel", "semanticDataModel"), Map.entry("semanticModelId", "semanticModelId"), Map.entry("van", "van"), - Map.entry("businessPartner", "manufacturerId") + Map.entry("businessPartner", "manufacturerId"), + Map.entry("alerts", "alerts") ); @Override diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java index 235ed133a6..51e118cffa 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java @@ -24,5 +24,6 @@ public enum SearchCriteriaStrategy { STARTS_WITH, AT_LOCAL_DATE, AFTER_LOCAL_DATE, - BEFORE_LOCAL_DATE + BEFORE_LOCAL_DATE, + COUNT_EQUAL } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java index dd3f7eab89..5a7b119546 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java @@ -19,26 +19,34 @@ package org.eclipse.tractusx.traceability.common.repository; +import jakarta.persistence.ManyToMany; import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Join; +import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.Selection; +import jakarta.persistence.criteria.Subquery; import lombok.Getter; import org.eclipse.tractusx.traceability.common.domain.ParseLocalDateException; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaFilter; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaOperator; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy; +import org.eclipse.tractusx.traceability.qualitynotification.infrastructure.alert.model.AlertEntity; import org.springframework.data.jpa.domain.Specification; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy; import static org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy.AFTER_LOCAL_DATE; import static org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy.BEFORE_LOCAL_DATE; @@ -88,6 +96,21 @@ protected Predicate createPredicate(SearchCriteriaFilter criteria, Root root, return builder.greaterThanOrEqualTo(fieldPath.as(LocalDateTime.class), LocalDateTime.of(localDate, LocalTime.MIN)); } + if (SearchCriteriaStrategy.COUNT_EQUAL.equals(criteria.getStrategy())) { + CriteriaQuery query = builder.createQuery(Long.class); + Subquery subquery = query.subquery(Long.class); + Join join = root.join("alerts"); +// subquery.select(builder.count(join)).from(root); + + + return builder.equal(builder.count(subquery.select(builder.count(join)).from(AlertEntity.class)), "6"); + +// return builder.equal(joinAlerts.get("side").as(String.class), "SENDER"); +// return builder.equal(joinAlerts.get("assets"), joinAlerts.getParent().get("alerts")); + // select a1_0.id,a1_0.active_alert,a1_0.classification,a1_0.customer_part_id,a1_0.id_short,a1_0.in_investigation,a1_0.manufacturer_id,a1_0.manufacturer_name,a1_0.manufacturer_part_id,a1_0.manufacturing_country,a1_0.manufacturing_date,a1_0.name_at_customer,a1_0.name_at_manufacturer,a1_0.owner,a1_0.product_type,a1_0.quality_type,a1_0.semantic_data_model,a1_0.semantic_model_id,a1_0.traction_battery_code,a1_0.van from assets_as_built a1_0 join assets_as_built_alerts a2_0 on a1_0.id=a2_0.asset_id where count(a2_0.alert_id)=? offset ? rows fetch first ? rows only + + } + return null; } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/infrastructure/alert/model/AlertEntity.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/infrastructure/alert/model/AlertEntity.java index 32ae980e04..913e92932d 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/infrastructure/alert/model/AlertEntity.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/infrastructure/alert/model/AlertEntity.java @@ -60,7 +60,7 @@ public class AlertEntity extends NotificationBaseEntity { joinColumns = @JoinColumn(name = "alert_id"), inverseJoinColumns = @JoinColumn(name = "asset_id") ) - private List assets; + public List assets; @ManyToMany(cascade = CascadeType.ALL) @JoinTable( diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java index f11ee62e0e..25feb6c8af 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java @@ -20,16 +20,29 @@ package org.eclipse.tractusx.traceability.integration.assets; import io.restassured.http.ContentType; +import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.model.AssetAsBuiltEntity; import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.repository.JpaAssetAsBuiltRepository; import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification; +import org.eclipse.tractusx.traceability.integration.common.support.AlertsSupport; import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport; import org.jose4j.lang.JoseException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; + import static io.restassured.RestAssured.given; import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACCEPTED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACKNOWLEDGED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CANCELED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CLOSED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CREATED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.DECLINED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.RECEIVED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.SENT; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; class AssetAsBuiltControllerFilteringIT extends IntegrationTestSpecification { @@ -37,7 +50,10 @@ class AssetAsBuiltControllerFilteringIT extends IntegrationTestSpecification { AssetsSupport assetsSupport; @Autowired - JpaAssetAsBuiltRepository repo; + JpaAssetAsBuiltRepository jpaAssetAsBuiltRepository; + + @Autowired + AlertsSupport alertsSupport; @Test void givenNoFilter_whenCallFilteredEndpoint_thenReturnExpectedResult() throws JoseException { @@ -319,4 +335,34 @@ void givenNonExistingFilterField_whenGetAssetsAsBuilt_thenBadRequest() throws Jo .log().all() .statusCode(400); } + + @Test + void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseException { + // Given + assetsSupport.defaultAssetsStored(); + AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); + alertsSupport.storeAlertWithStatusAndAssets(CREATED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(SENT, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(RECEIVED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(ACKNOWLEDGED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(ACCEPTED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(DECLINED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(CANCELED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(CLOSED, List.of(assetAsBuilt), null); + + final String filter = "alerts,COUNT_EQUAL,5,AND"; + + // When + given() + .header(oAuth2Support.jwtAuthorization(ADMIN)) + .contentType(ContentType.JSON) + .when() + .param("filter", filter) + .get("/api/assets/as-built") + .then() + .log().all() + .statusCode(200) + .assertThat() + .body("totalItems", equalTo(1)); + } } From b5761050d2e61ed3437cb26802adc18816ae1f8a Mon Sep 17 00:00:00 2001 From: ds-ext-sceronik Date: Wed, 8 Nov 2023 17:06:17 +0100 Subject: [PATCH 2/6] feature: TRACEFOSS-2796 partial count working --- .../common/model/SearchCriteriaStrategy.java | 3 ++- .../common/repository/BaseSpecification.java | 19 +++++++++---------- .../AssetAsBuiltControllerFilteringIT.java | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java index 51e118cffa..3d71382852 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java @@ -25,5 +25,6 @@ public enum SearchCriteriaStrategy { AT_LOCAL_DATE, AFTER_LOCAL_DATE, BEFORE_LOCAL_DATE, - COUNT_EQUAL + COUNT_EQUAL, + COUNT_EQUALA } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java index 5a7b119546..2ab38e2046 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java @@ -98,17 +98,16 @@ protected Predicate createPredicate(SearchCriteriaFilter criteria, Root root, } if (SearchCriteriaStrategy.COUNT_EQUAL.equals(criteria.getStrategy())) { CriteriaQuery query = builder.createQuery(Long.class); - Subquery subquery = query.subquery(Long.class); +// Subquery subquery = query.subquery(Long.class); Join join = root.join("alerts"); -// subquery.select(builder.count(join)).from(root); - - - return builder.equal(builder.count(subquery.select(builder.count(join)).from(AlertEntity.class)), "6"); - -// return builder.equal(joinAlerts.get("side").as(String.class), "SENDER"); -// return builder.equal(joinAlerts.get("assets"), joinAlerts.getParent().get("alerts")); - // select a1_0.id,a1_0.active_alert,a1_0.classification,a1_0.customer_part_id,a1_0.id_short,a1_0.in_investigation,a1_0.manufacturer_id,a1_0.manufacturer_name,a1_0.manufacturer_part_id,a1_0.manufacturing_country,a1_0.manufacturing_date,a1_0.name_at_customer,a1_0.name_at_manufacturer,a1_0.owner,a1_0.product_type,a1_0.quality_type,a1_0.semantic_data_model,a1_0.semantic_model_id,a1_0.traction_battery_code,a1_0.van from assets_as_built a1_0 join assets_as_built_alerts a2_0 on a1_0.id=a2_0.asset_id where count(a2_0.alert_id)=? offset ? rows fetch first ? rows only - +// subquery.select(builder.count(join)); +// subquery.from(join.getJavaType()); +// Predicate a = builder.greaterThanOrEqualTo(builder.size(root.get("alerts")), Integer.parseInt(expectedFieldValue)); + Predicate b = builder.equal(builder.size(root.get("alerts")), 8); + Predicate c = builder.equal(join.get("status").as(String.class), "CREATED"); +// return builder.lessThanOrEqualTo(builder.size(root.get("alerts")), Integer.parseInt(expectedFieldValue)); + return builder.and(b,c); +// return b; } return null; diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java index 25feb6c8af..7fc8fee80b 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java @@ -350,7 +350,7 @@ void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseEx alertsSupport.storeAlertWithStatusAndAssets(CANCELED, List.of(assetAsBuilt), null); alertsSupport.storeAlertWithStatusAndAssets(CLOSED, List.of(assetAsBuilt), null); - final String filter = "alerts,COUNT_EQUAL,5,AND"; + final String filter = "alerts,COUNT_EQUAL,8,AND"; // When given() From 0dd5a3e3bbd201b00708d982dc4d1e572d43c8db Mon Sep 17 00:00:00 2001 From: ds-ext-sceronik Date: Wed, 8 Nov 2023 21:04:40 +0100 Subject: [PATCH 3/6] feature: TRACEFOSS-2796 refactor and implementation of custom count for assets as built notifications --- .../mapper/AssetAsBuiltFieldMapper.java | 4 +- .../mapper/AssetAsBuiltResponseMapper.java | 4 +- .../mapper/AssetAsPlannedResponseMapper.java | 4 +- .../base/mapper/AssetBaseResponseMapper.java | 2 +- .../repository/AssetAsBuildSpecification.java | 50 +++++++++++++++++++ .../common/model/SearchCriteriaStrategy.java | 3 +- .../common/repository/BaseSpecification.java | 23 +-------- .../base/model/QualityNotificationStatus.java | 4 ++ .../AssetAsBuiltControllerFilteringIT.java | 36 ++++++++++++- 9 files changed, 99 insertions(+), 31 deletions(-) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java index 3ae2c6b67d..550c9e007a 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltFieldMapper.java @@ -49,7 +49,9 @@ public class AssetAsBuiltFieldMapper extends BaseRequestFieldMapper { Map.entry("semanticModelId", "semanticModelId"), Map.entry("van", "van"), Map.entry("businessPartner", "manufacturerId"), - Map.entry("alerts", "alerts") + Map.entry("alerts", "alerts"), + Map.entry("qualityAlertIdsInStatusActive", "activeAlertsCount"), + Map.entry("qualityInvestigationIdsInStatusActive", "activeInvestigationsCount") ); @Override diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltResponseMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltResponseMapper.java index 10cfb0c4b8..ba2ab1a0cb 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltResponseMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asbuilt/mapper/AssetAsBuiltResponseMapper.java @@ -54,8 +54,8 @@ public static AssetAsBuiltResponse from(final AssetBase asset) { .van(asset.getVan()) .semanticDataModel(from(asset.getSemanticDataModel())) .detailAspectModels(fromList(asset.getDetailAspectModels())) - .qualityAlertIdsInStatusActive(gettNotificationIdsInActiveState(asset.getQualityAlerts())) - .qualityInvestigationIdsInStatusActive(gettNotificationIdsInActiveState(asset.getQualityInvestigations())) + .qualityAlertIdsInStatusActive(getNotificationIdsInActiveState(asset.getQualityAlerts())) + .qualityInvestigationIdsInStatusActive(getNotificationIdsInActiveState(asset.getQualityInvestigations())) .build(); } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asplanned/mapper/AssetAsPlannedResponseMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asplanned/mapper/AssetAsPlannedResponseMapper.java index 4c6f391b4e..f87420fbdc 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asplanned/mapper/AssetAsPlannedResponseMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/asplanned/mapper/AssetAsPlannedResponseMapper.java @@ -54,8 +54,8 @@ public static AssetAsPlannedResponse from(final AssetBase asset) { .van(asset.getVan()) .semanticDataModel(from(asset.getSemanticDataModel())) .detailAspectModels(fromList(asset.getDetailAspectModels())) - .qualityAlertIdsInStatusActive(gettNotificationIdsInActiveState(asset.getQualityAlerts())) - .qualityInvestigationIdsInStatusActive(gettNotificationIdsInActiveState(asset.getQualityInvestigations())) + .qualityAlertIdsInStatusActive(getNotificationIdsInActiveState(asset.getQualityAlerts())) + .qualityInvestigationIdsInStatusActive(getNotificationIdsInActiveState(asset.getQualityInvestigations())) .build(); } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/base/mapper/AssetBaseResponseMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/base/mapper/AssetBaseResponseMapper.java index dcf9449805..e69056bdf9 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/base/mapper/AssetBaseResponseMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/application/base/mapper/AssetBaseResponseMapper.java @@ -135,7 +135,7 @@ public static SemanticDataModelResponse from(final SemanticDataModel semanticDat return SemanticDataModelResponse.valueOf(semanticDataModel.name()); } - protected static List gettNotificationIdsInActiveState(List notifications) { + protected static List getNotificationIdsInActiveState(List notifications) { return emptyIfNull(notifications).stream() .filter(QualityNotification::isActiveState) .map(QualityNotification::getNotificationId) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/asbuilt/repository/AssetAsBuildSpecification.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/asbuilt/repository/AssetAsBuildSpecification.java index ed7a3f2e05..c4e3cca907 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/asbuilt/repository/AssetAsBuildSpecification.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/asbuilt/repository/AssetAsBuildSpecification.java @@ -23,12 +23,19 @@ import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.Subquery; import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.model.AssetAsBuiltEntity; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaFilter; +import org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy; import org.eclipse.tractusx.traceability.common.repository.BaseSpecification; +import org.eclipse.tractusx.traceability.qualitynotification.domain.base.model.QualityNotificationStatus; +import org.eclipse.tractusx.traceability.qualitynotification.infrastructure.alert.model.AlertEntity; +import org.eclipse.tractusx.traceability.qualitynotification.infrastructure.investigation.model.InvestigationEntity; import org.jetbrains.annotations.NotNull; import org.springframework.data.jpa.domain.Specification; +import java.util.List; + public class AssetAsBuildSpecification extends BaseSpecification implements Specification { public AssetAsBuildSpecification(SearchCriteriaFilter criteria) { @@ -37,6 +44,49 @@ public AssetAsBuildSpecification(SearchCriteriaFilter criteria) { @Override public Predicate toPredicate(@NotNull Root root, @NotNull CriteriaQuery query, @NotNull CriteriaBuilder builder) { + if (SearchCriteriaStrategy.NOTIFICATION_COUNT_EQUAL.equals(getSearchCriteriaFilter().getStrategy())) { + return activeNotificationCountEqualPredicate(getSearchCriteriaFilter(), root, builder, getSearchCriteriaFilter().getValue()); + } + return createPredicate(getSearchCriteriaFilter(), root, builder); } + + + private static Predicate activeNotificationCountEqualPredicate(SearchCriteriaFilter criteria, Root root, CriteriaBuilder builder, String expectedFieldValue) { + String joinTableName; + Class notificationClass; + switch (criteria.getKey()) { + case "activeAlertsCount" -> { + notificationClass = AlertEntity.class; + joinTableName = "alerts"; + } + case "activeInvestigationsCount" -> { + notificationClass = InvestigationEntity.class; + joinTableName = "investigations"; + } + default -> throw new UnsupportedOperationException(); + } + + CriteriaQuery cq = builder.createQuery(); + + Subquery sub = cq.subquery(Long.class); + Root subRoot = sub.from(notificationClass); + sub.select(builder.count(subRoot.get("id"))); + sub.where( + builder.or( + activeNotificationPredicates(builder, subRoot) + ) + ); + root.join(joinTableName); + + return builder.equal(sub, Integer.parseInt(expectedFieldValue)); + } + + private static Predicate[] activeNotificationPredicates(CriteriaBuilder builder, Root root) { + List predicates = QualityNotificationStatus.getActiveStates().stream() + .map(state -> builder.equal(root.get("status").as(String.class), state.name())) + .toList(); + + return predicates.toArray(new Predicate[0]); + } } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java index 3d71382852..daab1ac888 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/model/SearchCriteriaStrategy.java @@ -25,6 +25,5 @@ public enum SearchCriteriaStrategy { AT_LOCAL_DATE, AFTER_LOCAL_DATE, BEFORE_LOCAL_DATE, - COUNT_EQUAL, - COUNT_EQUALA + NOTIFICATION_COUNT_EQUAL } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java index 2ab38e2046..204f1636e2 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/common/repository/BaseSpecification.java @@ -19,34 +19,26 @@ package org.eclipse.tractusx.traceability.common.repository; -import jakarta.persistence.ManyToMany; import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Join; -import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; -import jakarta.persistence.criteria.Selection; -import jakarta.persistence.criteria.Subquery; import lombok.Getter; import org.eclipse.tractusx.traceability.common.domain.ParseLocalDateException; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaFilter; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaOperator; import org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy; -import org.eclipse.tractusx.traceability.qualitynotification.infrastructure.alert.model.AlertEntity; import org.springframework.data.jpa.domain.Specification; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import static java.util.stream.Collectors.counting; import static java.util.stream.Collectors.groupingBy; import static org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy.AFTER_LOCAL_DATE; import static org.eclipse.tractusx.traceability.common.model.SearchCriteriaStrategy.BEFORE_LOCAL_DATE; @@ -61,9 +53,9 @@ protected BaseSpecification(SearchCriteriaFilter searchCriteriaFilter) { } protected Predicate createPredicate(SearchCriteriaFilter criteria, Root root, CriteriaBuilder builder) { + String expectedFieldValue = criteria.getValue(); String fieldName = getJoinTableFieldName(criteria.getKey()); Path fieldPath = getFieldPath(root, criteria); - String expectedFieldValue = criteria.getValue(); if (SearchCriteriaStrategy.EQUAL.equals(criteria.getStrategy())) { return builder.equal( @@ -96,19 +88,6 @@ protected Predicate createPredicate(SearchCriteriaFilter criteria, Root root, return builder.greaterThanOrEqualTo(fieldPath.as(LocalDateTime.class), LocalDateTime.of(localDate, LocalTime.MIN)); } - if (SearchCriteriaStrategy.COUNT_EQUAL.equals(criteria.getStrategy())) { - CriteriaQuery query = builder.createQuery(Long.class); -// Subquery subquery = query.subquery(Long.class); - Join join = root.join("alerts"); -// subquery.select(builder.count(join)); -// subquery.from(join.getJavaType()); -// Predicate a = builder.greaterThanOrEqualTo(builder.size(root.get("alerts")), Integer.parseInt(expectedFieldValue)); - Predicate b = builder.equal(builder.size(root.get("alerts")), 8); - Predicate c = builder.equal(join.get("status").as(String.class), "CREATED"); -// return builder.lessThanOrEqualTo(builder.size(root.get("alerts")), Integer.parseInt(expectedFieldValue)); - return builder.and(b,c); -// return b; - } return null; } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/domain/base/model/QualityNotificationStatus.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/domain/base/model/QualityNotificationStatus.java index 72d784a646..c8b6f2b9ac 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/domain/base/model/QualityNotificationStatus.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/domain/base/model/QualityNotificationStatus.java @@ -99,6 +99,10 @@ public boolean isActiveState() { return ACTIVE_STATES.contains(this); } + public static List getActiveStates() { + return ACTIVE_STATES; + } + public static QualityNotificationStatus from(QualityNotificationStatusRequest qualityNotificationStatusRequest) { return QualityNotificationStatus.fromStringValue(qualityNotificationStatusRequest.name()); } diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java index 7fc8fee80b..081e9e565b 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java @@ -25,6 +25,7 @@ import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification; import org.eclipse.tractusx.traceability.integration.common.support.AlertsSupport; import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport; +import org.eclipse.tractusx.traceability.integration.common.support.InvestigationsSupport; import org.jose4j.lang.JoseException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -55,6 +56,9 @@ class AssetAsBuiltControllerFilteringIT extends IntegrationTestSpecification { @Autowired AlertsSupport alertsSupport; + @Autowired + InvestigationsSupport investigationsSupport; + @Test void givenNoFilter_whenCallFilteredEndpoint_thenReturnExpectedResult() throws JoseException { // given @@ -350,7 +354,7 @@ void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseEx alertsSupport.storeAlertWithStatusAndAssets(CANCELED, List.of(assetAsBuilt), null); alertsSupport.storeAlertWithStatusAndAssets(CLOSED, List.of(assetAsBuilt), null); - final String filter = "alerts,COUNT_EQUAL,8,AND"; + final String filter = "qualityAlertIdsInStatusActive,NOTIFICATION_COUNT_EQUAL,6,AND"; // When given() @@ -365,4 +369,34 @@ void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseEx .assertThat() .body("totalItems", equalTo(1)); } + + @Test + void givenInvestigationsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseException { + // Given + assetsSupport.defaultAssetsStored(); + AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); + investigationsSupport.storeInvestigationWithStatusAndAssets(CREATED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(SENT, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(RECEIVED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(ACKNOWLEDGED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(ACCEPTED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(DECLINED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(CANCELED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(CLOSED, List.of(assetAsBuilt), null); + + final String filter = "qualityInvestigationIdsInStatusActive,NOTIFICATION_COUNT_EQUAL,6,AND"; + + + // When + given() + .header(oAuth2Support.jwtAuthorization(ADMIN)) + .contentType(ContentType.JSON) + .when() + .param("filter", filter) + .get("/api/assets/as-built") + .then() + .statusCode(200) + .assertThat() + .body("totalItems", equalTo(1)); + } } From 441a547030f7e1c08b5046098f0f77043ed59a29 Mon Sep 17 00:00:00 2001 From: ds-ext-sceronik Date: Thu, 9 Nov 2023 08:02:18 +0100 Subject: [PATCH 4/6] feature: TRACEFOSS-2796 add changelog info --- CHANGELOG.md | 1 + .../openapi/traceability-foss-backend.json | 1468 ++++++++--------- 2 files changed, 735 insertions(+), 734 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9009907c8a..231fed94c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Cypress Login to E2E Environment to enable cypress e2e tests. - Fixed bug in argo workflow which allows to successfully run on INT-A/INT-B +- Added NOTIFICATION_COUNT_EQUAL filter strategy for Assets as built Specifications ### Changed - Fixed table-settings reset bug diff --git a/tx-backend/openapi/traceability-foss-backend.json b/tx-backend/openapi/traceability-foss-backend.json index c6bed5927a..7f7b8afe76 100644 --- a/tx-backend/openapi/traceability-foss-backend.json +++ b/tx-backend/openapi/traceability-foss-backend.json @@ -41,24 +41,24 @@ "description" : "The endpoint returns a result of BPN EDC URL mappings.", "operationId" : "getBpnEdcs", "responses" : { - "429" : { - "description" : "Too many requests.", + "200" : { + "description" : "Returns the paged result found", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "200" : { - "description" : "Returns the paged result found", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } @@ -73,8 +73,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -93,8 +93,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -103,8 +103,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -113,8 +113,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -155,20 +155,18 @@ "required" : true }, "responses" : { - "200" : { - "description" : "Returns the paged result found for BpnEdcMapping", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "429" : { - "description" : "Too many requests.", + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -177,18 +175,20 @@ } } }, - "500" : { - "description" : "Internal server error.", + "200" : { + "description" : "Returns the paged result found for BpnEdcMapping", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -207,8 +207,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -217,8 +217,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -227,8 +227,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -269,20 +269,18 @@ "required" : true }, "responses" : { - "200" : { - "description" : "Returns the paged result found for BpnEdcMapping", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "429" : { - "description" : "Too many requests.", + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -291,18 +289,20 @@ } } }, - "500" : { - "description" : "Internal server error.", + "200" : { + "description" : "Returns the paged result found for BpnEdcMapping", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -321,8 +321,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -331,8 +331,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -341,8 +341,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -380,14 +380,8 @@ } ], "responses" : { - "200" : { - "description" : "Returns the paged result found", - "content" : { - "application/json" : {} - } - }, - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -406,8 +400,14 @@ } } }, - "404" : { - "description" : "Not found.", + "200" : { + "description" : "Returns the paged result found", + "content" : { + "application/json" : {} + } + }, + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -426,8 +426,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -436,8 +436,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -446,8 +446,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -493,8 +493,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -513,8 +513,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -523,9 +523,6 @@ } } }, - "204" : { - "description" : "No Content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -536,8 +533,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -546,8 +543,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -556,8 +553,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -565,6 +562,9 @@ } } } + }, + "204" : { + "description" : "No Content." } }, "security" : [ @@ -603,8 +603,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -623,20 +623,18 @@ } } }, - "200" : { - "description" : "Returns the paged result found for Asset", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "404" : { - "description" : "Not found.", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { @@ -645,8 +643,8 @@ } } }, - "401" : { - "description" : "Authorization failed.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -655,8 +653,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -665,8 +663,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -675,12 +673,14 @@ } } }, - "400" : { - "description" : "Bad request.", + "200" : { + "description" : "Returns the paged result found for Asset", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } @@ -712,8 +712,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -732,8 +732,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -752,8 +752,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -762,8 +762,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -772,22 +772,22 @@ } } }, - "201" : { - "description" : "Created.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/QualityNotificationIdResponse" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "400" : { - "description" : "Bad request.", + "201" : { + "description" : "Created.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "$ref" : "#/components/schemas/QualityNotificationIdResponse" } } } @@ -832,8 +832,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -852,8 +852,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -862,9 +862,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -875,8 +872,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -885,8 +885,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -895,8 +895,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -945,8 +945,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -965,8 +965,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -975,9 +975,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -988,8 +985,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -998,8 +998,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1008,8 +1008,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1048,8 +1048,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1068,8 +1068,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1078,9 +1078,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -1091,8 +1088,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1101,8 +1098,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1111,8 +1108,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1120,6 +1117,9 @@ } } } + }, + "204" : { + "description" : "No content." } }, "security" : [ @@ -1151,8 +1151,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1171,8 +1171,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1181,9 +1181,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -1194,8 +1191,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1204,8 +1204,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1214,8 +1214,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1253,8 +1253,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1273,8 +1273,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1293,8 +1293,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1303,8 +1303,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1313,22 +1313,22 @@ } } }, - "201" : { - "description" : "Created.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/CreateNotificationContractResponse" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "400" : { - "description" : "Bad request.", + "201" : { + "description" : "Created.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "$ref" : "#/components/schemas/CreateNotificationContractResponse" } } } @@ -1362,8 +1362,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1382,8 +1382,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1402,8 +1402,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1412,8 +1412,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1422,11 +1422,8 @@ } } }, - "201" : { - "description" : "Created." - }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1434,6 +1431,9 @@ } } } + }, + "201" : { + "description" : "Created." } }, "security" : [ @@ -1464,20 +1464,18 @@ "required" : true }, "responses" : { - "200" : { - "description" : "Returns the paged result found for Asset", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "429" : { - "description" : "Too many requests.", + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -1486,8 +1484,8 @@ } } }, - "500" : { - "description" : "Internal server error.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1496,12 +1494,14 @@ } } }, - "404" : { - "description" : "Not found.", + "200" : { + "description" : "Returns the paged result found for Asset", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } @@ -1516,8 +1516,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1526,8 +1526,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1536,8 +1536,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1575,8 +1575,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1595,8 +1595,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1615,8 +1615,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1625,8 +1625,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1635,11 +1635,8 @@ } } }, - "201" : { - "description" : "Created." - }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1647,6 +1644,9 @@ } } } + }, + "201" : { + "description" : "Created." } }, "security" : [ @@ -1677,24 +1677,24 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "200" : { + "description" : "Returns the paged result found for Asset", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "200" : { - "description" : "Returns the paged result found for Asset", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } @@ -1709,8 +1709,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1729,8 +1729,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1739,8 +1739,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1749,8 +1749,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1796,8 +1796,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1816,19 +1816,18 @@ } } }, - "200" : { - "description" : "Returns the paged result found for Asset", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "404" : { - "description" : "Not found.", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { @@ -1837,8 +1836,8 @@ } } }, - "401" : { - "description" : "Authorization failed.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1847,8 +1846,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1857,8 +1856,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -1867,12 +1866,13 @@ } } }, - "400" : { - "description" : "Bad request.", + "200" : { + "description" : "Returns the paged result found for Asset", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "type" : "array" } } } @@ -1904,8 +1904,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -1924,8 +1924,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -1944,8 +1944,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -1954,8 +1954,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -1964,22 +1964,22 @@ } } }, - "201" : { - "description" : "Created.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/QualityNotificationIdResponse" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "400" : { - "description" : "Bad request.", + "201" : { + "description" : "Created.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "$ref" : "#/components/schemas/QualityNotificationIdResponse" } } } @@ -2024,8 +2024,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2044,8 +2044,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -2054,9 +2054,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -2067,8 +2064,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -2077,8 +2077,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -2087,8 +2087,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -2137,8 +2137,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2157,8 +2157,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -2167,9 +2167,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -2180,8 +2177,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -2190,8 +2190,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -2200,8 +2200,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -2240,8 +2240,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2260,8 +2260,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -2270,9 +2270,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -2283,8 +2280,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "204" : { + "description" : "No content." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -2293,8 +2293,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -2303,8 +2303,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -2343,8 +2343,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2363,8 +2363,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -2373,9 +2373,6 @@ } } }, - "204" : { - "description" : "No content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -2386,8 +2383,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -2396,8 +2393,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -2406,8 +2403,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -2415,6 +2412,9 @@ } } } + }, + "204" : { + "description" : "No content." } }, "security" : [ @@ -2445,8 +2445,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2465,8 +2465,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -2485,8 +2485,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -2495,8 +2495,18 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -2637,16 +2647,6 @@ } } } - }, - "400" : { - "description" : "Bad request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } } }, "security" : [ @@ -2685,8 +2685,8 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -2705,46 +2705,6 @@ } } }, - "404" : { - "description" : "Not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "401" : { - "description" : "Authorization failed.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "403" : { - "description" : "Forbidden.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "415" : { - "description" : "Unsupported media type", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, "200" : { "description" : "Returns the updated asset", "content" : { @@ -2878,6 +2838,26 @@ } } }, + "403" : { + "description" : "Forbidden.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "401" : { + "description" : "Authorization failed.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, "400" : { "description" : "Bad request.", "content" : { @@ -2887,6 +2867,26 @@ } } } + }, + "404" : { + "description" : "Not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } } }, "security" : [ @@ -2917,8 +2917,58 @@ } ], "responses" : { - "200" : { - "description" : "Returns the assets found", + "415" : { + "description" : "Unsupported media type", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "500" : { + "description" : "Internal server error.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Forbidden.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "401" : { + "description" : "Authorization failed.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "400" : { + "description" : "Bad request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "200" : { + "description" : "Returns the assets found", "content" : { "application/json" : { "schema" : { @@ -3050,26 +3100,6 @@ } } }, - "429" : { - "description" : "Too many requests.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "500" : { - "description" : "Internal server error.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, "404" : { "description" : "Not found.", "content" : { @@ -3080,38 +3110,8 @@ } } }, - "401" : { - "description" : "Authorization failed.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "403" : { - "description" : "Forbidden.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "415" : { - "description" : "Unsupported media type", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3157,36 +3157,6 @@ "required" : true }, "responses" : { - "429" : { - "description" : "Too many requests.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "500" : { - "description" : "Internal server error.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "404" : { - "description" : "Not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, "200" : { "description" : "Returns the updated asset", "content" : { @@ -3320,8 +3290,18 @@ } } }, - "401" : { - "description" : "Authorization failed.", + "415" : { + "description" : "Unsupported media type", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -3340,8 +3320,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { @@ -3359,6 +3339,26 @@ } } } + }, + "404" : { + "description" : "Not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } } }, "security" : [ @@ -3379,8 +3379,8 @@ "description" : "The endpoint returns all shell descriptors.", "operationId" : "findAll", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3399,8 +3399,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -3409,21 +3409,18 @@ } } }, - "200" : { - "description" : "ShellDescriptors found.", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { - "type" : "array", - "items" : { - "$ref" : "#/components/schemas/ShellDescriptorResponse" - } + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "401" : { - "description" : "Authorization failed.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -3432,18 +3429,21 @@ } } }, - "403" : { - "description" : "Forbidden.", + "200" : { + "description" : "ShellDescriptors found.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ShellDescriptorResponse" + } } } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -3452,8 +3452,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3480,8 +3480,8 @@ "description" : "The endpoint deletes all shell descriptors.", "operationId" : "deleteAll", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3503,8 +3503,8 @@ "204" : { "description" : "Deleted." }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -3523,8 +3523,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -3533,8 +3533,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -3543,8 +3543,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3572,8 +3572,8 @@ "description" : "The endpoint Triggers reload of shell descriptors.", "operationId" : "reload", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3592,8 +3592,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -3602,9 +3602,6 @@ } } }, - "202" : { - "description" : "Created registry reload job." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -3615,8 +3612,11 @@ } } }, - "403" : { - "description" : "Forbidden.", + "202" : { + "description" : "Created registry reload job." + }, + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -3625,8 +3625,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -3635,8 +3635,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3675,8 +3675,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3711,8 +3711,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -3731,8 +3731,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -3741,8 +3741,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -3751,8 +3751,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3780,8 +3780,8 @@ "description" : "The endpoint can return limited data based on the user role", "operationId" : "dashboard", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3800,8 +3800,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -3830,8 +3830,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -3840,8 +3840,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -3850,8 +3850,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -3897,8 +3897,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -3917,16 +3917,6 @@ } } }, - "404" : { - "description" : "Not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, "200" : { "description" : "Returns the paged result found for Asset", "content" : { @@ -4065,6 +4055,16 @@ } } }, + "403" : { + "description" : "Forbidden.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, "401" : { "description" : "Authorization failed.", "content" : { @@ -4075,8 +4075,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -4085,8 +4085,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -4095,8 +4095,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -4275,8 +4275,8 @@ } } }, - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -4295,8 +4295,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -4315,8 +4315,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -4325,8 +4325,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -4335,8 +4335,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -4392,18 +4392,20 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "200" : { + "description" : "Returns a distinct filter values for given fieldName.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "500" : { - "description" : "Internal server error.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -4412,8 +4414,8 @@ } } }, - "404" : { - "description" : "Not found.", + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -4422,8 +4424,8 @@ } } }, - "401" : { - "description" : "Authorization failed.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -4432,8 +4434,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { @@ -4442,8 +4444,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -4452,20 +4454,18 @@ } } }, - "200" : { - "description" : "Returns a distinct filter values for given fieldName.", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -4511,8 +4511,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -4531,8 +4531,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -4551,8 +4551,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -4561,8 +4561,18 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -4708,16 +4718,6 @@ } } } - }, - "400" : { - "description" : "Bad request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } } }, "security" : [ @@ -4756,6 +4756,76 @@ } ], "responses" : { + "415" : { + "description" : "Unsupported media type", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "500" : { + "description" : "Internal server error.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "403" : { + "description" : "Forbidden.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "401" : { + "description" : "Authorization failed.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "400" : { + "description" : "Bad request.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "404" : { + "description" : "Not found.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, + "429" : { + "description" : "Too many requests.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ErrorResponse" + } + } + } + }, "200" : { "description" : "Returns the asset by childId", "content" : { @@ -4888,76 +4958,6 @@ } } } - }, - "429" : { - "description" : "Too many requests.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "500" : { - "description" : "Internal server error.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "404" : { - "description" : "Not found.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "401" : { - "description" : "Authorization failed.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "403" : { - "description" : "Forbidden.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "415" : { - "description" : "Unsupported media type", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } - }, - "400" : { - "description" : "Bad request.", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" - } - } - } } }, "security" : [ @@ -5006,18 +5006,20 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "200" : { + "description" : "Returns a distinct filter values for given fieldName.", "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ErrorResponse" + "maxItems" : 2147483647, + "minItems" : 0, + "type" : "array" } } } }, - "500" : { - "description" : "Internal server error.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -5026,8 +5028,8 @@ } } }, - "404" : { - "description" : "Not found.", + "500" : { + "description" : "Internal server error.", "content" : { "application/json" : { "schema" : { @@ -5036,8 +5038,8 @@ } } }, - "401" : { - "description" : "Authorization failed.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -5046,8 +5048,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "401" : { + "description" : "Authorization failed.", "content" : { "application/json" : { "schema" : { @@ -5056,8 +5058,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -5066,20 +5068,18 @@ } } }, - "200" : { - "description" : "Returns a distinct filter values for given fieldName.", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { - "maxItems" : 2147483647, - "minItems" : 0, - "type" : "array" + "$ref" : "#/components/schemas/ErrorResponse" } } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -5107,8 +5107,8 @@ "description" : "The endpoint returns a map for assets consumed by the map.", "operationId" : "assetsCountryMap", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -5141,8 +5141,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -5161,8 +5161,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -5171,8 +5171,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -5181,8 +5181,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -5221,8 +5221,8 @@ } ], "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -5256,8 +5256,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -5276,8 +5276,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -5286,8 +5286,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -5296,8 +5296,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -5325,8 +5325,8 @@ "description" : "Deletes all submodels from the system.", "operationId" : "deleteSubmodels", "responses" : { - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -5345,8 +5345,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -5355,9 +5355,6 @@ } } }, - "204" : { - "description" : "No Content." - }, "401" : { "description" : "Authorization failed.", "content" : { @@ -5368,8 +5365,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -5378,8 +5375,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -5388,8 +5385,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -5397,6 +5394,9 @@ } } } + }, + "204" : { + "description" : "No Content." } }, "security" : [ @@ -5427,11 +5427,8 @@ } ], "responses" : { - "204" : { - "description" : "Deleted." - }, - "429" : { - "description" : "Too many requests.", + "415" : { + "description" : "Unsupported media type", "content" : { "application/json" : { "schema" : { @@ -5450,8 +5447,8 @@ } } }, - "404" : { - "description" : "Not found.", + "403" : { + "description" : "Forbidden.", "content" : { "application/json" : { "schema" : { @@ -5470,8 +5467,8 @@ } } }, - "403" : { - "description" : "Forbidden.", + "400" : { + "description" : "Bad request.", "content" : { "application/json" : { "schema" : { @@ -5480,8 +5477,8 @@ } } }, - "415" : { - "description" : "Unsupported media type", + "404" : { + "description" : "Not found.", "content" : { "application/json" : { "schema" : { @@ -5490,8 +5487,8 @@ } } }, - "400" : { - "description" : "Bad request.", + "429" : { + "description" : "Too many requests.", "content" : { "application/json" : { "schema" : { @@ -5499,6 +5496,9 @@ } } } + }, + "204" : { + "description" : "Deleted." } }, "security" : [ From 36ba32286a47c370edc19fbb24028274ec896135 Mon Sep 17 00:00:00 2001 From: ds-ext-sceronik Date: Thu, 9 Nov 2023 09:09:17 +0100 Subject: [PATCH 5/6] feature: TRACEFOSS-2796 support for filtering notifications by assetId --- CHANGELOG.md | 1 + .../QualityNotificationFieldMapper.java | 3 +- .../AssetAsBuiltControllerFilteringIT.java | 4 +- .../alert/AlertControllerFilterIT.java | 57 +++++++++++++++++++ .../InvestigationControllerFilterIT.java | 55 ++++++++++++++++++ 5 files changed, 117 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e4ce82841..8a6287821c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Fixed bug in argo workflow which allows to successfully run on INT-A/INT-B - New job named 'print_environment' to the Argo-workflow that prints the selected environment to the GitHub Step Summary. - Added NOTIFICATION_COUNT_EQUAL filter strategy for Assets as built Specifications +- Added new supported filter for notifications assetId that allows filtering alerts and investigations by assetId ### Changed - Fixed table-settings reset bug diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/application/base/mapper/QualityNotificationFieldMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/application/base/mapper/QualityNotificationFieldMapper.java index ee35e989fb..fd455adb72 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/application/base/mapper/QualityNotificationFieldMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/qualitynotification/application/base/mapper/QualityNotificationFieldMapper.java @@ -43,7 +43,8 @@ public class QualityNotificationFieldMapper extends BaseRequestFieldMapper { Map.entry("createdByName", "notifications_createdByName"), Map.entry("sendTo", "notifications_sentTo"), Map.entry("sendToName", "notifications_sentToName"), - Map.entry("targetDate", "notifications_targetDate") + Map.entry("targetDate", "notifications_targetDate"), + Map.entry("assetId", "assets_id") ); diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java index 081e9e565b..ce95041a3a 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/assets/AssetAsBuiltControllerFilteringIT.java @@ -341,7 +341,7 @@ void givenNonExistingFilterField_whenGetAssetsAsBuilt_thenBadRequest() throws Jo } @Test - void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseException { + void givenAssetsWithAlerts_whenGetAssetsWithActiveAlertCountFilter_thenReturnProperAssets() throws JoseException { // Given assetsSupport.defaultAssetsStored(); AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); @@ -371,7 +371,7 @@ void givenAlertsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseEx } @Test - void givenInvestigationsForAsset_whenCallAssetById_thenReturnProperCount() throws JoseException { + void givenAssetsWithInvestigations_whenGetAssetsWithActiveInvestigationCountFilter_thenReturnProperAssets() throws JoseException { // Given assetsSupport.defaultAssetsStored(); AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/alert/AlertControllerFilterIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/alert/AlertControllerFilterIT.java index 92e22035eb..d1f5d9ff1d 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/alert/AlertControllerFilterIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/alert/AlertControllerFilterIT.java @@ -20,21 +20,46 @@ package org.eclipse.tractusx.traceability.integration.qualitynotification.alert; import io.restassured.http.ContentType; +import org.checkerframework.checker.units.qual.A; +import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.model.AssetAsBuiltEntity; +import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.repository.JpaAssetAsBuiltRepository; import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification; import org.eclipse.tractusx.traceability.integration.common.support.AlertNotificationsSupport; +import org.eclipse.tractusx.traceability.integration.common.support.AlertsSupport; +import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport; import org.hamcrest.Matchers; import org.jose4j.lang.JoseException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; + import static io.restassured.RestAssured.given; import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACCEPTED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACKNOWLEDGED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CANCELED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CLOSED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CREATED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.DECLINED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.RECEIVED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.SENT; +import static org.hamcrest.Matchers.equalTo; class AlertControllerFilterIT extends IntegrationTestSpecification { @Autowired AlertNotificationsSupport alertNotificationsSupport; + @Autowired + AlertsSupport alertsSupport; + + @Autowired + AssetsSupport assetsSupport; + + @Autowired + JpaAssetAsBuiltRepository jpaAssetAsBuiltRepository; + @Test void givenAlerts_whenProvideNoFilter_thenReturnAll() throws JoseException { // given @@ -268,4 +293,36 @@ void givenInvestigations_whenProvideFilterCreatedByName_thenReturnAllCritical() .body("totalItems", Matchers.is(4)) .body("content", Matchers.hasSize(4)); } + + @Test + void givenAlerts_whenGetAlertsByAssetId_thenReturnOnlyRelatedAlerts() throws JoseException { + // Given + assetsSupport.defaultAssetsStored(); + AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); + AssetAsBuiltEntity assetAsBuilt2 = jpaAssetAsBuiltRepository.findById("urn:uuid:7fa65f10-9dc1-49fe-818a-09c7313a4562").orElseThrow(); + alertsSupport.storeAlertWithStatusAndAssets(CREATED, List.of(assetAsBuilt), null); + alertsSupport.storeAlertWithStatusAndAssets(SENT, List.of(), null); + alertsSupport.storeAlertWithStatusAndAssets(RECEIVED, List.of(), null); + alertsSupport.storeAlertWithStatusAndAssets(ACKNOWLEDGED, List.of(), null); + alertsSupport.storeAlertWithStatusAndAssets(ACCEPTED, List.of(), null); + alertsSupport.storeAlertWithStatusAndAssets(DECLINED, List.of(assetAsBuilt2), null); + alertsSupport.storeAlertWithStatusAndAssets(CANCELED, List.of(), null); + alertsSupport.storeAlertWithStatusAndAssets(CLOSED, List.of(assetAsBuilt), null); + + final String filter = "assetId,EQUAL,urn:uuid:7fa65f10-9dc1-49fe-818a-09c7313a4562,AND"; + + // When + given() + .header(oAuth2Support.jwtAuthorization(ADMIN)) + .contentType(ContentType.JSON) + .when() + .param("filter", filter) + .get("/api/alerts") + .then() + .log().all() + .statusCode(200) + .assertThat() + .body("totalItems", equalTo(1)); + } + } diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/investigation/InvestigationControllerFilterIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/investigation/InvestigationControllerFilterIT.java index fa955f1b7b..b288ff6fdd 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/investigation/InvestigationControllerFilterIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/qualitynotification/investigation/InvestigationControllerFilterIT.java @@ -20,21 +20,45 @@ package org.eclipse.tractusx.traceability.integration.qualitynotification.investigation; import io.restassured.http.ContentType; +import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.model.AssetAsBuiltEntity; +import org.eclipse.tractusx.traceability.assets.infrastructure.asbuilt.repository.JpaAssetAsBuiltRepository; import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification; +import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport; import org.eclipse.tractusx.traceability.integration.common.support.InvestigationNotificationsSupport; +import org.eclipse.tractusx.traceability.integration.common.support.InvestigationsSupport; import org.hamcrest.Matchers; import org.jose4j.lang.JoseException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; + import static io.restassured.RestAssured.given; import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACCEPTED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.ACKNOWLEDGED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CANCELED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CLOSED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.CREATED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.DECLINED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.RECEIVED; +import static org.eclipse.tractusx.traceability.qualitynotification.infrastructure.model.NotificationStatusBaseEntity.SENT; +import static org.hamcrest.Matchers.equalTo; class InvestigationControllerFilterIT extends IntegrationTestSpecification { @Autowired InvestigationNotificationsSupport investigationNotificationSupport; + @Autowired + AssetsSupport assetsSupport; + + @Autowired + JpaAssetAsBuiltRepository jpaAssetAsBuiltRepository; + + @Autowired + InvestigationsSupport investigationsSupport; + @Test void givenInvestigations_whenProvideNoFilter_thenReturnAll() throws JoseException { // given @@ -267,4 +291,35 @@ void givenNonExistingFilterField_whenGetInvestigations_thenBadRequest() throws J .then() .statusCode(400); } + + @Test + void givenInvestigations_whenGetInvestigationsByAssetId_thenReturnOnlyRelatedInvestigations() throws JoseException { + // Given + assetsSupport.defaultAssetsStored(); + AssetAsBuiltEntity assetAsBuilt = jpaAssetAsBuiltRepository.findById("urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb").orElseThrow(); + AssetAsBuiltEntity assetAsBuilt2 = jpaAssetAsBuiltRepository.findById("urn:uuid:7fa65f10-9dc1-49fe-818a-09c7313a4562").orElseThrow(); + investigationsSupport.storeInvestigationWithStatusAndAssets(CREATED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(SENT, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(RECEIVED, List.of(assetAsBuilt), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(ACKNOWLEDGED, List.of(assetAsBuilt2), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(ACCEPTED, List.of(assetAsBuilt2), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(DECLINED, List.of(assetAsBuilt2), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(CANCELED, List.of(assetAsBuilt2), null); + investigationsSupport.storeInvestigationWithStatusAndAssets(CLOSED, List.of(assetAsBuilt2), null); + + final String filter = "assetId,EQUAL,urn:uuid:d387fa8e-603c-42bd-98c3-4d87fef8d2bb,AND"; + + + // When + given() + .header(oAuth2Support.jwtAuthorization(ADMIN)) + .contentType(ContentType.JSON) + .when() + .param("filter", filter) + .get("/api/investigations") + .then() + .statusCode(200) + .assertThat() + .body("totalItems", equalTo(3)); + } } From 9caade4b7bd4e6cae1bcc77cd2f1aeab3e3dcdf7 Mon Sep 17 00:00:00 2001 From: Maximilian Wesener Date: Thu, 9 Nov 2023 11:01:43 +0100 Subject: [PATCH 6/6] chore: TRACEFOSS-2796 adapt frontend to use correct filter --- .../modules/page/parts/model/parts.model.ts | 3 +- .../parts-table/parts-table.component.ts | 4 - .../modules/shared/helper/filter-helper.ts | 162 ++++++++++-------- 3 files changed, 94 insertions(+), 75 deletions(-) diff --git a/frontend/src/app/modules/page/parts/model/parts.model.ts b/frontend/src/app/modules/page/parts/model/parts.model.ts index cd32d4ca27..e9f775c89f 100644 --- a/frontend/src/app/modules/page/parts/model/parts.model.ts +++ b/frontend/src/app/modules/page/parts/model/parts.model.ts @@ -170,7 +170,8 @@ export enum FilterOperator { AT_LOCAL_DATE = 'AT_LOCAL_DATE', STARTS_WITH = 'STARTS_WITH', BEFORE_LOCAL_DATE = 'BEFORE_LOCAL_DATE', - AFTER_LOCAL_DATE = 'AFTER_LOCAL_DATE' + AFTER_LOCAL_DATE = 'AFTER_LOCAL_DATE', + NOTIFICATION_COUNT_EQUAL = 'NOTIFICATION_COUNT_EQUAL' } export function getFilterOperatorValue(operator: FilterOperator) { diff --git a/frontend/src/app/modules/shared/components/parts-table/parts-table.component.ts b/frontend/src/app/modules/shared/components/parts-table/parts-table.component.ts index 76466528c9..2ec9d54e30 100644 --- a/frontend/src/app/modules/shared/components/parts-table/parts-table.component.ts +++ b/frontend/src/app/modules/shared/components/parts-table/parts-table.component.ts @@ -752,10 +752,6 @@ export class PartsTableComponent implements OnInit { this.multiSelect.emit(this.selection.selected); } - public toggleFilter(): void { - this.displayedFilter = !this.displayedFilter; - } - public isSelected(row: unknown): boolean { return !!this.selection.selected.find(data => JSON.stringify(data) === JSON.stringify(row)); } diff --git a/frontend/src/app/modules/shared/helper/filter-helper.ts b/frontend/src/app/modules/shared/helper/filter-helper.ts index 98fcfe6353..456d6f6350 100644 --- a/frontend/src/app/modules/shared/helper/filter-helper.ts +++ b/frontend/src/app/modules/shared/helper/filter-helper.ts @@ -24,56 +24,70 @@ import { getFilterOperatorValue, } from '@page/parts/model/parts.model'; -export const FILTER_KEYS = ['manufacturingDate', 'functionValidFrom', 'functionValidUntil', 'validityPeriodFrom', 'validityPeriodTo']; +export const DATE_FILTER_KEYS = [ 'manufacturingDate', 'functionValidFrom', 'functionValidUntil', 'validityPeriodFrom', 'validityPeriodTo' ]; + // TODO: Refactor function as soon as multi value filter is supported export function enrichFilterAndGetUpdatedParams(filter: AssetAsBuiltFilter, params: HttpParams, filterOperator: string): HttpParams { - const semanticDataModelKey = "semanticDataModel"; - for (const key in filter) { - let operator: string; - const filterValues: string = filter[key]; - if (key !== semanticDataModelKey) { - if (filterValues.length !== 0) { - if (isDateFilter(key)) { - if(isDateRangeFilter(filterValues)) { - const [startDate, endDate] = filterValues.split(",") - if(isSameDate(startDate,endDate)) { - operator = getFilterOperatorValue(FilterOperator.AT_LOCAL_DATE); - params = params.append('filter', `${key},${operator},${startDate},${filterOperator}`); - continue; - } - let endDateOperator = getFilterOperatorValue(FilterOperator.BEFORE_LOCAL_DATE) - operator = getFilterOperatorValue((FilterOperator.AFTER_LOCAL_DATE)); - params = params.append('filter', `${key},${operator},${startDate},${filterOperator}`); - params = params.append('filter', `${key},${endDateOperator},${endDate},${filterOperator}`); - continue; - } else { - operator = getFilterOperatorValue(FilterOperator.AFTER_LOCAL_DATE); - } - } else { - operator = getFilterOperatorValue(FilterOperator.STARTS_WITH); - } - params = params.append('filter', `${key},${operator},${filterValues},${filterOperator}`); + const semanticDataModelKey = 'semanticDataModel'; + for (const key in filter) { + let operator: string; + const filterValues: string = filter[key]; + if (key !== semanticDataModelKey) { + if (filterValues.length !== 0) { + if (isDateFilter(key)) { + if (isDateRangeFilter(filterValues)) { + const [ startDate, endDate ] = filterValues.split(','); + if (isSameDate(startDate, endDate)) { + operator = getFilterOperatorValue(FilterOperator.AT_LOCAL_DATE); + params = params.append('filter', `${ key },${ operator },${ startDate },${ filterOperator }`); + continue; } + let endDateOperator = getFilterOperatorValue(FilterOperator.BEFORE_LOCAL_DATE); + operator = getFilterOperatorValue((FilterOperator.AFTER_LOCAL_DATE)); + params = params.append('filter', `${ key },${ operator },${ startDate },${ filterOperator }`); + params = params.append('filter', `${ key },${ endDateOperator },${ endDate },${ filterOperator }`); + continue; + } else { + operator = getFilterOperatorValue(FilterOperator.AFTER_LOCAL_DATE); + } } else { - operator = getFilterOperatorValue(FilterOperator.EQUAL); - if (Array.isArray(filterValues)) { - for (let value of filterValues) { - params = params.append('filter', `${key},${operator},${value},${filterOperator}`); - } - } else { - params = params.append('filter', `${key},${operator},${filterValues},${filterOperator}`); - } + if (isNotificationCountFilter(key)) { + operator = getFilterOperatorValue(FilterOperator.NOTIFICATION_COUNT_EQUAL); + } else { + operator = getFilterOperatorValue(FilterOperator.STARTS_WITH); + } + + } + params = params.append('filter', `${ key },${ operator },${ filterValues },${ filterOperator }`); + } + } else { + operator = getFilterOperatorValue(FilterOperator.EQUAL); + if (Array.isArray(filterValues)) { + for (let value of filterValues) { + params = params.append('filter', `${ key },${ operator },${ value },${ filterOperator }`); } + } else { + params = params.append('filter', `${ key },${ operator },${ filterValues },${ filterOperator }`); + } } - return params; + } + return params; +} + +export function isStartsWithFilter(key: string): boolean { + return !isDateFilter(key) && !isNotificationCountFilter(key); +} + +export function isNotificationCountFilter(key: string): boolean { + return 'qualityInvestigationIdsInStatusActive' === key || 'qualityAlertIdsInStatusActive' === key; } export function isDateFilter(key: string): boolean { - return FILTER_KEYS.includes(key); + return DATE_FILTER_KEYS.includes(key); } export function isDateRangeFilter(filterValues: string): boolean { - return filterValues.includes(","); + return filterValues.includes(','); } export function isSameDate(startDate: string, endDate: string): boolean { @@ -82,46 +96,54 @@ export function isSameDate(startDate: string, endDate: string): boolean { export function toAssetFilter(formValues: any, isAsBuilt: boolean): AssetAsPlannedFilter | AssetAsBuiltFilter { - const transformedFilter: any = {}; + const transformedFilter: any = {}; + + // Loop through each form control and add it to the transformedFilter if it has a non-null and non-undefined value + for (const key in formValues) { + if (formValues[key] !== null && formValues[key] !== undefined) { + if ('activeAlerts' === key) { + transformedFilter['qualityAlertIdsInStatusActive'] = formValues[key]; + } + if ('activeInvestigations' === key) { + transformedFilter['qualityInvestigationIdsInStatusActive'] = formValues[key]; + } else { + transformedFilter[key] = formValues[key]; + } - // Loop through each form control and add it to the transformedFilter if it has a non-null and non-undefined value - for (const key in formValues) { - if (formValues[key] !== null && formValues[key] !== undefined) { - transformedFilter[key] = formValues[key]; - } } + } - const filterIsSet = Object.values(transformedFilter).some(value => value !== undefined && value !== null); - if (filterIsSet) { - if (isAsBuilt) { - return transformedFilter as AssetAsBuiltFilter; - } else { - return transformedFilter as AssetAsPlannedFilter; - } + const filterIsSet = Object.values(transformedFilter).some(value => value !== undefined && value !== null); + if (filterIsSet) { + if (isAsBuilt) { + return transformedFilter as AssetAsBuiltFilter; } else { - return null; + return transformedFilter as AssetAsPlannedFilter; } + } else { + return null; + } } export function toGlobalSearchAssetFilter(formValues: string, isAsBuilt: boolean) { - let filter; - if (isAsBuilt) { - filter = { - id: formValues, - semanticModelId: formValues, - idShort: formValues, - customerPartId: formValues, - manufacturerPartId: formValues - } as AssetAsBuiltFilter; - } else { - filter = { - id: formValues, - idShort: formValues, - semanticModelId: formValues, - manufacturerPartId: formValues - } as AssetAsPlannedFilter; - } + let filter; + if (isAsBuilt) { + filter = { + id: formValues, + semanticModelId: formValues, + idShort: formValues, + customerPartId: formValues, + manufacturerPartId: formValues, + } as AssetAsBuiltFilter; + } else { + filter = { + id: formValues, + idShort: formValues, + semanticModelId: formValues, + manufacturerPartId: formValues, + } as AssetAsPlannedFilter; + } - return filter; + return filter; }