Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/do 4418 wrong spelling of the column catenax site id in the table assets as planned #63

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static List<DetailAspectModel> from(AssetAsPlannedEntity entity) {
DetailAspectModel partSiteInfo = DetailAspectModel.builder()
.type(DetailAspectType.PART_SITE_INFORMATION_AS_PLANNED)
.data(DetailAspectDataPartSiteInformationAsPlanned.builder()
.catenaXSiteId(entity.getCatenaxSiteId())
.catenaXSiteId(entity.getCatenaXSiteId())
.functionValidFrom(toOffsetDateTime(entity.getFunctionValidFrom()))
.function(entity.getFunction())
.functionValidUntil(toOffsetDateTime(entity.getFunctionValidUntil()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class AsPlannedInfo {
private String function;
private OffsetDateTime validityPeriodFrom;
private OffsetDateTime validityPeriodTo;
private String catenaxSiteId;
private String catenaXSiteId;

public static AsPlannedInfo from(List<DetailAspectModel> detailAspectModels) {
Optional<DetailAspectModel> asPlannedInfo = detailAspectModels
Expand Down Expand Up @@ -52,7 +52,7 @@ public static AsPlannedInfo from(List<DetailAspectModel> detailAspectModels) {
.map(org.eclipse.tractusx.traceability.assets.domain.asplanned.model.aspect.DetailAspectDataPartSiteInformationAsPlanned::getFunctionValidFrom)
.orElse(null);

String catenaxSiteId = partSiteInfo.map(detailAspectModel -> (DetailAspectDataPartSiteInformationAsPlanned) detailAspectModel.getData())
String catenaXSiteId = partSiteInfo.map(detailAspectModel -> (DetailAspectDataPartSiteInformationAsPlanned) detailAspectModel.getData())
.map(org.eclipse.tractusx.traceability.assets.domain.asplanned.model.aspect.DetailAspectDataPartSiteInformationAsPlanned::getCatenaXSiteId)
.orElse("");

Expand All @@ -62,7 +62,7 @@ public static AsPlannedInfo from(List<DetailAspectModel> detailAspectModels) {
.function(function)
.validityPeriodFrom(validityPeriodFrom)
.validityPeriodTo(validityPeriodTo)
.catenaxSiteId(catenaxSiteId)
.catenaXSiteId(catenaXSiteId)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.eclipse.tractusx.traceability.assets.infrastructure.asplanned.model;

import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -58,8 +59,8 @@ public class AssetAsPlannedEntity extends AssetBaseEntity {
private Instant functionValidUntil;
private String function;
private Instant functionValidFrom;
private String catenaxSiteId;

@Column(name = "catenax_site_id")
private String catenaXSiteId;

@ElementCollection
@CollectionTable(name = "assets_as_planned_childs", joinColumns = {@JoinColumn(name = "asset_as_planned_id")})
Expand Down Expand Up @@ -107,7 +108,7 @@ public static AssetAsPlannedEntity from(AssetBase asset) {
.activeAlert(asset.isActiveAlert())
.inInvestigation(asset.isUnderInvestigation())
.semanticDataModel(SemanticDataModelEntity.from(asset.getSemanticDataModel()))
.catenaxSiteId(asPlannedInfo.getCatenaxSiteId())
.catenaXSiteId(asPlannedInfo.getCatenaXSiteId())
.build();
}

Expand Down
martin-fritz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
********************************************************************************/
package org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.semanticdatamodel;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.eclipse.tractusx.traceability.common.date.CustomOffSetDateTimeNullOnException;
Expand All @@ -30,6 +31,12 @@ public record Site(
@JsonDeserialize(using = CustomOffSetDateTimeNullOnException.class)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss", timezone = "UTC") OffsetDateTime functionValidFrom,
String function,
// As long as no clear spelling is defined, be lax with it. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
// JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES is not working, as it is a global feature.
@JsonAlias({
"catenaXSiteId", "catenaxSiteId", "catenaXsiteId", "catenaxsiteId",
"catenaXSiteid", "catenaxSiteid", "catenaXsiteid", "catenaxsiteid"})
String catenaXSiteId
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private static Sort toDomainSort(final List<String> sorts) {
}

private static String handleEnumColumns(final String column) {
return switch(column) {
return switch (column) {
case "status" -> "statusrank";
case "notifications_status" -> "notifications_statusrank";
// Include the notification table based attributes
Expand All @@ -88,7 +88,10 @@ private static String handleEnumColumns(final String column) {
case "sendTo" -> "notifications.sendTo";
case "qualityAlertsInStatusActive" -> "noOfActiveAlerts";
case "qualityInvestigationsInStatusActive" -> "noOfActiveInvestigations";
default -> column;
// As long as no clear spelling is defined, be lax with it. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
default -> column.equalsIgnoreCase("catenaxsiteid")
? "catenaXSiteId"
: column;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.eclipse.tractusx.traceability.common.model.SearchCriteriaOperator;
import org.eclipse.tractusx.traceability.common.model.SearchStrategy;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

Expand All @@ -37,54 +36,60 @@
@Data
@AllArgsConstructor
public class SearchCriteriaRequestParam {

@ArraySchema(arraySchema = @Schema(description = "Filter Criteria", additionalProperties = Schema.AdditionalPropertiesValue.FALSE, example = "owner,EQUAL,OWN"), maxItems = Integer.MAX_VALUE)
private List<String> filter;

@Schema(description = "The filter logical operator", example = "AND", allowableValues = {"AND", "OR"})
private String filterOperator;

public SearchCriteria toSearchCriteria() {
ArrayList<SearchCriteriaFilter> filters = new ArrayList<>();
List<String> inputFilters = filter;
if (isNull(this.filter)) {
inputFilters = Collections.emptyList();
}

if (!isNull(this.filter) && isNull(this.filterOperator)) {
throw new InvalidFilterException(
"No filter operator found. Please add param filterOperator=AND or filterOperator=OR");
"No filter operator found. Please add param filterOperator=AND or filterOperator=OR.");
}
if (isNull(this.filter) && isNull(this.filterOperator)) {
return SearchCriteria.builder().build();
}

for (String filter : inputFilters) {
try {
String[] filterParams = filter.split(",");
filters.add(
SearchCriteriaFilter.builder()
.key(filterParams[0])
final List<String> inputFilters = (filter != null) ? filter : Collections.emptyList();

final List<SearchCriteriaFilter> filters = inputFilters
.stream()
.map(inputFilter -> {
try {
final String[] filterParams = inputFilter.split(",");
return SearchCriteriaFilter.builder()
.key(handleFilterParameter(filterParams[0]))
.strategy(SearchStrategy.valueOf(filterParams[1]))
.value(filterParams[2])
.build());
} catch (Exception exception) {
.build();
} catch (final Exception exception) {
throw new InvalidFilterException(
"Invalid filter param provided filter={provided} expected format is following filter=parameter,operation,value"
.replace("{provided}", filter)
.replace("{provided}", inputFilter)
);
}

}
})
.toList();

SearchCriteriaOperator operator;
final SearchCriteriaOperator operator;
try {
operator = SearchCriteriaOperator.valueOf(filterOperator);
} catch (Exception exception) {
} catch (final Exception exception) {
throw new InvalidFilterException(
"Invalid filter operator provided filterOperator={provided} expected format is following filterOperator=value. Where value is one of AND, OR"
.replace("{provided}", filterOperator)
);
}

return SearchCriteria.builder().searchCriteriaOperator(operator).searchCriteriaFilterList(filters).build();
}

private static String handleFilterParameter(final String filterParameter) {
// As long as no clear spelling is defined, be lax with it. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
return filterParameter.equalsIgnoreCase("catenaxsiteid") ? "catenaXSiteId" : filterParameter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@
"functionValidUntil": "2025-02-08T04:30:48.000Z",
"function": "production",
"functionValidFrom": "2019-08-21T02:10:36.000Z",
"catenaXSiteId": "BPNS000004711DMY"
"catenaxSiteId": "BPNS000004711DMY"
}
]
}
Expand Down Expand Up @@ -410,7 +410,7 @@
"functionValidUntil": "2025-02-08T04:30:48.000Z",
"function": "production",
"functionValidFrom": "2019-08-21T02:10:36.000Z",
"catenaXSiteId": "BPNS000004711DMY"
"catenaXsiteId": "BPNS000004711DMY"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/********************************************************************************
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.traceability.integration.assets;

import static io.restassured.RestAssured.given;
import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN;
import static org.hamcrest.Matchers.equalTo;

import io.restassured.http.ContentType;
import java.util.stream.Stream;
import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification;
import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport;
import org.hamcrest.Matchers;
import org.jose4j.lang.JoseException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;

class AssetAsPlannedControllerSortAndFilterValuesIT extends IntegrationTestSpecification {

@Autowired
AssetsSupport assetsSupport;

@BeforeEach
void before() {
// Test data contains different spellings for 'catenaXSiteId', as long as no clear spelling is defined. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
assetsSupport.defaultAssetsAsPlannedStored(
"/testdata/irs_assets_as_planned_v4_long_list.json");
}

private static Stream<Arguments> sortAndFilterArguments() {
return Stream.of(
// As long as no clear spelling for 'catenaxSiteId' is defined, test on different spellings. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
Arguments.of("nameAtManufacturer,asc", "catenaXSiteId,EQUAL,BPNS000004711DMY", "AND",
new String[]{"HVModul", "OEMAHighVoltageBattery", "VehicleModelA", "ZBZELLE"}),
Arguments.of("nameAtManufacturer,asc", "catenaxSiteId,EQUAL,BPNS000004711DMY", "AND",
new String[]{"HVModul", "OEMAHighVoltageBattery", "VehicleModelA", "ZBZELLE"})
);
}

@ParameterizedTest
@MethodSource("sortAndFilterArguments")
void givenSortArguments_whenCallSortAndFilterEndpoint_thenReturnExpectedResponse(
final String sort,
final String filter,
final String filterOperator,
final String[] expectedOrderOfIdShortItems
) throws JoseException {

final long page = 0;
final long size = 20;

given()
.header(oAuth2Support.jwtAuthorization(ADMIN))
.contentType(ContentType.JSON)
.param("page", page)
.param("size", size)
.param("sort", sort)
.param("filter", filter)
.param("filterOperator", filterOperator)
.log().all()
.when()
.get("/api/assets/as-planned")
.then()
.log().all()
.statusCode(200)
.body("totalItems", equalTo(expectedOrderOfIdShortItems.length))
.body("content.idShort", Matchers.containsInRelativeOrder(expectedOrderOfIdShortItems));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/********************************************************************************
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.traceability.integration.assets;

import static io.restassured.RestAssured.given;
import static org.eclipse.tractusx.traceability.common.security.JwtRole.ADMIN;
import static org.hamcrest.Matchers.equalTo;

import io.restassured.http.ContentType;
import java.util.stream.Stream;
import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification;
import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport;
import org.hamcrest.Matchers;
import org.jose4j.lang.JoseException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;

class AssetAsPlannedControllerSortValuesIT extends IntegrationTestSpecification {

@Autowired
AssetsSupport assetsSupport;

@BeforeEach
void before() {
// Test data contains different spellings for 'catenaXSiteId', as long as no clear spelling is defined. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
assetsSupport.defaultAssetsAsPlannedStored(
"/testdata/irs_assets_as_planned_v4_long_list_distinct_catenaxsiteid.json");
}

private static Stream<Arguments> sortArguments() {
return Stream.of(
// As long as no clear spelling for 'catenaxSiteId' is defined, test on different spellings. https://github.com/eclipse-tractusx/sldt-semantic-models/issues/470
Arguments.of("catenaXSiteId,desc",
new String[]{"ZBZELLE", "HVModul", "OEMAHighVoltageBattery", "VehicleModelA", "TierBECU1",
"SubTierASensor", "TierAGearbox", "NTierACathodeMaterial", "NTierANTierProduct",
"NTierAPlastics", "SubTierBSealant", "SubTierBGlue"}),
Arguments.of("catenaxSiteId,asc",
new String[]{"SubTierBGlue", "SubTierBSealant", "NTierAPlastics", "NTierANTierProduct",
"NTierACathodeMaterial", "TierAGearbox", "SubTierASensor", "TierBECU1", "VehicleModelA",
"OEMAHighVoltageBattery", "HVModul", "ZBZELLE"})
);
}

@ParameterizedTest
@MethodSource("sortArguments")
void givenSortArguments_whenCallSortEndpoint_thenReturnExpectedResponse(
final String sort,
final String[] expectedOrderOfIdShortItems
) throws JoseException {

final long page = 0;
final long size = 20;

given()
.header(oAuth2Support.jwtAuthorization(ADMIN))
.contentType(ContentType.JSON)
.param("page", page)
.param("size", size)
.param("sort", sort)
.log().all()
.when()
.get("/api/assets/as-planned")
.then()
.log().all()
.statusCode(200)
.body("totalItems", equalTo(expectedOrderOfIdShortItems.length))
.body("content.idShort", Matchers.containsInRelativeOrder(expectedOrderOfIdShortItems));
}
}
Loading
Loading