diff --git a/core/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/core/exception/ConstraintViolatedException.java b/core/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/core/exception/ConstraintViolatedException.java new file mode 100644 index 00000000..c901f544 --- /dev/null +++ b/core/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/core/exception/ConstraintViolatedException.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Fraunhofer IOSB, eine rechtlich nicht selbstaendige + * Einrichtung der Fraunhofer-Gesellschaft zur Foerderung der angewandten + * Forschung e.V. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://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. + */ +package de.fraunhofer.iosb.ilt.faaast.registry.core.exception; + +/** + * Exception class for constraint violated. + */ +public class ConstraintViolatedException extends RuntimeException { + + public ConstraintViolatedException() { + super(); + } + + + public ConstraintViolatedException(final String message, final Throwable cause) { + super(message, cause); + } + + + public ConstraintViolatedException(final String message) { + super(message); + } + + + public ConstraintViolatedException(final Throwable cause) { + super(cause); + } +} diff --git a/docs/source/changelog/changelog.md b/docs/source/changelog/changelog.md index c639469c..f98a1dc0 100644 --- a/docs/source/changelog/changelog.md +++ b/docs/source/changelog/changelog.md @@ -12,6 +12,7 @@ - Update JPA mapping - Use descriptors from AAS4J - Fix documentation formatting errors + - Add log message if a constraint violation occurs when creating AAS or Submodel ## 1.0.0 diff --git a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/ShellRegistryController.java b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/ShellRegistryController.java index edb55113..c17bceb8 100644 --- a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/ShellRegistryController.java +++ b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/ShellRegistryController.java @@ -15,8 +15,10 @@ package de.fraunhofer.iosb.ilt.faaast.registry.service; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.BadRequestException; +import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ConstraintViolatedException; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ResourceAlreadyExistsException; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ResourceNotFoundException; +import de.fraunhofer.iosb.ilt.faaast.registry.service.helper.CommonConstraintHelper; import de.fraunhofer.iosb.ilt.faaast.service.model.api.paging.Page; import de.fraunhofer.iosb.ilt.faaast.service.model.api.paging.PagingInfo; import de.fraunhofer.iosb.ilt.faaast.service.util.EncodingHelper; @@ -24,6 +26,8 @@ import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShellDescriptor; import org.eclipse.digitaltwin.aas4j.v3.model.AssetKind; import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -47,6 +51,8 @@ @RequestMapping("/api/v3.0/shell-descriptors") public class ShellRegistryController { + private static final Logger LOGGER = LoggerFactory.getLogger(ShellRegistryController.class); + @Autowired RegistryService service; @@ -97,12 +103,18 @@ public AssetAdministrationShellDescriptor getAAS(@PathVariable("aasIdentifier") */ @PostMapping() public ResponseEntity create(@RequestBody AssetAdministrationShellDescriptor resource) throws ResourceAlreadyExistsException { - AssetAdministrationShellDescriptor aas = service.createAAS(resource); - URI location = ServletUriComponentsBuilder - .fromCurrentRequest() - .path(String.format("/%s", EncodingHelper.base64UrlEncode(aas.getId()))) - .build().toUri(); - return ResponseEntity.created(location).body(aas); + try { + AssetAdministrationShellDescriptor aas = service.createAAS(resource); + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .path(String.format("/%s", EncodingHelper.base64UrlEncode(aas.getId()))) + .build().toUri(); + return ResponseEntity.created(location).body(aas); + } + catch (ConstraintViolatedException e) { + logConstraintViolated("create AAS", e.getMessage(), resource); + throw new BadRequestException(e.getMessage()); + } } @@ -190,12 +202,18 @@ public SubmodelDescriptor getSubmodelOfAAS(@PathVariable("aasIdentifier") String public ResponseEntity create(@PathVariable("aasIdentifier") String aasIdentifier, @RequestBody SubmodelDescriptor submodel) throws ResourceNotFoundException, ResourceAlreadyExistsException { - SubmodelDescriptor descriptor = service.createSubmodel(aasIdentifier, submodel); - URI location = ServletUriComponentsBuilder - .fromCurrentRequest() - .path(String.format("/%s", EncodingHelper.base64UrlEncode(descriptor.getId()))) - .build().toUri(); - return ResponseEntity.created(location).body(descriptor); + try { + SubmodelDescriptor descriptor = service.createSubmodel(aasIdentifier, submodel); + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .path(String.format("/%s", EncodingHelper.base64UrlEncode(descriptor.getId()))) + .build().toUri(); + return ResponseEntity.created(location).body(descriptor); + } + catch (ConstraintViolatedException e) { + logConstraintViolated("create Submodel", e.getMessage(), aasIdentifier, submodel); + throw new BadRequestException(e.getMessage()); + } } @@ -233,4 +251,14 @@ public void deleteSubmodelOfAAS(@PathVariable("aasIdentifier") String aasIdentif throws ResourceNotFoundException { service.deleteSubmodel(aasIdentifier, submodelIdentifier); } + + + private void logConstraintViolated(String method, String message, AssetAdministrationShellDescriptor aas) { + LOGGER.atInfo().log(CommonConstraintHelper.getLogText(method, message, aas)); + } + + + private void logConstraintViolated(String method, String message, String aasId, SubmodelDescriptor submodel) { + LOGGER.atInfo().log(CommonConstraintHelper.getLogText(method, message, aasId, submodel)); + } } diff --git a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/SubmodelRegistryController.java b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/SubmodelRegistryController.java index bf453516..f4c17839 100644 --- a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/SubmodelRegistryController.java +++ b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/SubmodelRegistryController.java @@ -15,13 +15,17 @@ package de.fraunhofer.iosb.ilt.faaast.registry.service; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.BadRequestException; +import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ConstraintViolatedException; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ResourceAlreadyExistsException; import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ResourceNotFoundException; +import de.fraunhofer.iosb.ilt.faaast.registry.service.helper.CommonConstraintHelper; import de.fraunhofer.iosb.ilt.faaast.service.model.api.paging.Page; import de.fraunhofer.iosb.ilt.faaast.service.model.api.paging.PagingInfo; import de.fraunhofer.iosb.ilt.faaast.service.util.EncodingHelper; import java.net.URI; import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -45,6 +49,8 @@ @RequestMapping(value = "/api/v3.0/submodel-descriptors") public class SubmodelRegistryController { + private static final Logger LOGGER = LoggerFactory.getLogger(SubmodelRegistryController.class); + @Autowired RegistryService service; @@ -93,12 +99,18 @@ public SubmodelDescriptor getSubmodel(@PathVariable("submodelIdentifier") String */ @PostMapping public ResponseEntity createSubmodel(@RequestBody SubmodelDescriptor submodel) throws ResourceNotFoundException, ResourceAlreadyExistsException { - SubmodelDescriptor descriptor = service.createSubmodel(submodel); - URI location = ServletUriComponentsBuilder - .fromCurrentRequest() - .path(String.format("/%s", EncodingHelper.base64UrlEncode(descriptor.getId()))) - .build().toUri(); - return ResponseEntity.created(location).body(descriptor); + try { + SubmodelDescriptor descriptor = service.createSubmodel(submodel); + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .path(String.format("/%s", EncodingHelper.base64UrlEncode(descriptor.getId()))) + .build().toUri(); + return ResponseEntity.created(location).body(descriptor); + } + catch (ConstraintViolatedException e) { + logConstraintViolated("create Submodel", e.getMessage(), submodel); + throw new BadRequestException(e.getMessage()); + } } @@ -130,4 +142,9 @@ public SubmodelDescriptor update(@PathVariable("submodelIdentifier") String subm public void delete(@PathVariable("submodelIdentifier") String submodelIdentifier) throws ResourceNotFoundException { service.deleteSubmodel(submodelIdentifier); } + + + private void logConstraintViolated(String method, String message, SubmodelDescriptor submodel) { + LOGGER.atInfo().log(CommonConstraintHelper.getLogText(method, message, null, submodel)); + } } diff --git a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/helper/CommonConstraintHelper.java b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/helper/CommonConstraintHelper.java index 906c9890..25ea6e1f 100644 --- a/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/helper/CommonConstraintHelper.java +++ b/service/src/main/java/de/fraunhofer/iosb/ilt/faaast/registry/service/helper/CommonConstraintHelper.java @@ -14,10 +14,12 @@ */ package de.fraunhofer.iosb.ilt.faaast.registry.service.helper; -import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.BadRequestException; +import de.fraunhofer.iosb.ilt.faaast.registry.core.exception.ConstraintViolatedException; import java.util.List; +import org.eclipse.digitaltwin.aas4j.v3.model.AssetAdministrationShellDescriptor; import org.eclipse.digitaltwin.aas4j.v3.model.Key; import org.eclipse.digitaltwin.aas4j.v3.model.Reference; +import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelDescriptor; /** @@ -128,7 +130,65 @@ public static void checkReference(Reference reference) { * @param txt The desired text for the exception. */ public static void raiseConstraintViolatedException(String txt) { - throw new BadRequestException(txt); + throw new ConstraintViolatedException(txt); + } + + + /** + * Creates the log text for an AAS constraint violation. + * + * @param method The desired method name. + * @param message The desire dmessage. + * @param aas The AAS. + * @return The created log text. + */ + public static String getLogText(String method, String message, AssetAdministrationShellDescriptor aas) { + StringBuilder txt = new StringBuilder(); + txt.append(method); + txt.append(": "); + txt.append("Request for AAS: "); + if (aas.getId() != null) { + txt.append("'"); + txt.append(aas.getId()); + txt.append("' constraint violated: "); + txt.append(message); + } + else { + txt.append("no Id given!"); + } + return txt.toString(); + } + + + /** + * Creates the log text for a Submodel constraint violation. + * + * @param method The desired method name. + * @param message The desire dmessage. + * @param aasId The ID of the AAS, or null if not available. + * @param submodel The The created log text. + * @return The created log text. + */ + public static String getLogText(String method, String message, String aasId, SubmodelDescriptor submodel) { + StringBuilder txt = new StringBuilder(); + txt.append(method); + txt.append(": Request for "); + if (aasId != null) { + txt.append("AAS: '"); + txt.append(aasId); + txt.append("' "); + } + txt.append("Submodel: "); + if (submodel.getId() != null) { + txt.append("'"); + txt.append(submodel.getId()); + txt.append("' constraint violated: "); + txt.append(message); + } + else { + txt.append("no Id given!"); + } + return txt.toString(); } diff --git a/service/src/main/resources/logback-spring.xml b/service/src/main/resources/logback-spring.xml deleted file mode 100644 index 5679084e..00000000 --- a/service/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - ${PATTERN_STDOUT} - - - - logs/App.log - false - - INFO - - - %date{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger{55}: %msg%n - - - - - - - -