diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java index 6da98f51fa..6324ac0e00 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java @@ -51,6 +51,7 @@ import org.eclipse.tractusx.irs.policystore.models.PolicyResponse; import org.eclipse.tractusx.irs.policystore.models.UpdatePolicyRequest; import org.eclipse.tractusx.irs.policystore.services.PolicyStoreService; +import org.eclipse.tractusx.irs.policystore.validators.BusinessPartnerNumberListValidator; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; @@ -77,7 +78,7 @@ }) public class PolicyStoreController { - public static final String BPN_REGEX = "(BPN)[LSA][\\w\\d]{10}[\\w\\d]{2}"; + public static final String BPN_REGEX = BusinessPartnerNumberListValidator.BPN_REGEX; private final PolicyStoreService service; private final EdcTransformer edcTransformer; diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidator.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidator.java new file mode 100644 index 0000000000..7cd81e3f8e --- /dev/null +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidator.java @@ -0,0 +1,53 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 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.irs.policystore.validators; + +import java.util.List; +import java.util.regex.Pattern; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +public class BusinessPartnerNumberListValidator + implements ConstraintValidator> { + + public static final String BPN_REGEX = "(BPN)[LSA][\\w\\d]{10}[\\w\\d]{2}"; + + private static final Pattern PATTERN = Pattern.compile(BPN_REGEX); + + @Override + public boolean isValid(List value, ConstraintValidatorContext context) { + if (value == null || value.isEmpty()) { + return true; + } + + for (int i = 0; i < value.size(); i++) { + if (!PATTERN.matcher(value.get(i)).matches()) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate( + "The business partner number at index %d is invalid (should conform to pattern '%s')".formatted( + i, BPN_REGEX)).addConstraintViolation(); + return false; + } + } + + return true; + } +} \ No newline at end of file diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/ValidListOfBusinessPartnerNumbers.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/ValidListOfBusinessPartnerNumbers.java new file mode 100644 index 0000000000..bd68f94617 --- /dev/null +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/validators/ValidListOfBusinessPartnerNumbers.java @@ -0,0 +1,43 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 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.irs.policystore.validators; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +@Documented +@Constraint(validatedBy = BusinessPartnerNumberListValidator.class) +@Target({ ElementType.FIELD, + ElementType.PARAMETER +}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidListOfBusinessPartnerNumbers { + String message() default "Invalid list of business partner numbers"; + + Class[] groups() default { }; + + Class[] payload() default { }; +} \ No newline at end of file diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidatorTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidatorTest.java new file mode 100644 index 0000000000..018f9da437 --- /dev/null +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/validators/BusinessPartnerNumberListValidatorTest.java @@ -0,0 +1,79 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 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.irs.policystore.validators; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import jakarta.validation.ConstraintValidatorContext; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class BusinessPartnerNumberListValidatorTest { + + public static final String VALID_BPN_1 = "BPNL1234567890AB"; + public static final String VALID_BPN_2 = "BPNL123456789012"; + + @InjectMocks + private BusinessPartnerNumberListValidator validator; + + @Captor + private ArgumentCaptor messageCaptor; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private ConstraintValidatorContext contextMock; + + @Test + void withEmptyListOfStrings() { + assertThat(validator.isValid(Collections.emptyList(), contextMock)).isTrue(); + } + + @Test + void withNull() { + assertThat(validator.isValid(null, contextMock)).isTrue(); + } + + @Test + void withValidListOfStrings() { + List validList = Arrays.asList(VALID_BPN_1, VALID_BPN_2); + assertThat(validator.isValid(validList, contextMock)).isTrue(); + } + + @Test + void withListContainingInvalidBPN() { + List invalidList = Arrays.asList(VALID_BPN_1, "INVALID_BPN", VALID_BPN_2); + assertThat(validator.isValid(invalidList, contextMock)).isFalse(); + // verify(contextMock).buildConstraintViolationWithTemplate( + //// startsWith("Element at index 1 does not match the pattern")); + verify(contextMock).buildConstraintViolationWithTemplate(messageCaptor.capture()); + assertThat(messageCaptor.getValue()).contains("BPN").contains(" index 1 ").contains("invalid"); + } +}