diff --git a/src/main/java/org/etsi/osl/tmf/sim638/api/ServiceApiController.java b/src/main/java/org/etsi/osl/tmf/sim638/api/ServiceApiController.java index ac5ee19bc3ab6b14baff64f96a69a4369a84ff56..9771d5d416eb2c336d31e75728884a753bf37b0d 100644 --- a/src/main/java/org/etsi/osl/tmf/sim638/api/ServiceApiController.java +++ b/src/main/java/org/etsi/osl/tmf/sim638/api/ServiceApiController.java @@ -30,6 +30,8 @@ import org.etsi.osl.tmf.sim638.model.ServiceCreate; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.etsi.osl.tmf.sim638.service.ServiceRepoService; import org.etsi.osl.tmf.util.AddUserAsOwnerToRelatedParties; +import org.etsi.osl.tmf.util.ServiceInventoryValidator; +import org.etsi.osl.tmf.util.ServiceSpecificationValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -40,6 +42,8 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.RequestMapping; import org.etsi.osl.model.nfv.UserRoleType; @@ -61,6 +65,15 @@ public class ServiceApiController implements ServiceApi { @Autowired ServiceRepoService serviceRepoService; + @Autowired + private ServiceInventoryValidator serviceInventoryValidator; + + // Custom validation resulting from ServiceSpecCharacteristicValue range interval and type validation (https://labs.etsi.org/rep/groups/osl/code/-/epics/30) + @InitBinder + protected void initBinder(WebDataBinder binder) { + binder.addValidators(serviceInventoryValidator); + } + @org.springframework.beans.factory.annotation.Autowired public ServiceApiController(ObjectMapper objectMapper, HttpServletRequest request) { this.objectMapper = objectMapper; diff --git a/src/main/java/org/etsi/osl/tmf/so641/api/ServiceOrderApiController.java b/src/main/java/org/etsi/osl/tmf/so641/api/ServiceOrderApiController.java index bd0a98d10a33c582bcbe235fad111bca33d0ff79..77bd39e8199c7a470490421bd9c4b6039fcacecf 100644 --- a/src/main/java/org/etsi/osl/tmf/so641/api/ServiceOrderApiController.java +++ b/src/main/java/org/etsi/osl/tmf/so641/api/ServiceOrderApiController.java @@ -32,6 +32,7 @@ import org.etsi.osl.tmf.so641.model.ServiceOrderCreate; import org.etsi.osl.tmf.so641.model.ServiceOrderUpdate; import org.etsi.osl.tmf.so641.reposervices.ServiceOrderRepoService; import org.etsi.osl.tmf.util.AddUserAsOwnerToRelatedParties; +import org.etsi.osl.tmf.util.ServiceOrderValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -46,10 +47,8 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.*; import org.etsi.osl.model.nfv.UserRoleType; import io.swagger.v3.oas.annotations.Parameter; @@ -79,6 +78,15 @@ public class ServiceOrderApiController implements ServiceOrderApi { @Autowired ServiceOrderApiRouteBuilder serviceOrderApiRouteBuilder; + @Autowired + private ServiceOrderValidator serviceOrderValidator; + + // Custom validation resulting from ServiceSpecCharacteristicValue range interval and type validation (https://labs.etsi.org/rep/groups/osl/code/-/epics/30) + @InitBinder + protected void initBinder(WebDataBinder binder) { + binder.addValidators(serviceOrderValidator); + } + @org.springframework.beans.factory.annotation.Autowired public ServiceOrderApiController(ObjectMapper objectMapper, HttpServletRequest request) { this.objectMapper = objectMapper; diff --git a/src/main/java/org/etsi/osl/tmf/util/CharacteristicParser.java b/src/main/java/org/etsi/osl/tmf/util/CharacteristicParser.java new file mode 100644 index 0000000000000000000000000000000000000000..74a0638935d112cecc6bd18d8697c2ed943f5949 --- /dev/null +++ b/src/main/java/org/etsi/osl/tmf/util/CharacteristicParser.java @@ -0,0 +1,47 @@ +package org.etsi.osl.tmf.util; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.etsi.osl.tmf.common.model.Any; +import org.etsi.osl.tmf.common.model.service.Characteristic; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue; + +import java.util.Set; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +public class CharacteristicParser { + private static final ObjectMapper mapper = new ObjectMapper(); + + public void updateServiceSpecCharacteristicValues( + Set serviceSpecCharacteristicValues, + Characteristic characteristic + ) { + Any input = characteristic.getValue(); + if (input == null) { + return; + } + List values = new ArrayList<>(); + try { + JsonNode node = mapper.readTree(input.getValue()); + if (node.isArray()) { + values = mapper.readValue(input.getValue(), new TypeReference<>() {}); + } else if (node.isObject()) { + values.add(mapper.treeToValue(node, Any.class)); + } else { + values.add(input); + } + } catch (Exception e) { + values.add(input); + } + Iterator serviceSpecCharacteristicValueIterator = serviceSpecCharacteristicValues.iterator(); + Iterator valueIterator = values.iterator(); + while (serviceSpecCharacteristicValueIterator.hasNext() && valueIterator.hasNext()) { + ServiceSpecCharacteristicValue serviceSpecCharacteristicValue = serviceSpecCharacteristicValueIterator.next(); + Any value = valueIterator.next(); + serviceSpecCharacteristicValue.setValue(value); + } + } +} diff --git a/src/main/java/org/etsi/osl/tmf/util/ServiceInventoryValidator.java b/src/main/java/org/etsi/osl/tmf/util/ServiceInventoryValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..8ffb421a7a7030a830cce0a4b91ee5c89cb85248 --- /dev/null +++ b/src/main/java/org/etsi/osl/tmf/util/ServiceInventoryValidator.java @@ -0,0 +1,50 @@ +package org.etsi.osl.tmf.util; + +import org.etsi.osl.tmf.common.model.service.Characteristic; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristic; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue; +import org.etsi.osl.tmf.scm633.model.ServiceSpecification; +import org.etsi.osl.tmf.scm633.reposervices.ServiceSpecificationRepoService; +import org.etsi.osl.tmf.sim638.model.ServiceUpdate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +import java.util.Set; + +@Component +public class ServiceInventoryValidator implements Validator { + @Autowired + private ServiceSpecificationRepoService serviceSpecificationRepoService; + + @Override + public boolean supports(Class clazz) { + return ServiceUpdate.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + ServiceUpdate update = (ServiceUpdate) target; + if (update.getServiceCharacteristic() == null || update.getServiceSpecificationRef() == null) { + return; + } + String serviceSpecificationId = update.getServiceSpecificationRef().getId(); + ServiceSpecification serviceSpecification = serviceSpecificationRepoService.findByUuid(serviceSpecificationId); + CharacteristicParser characteristicParser = new CharacteristicParser(); + for (Characteristic characteristic: update.getServiceCharacteristic()) { + ServiceSpecCharacteristic serviceSpecCharacteristic = serviceSpecification.findSpecCharacteristicByName(characteristic.getName()); + if (serviceSpecCharacteristic != null) { + Set serviceSpecCharacteristicValues = serviceSpecCharacteristic.getServiceSpecCharacteristicValue(); + characteristicParser.updateServiceSpecCharacteristicValues(serviceSpecCharacteristicValues, characteristic); + if (serviceSpecCharacteristicValues.stream().anyMatch(value -> { + ServiceSpecCharacteristicValueValidator serviceSpecCharacteristicValueValidator = new ServiceSpecCharacteristicValueValidator(value); + return !serviceSpecCharacteristicValueValidator.validateType() || !serviceSpecCharacteristicValueValidator.isWithinRangeInterval(); + })) { + errors.reject("invalid.request"); + return; + } + } + } + } +} diff --git a/src/main/java/org/etsi/osl/tmf/util/ServiceOrderValidator.java b/src/main/java/org/etsi/osl/tmf/util/ServiceOrderValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..e734699daf01529c9737813eea851128251f3e91 --- /dev/null +++ b/src/main/java/org/etsi/osl/tmf/util/ServiceOrderValidator.java @@ -0,0 +1,62 @@ +package org.etsi.osl.tmf.util; + +import org.etsi.osl.tmf.common.model.service.Characteristic; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristic; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue; +import org.etsi.osl.tmf.scm633.model.ServiceSpecification; +import org.etsi.osl.tmf.scm633.reposervices.ServiceSpecificationRepoService; +import org.etsi.osl.tmf.so641.model.ServiceOrderCreate; +import org.etsi.osl.tmf.so641.model.ServiceOrderItem; +import org.etsi.osl.tmf.so641.model.ServiceOrderUpdate; +import org.etsi.osl.tmf.so641.model.ServiceRestriction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +import java.util.Set; + +@Component +public class ServiceOrderValidator implements Validator { + @Autowired + private ServiceSpecificationRepoService serviceSpecificationRepoService; + + @Override + public boolean supports(Class clazz) { + return ServiceOrderCreate.class.isAssignableFrom(clazz) || ServiceOrderUpdate.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + if (!(target instanceof ServiceOrderCreate)) { + return; + } + ServiceOrderCreate create = (ServiceOrderCreate) target; + for (ServiceOrderItem orderItem: create.getOrderItem()) { + if (orderItem.getService() == null) { + return; + } + ServiceRestriction service = orderItem.getService(); + if (service.getServiceCharacteristic() == null || service.getServiceSpecification() == null) { + return; + } + String serviceSpecificationId = service.getServiceSpecification().getId(); + ServiceSpecification serviceSpecification = serviceSpecificationRepoService.findByUuid(serviceSpecificationId); + CharacteristicParser characteristicParser = new CharacteristicParser(); + for (Characteristic characteristic: service.getServiceCharacteristic()) { + ServiceSpecCharacteristic serviceSpecCharacteristic = serviceSpecification.findSpecCharacteristicByName(characteristic.getName()); + if (serviceSpecCharacteristic != null) { + Set serviceSpecCharacteristicValues = serviceSpecCharacteristic.getServiceSpecCharacteristicValue(); + characteristicParser.updateServiceSpecCharacteristicValues(serviceSpecCharacteristicValues, characteristic); + if (serviceSpecCharacteristicValues.stream().anyMatch(value -> { + ServiceSpecCharacteristicValueValidator serviceSpecCharacteristicValueValidator = new ServiceSpecCharacteristicValueValidator(value); + return !serviceSpecCharacteristicValueValidator.validateType() || !serviceSpecCharacteristicValueValidator.isWithinRangeInterval(); + })) { + errors.reject("invalid.request"); + return; + } + } + } + } + } +} diff --git a/src/main/java/org/etsi/osl/tmf/util/ServiceSpecCharacteristicValueValidator.java b/src/main/java/org/etsi/osl/tmf/util/ServiceSpecCharacteristicValueValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..0dc2074ead7d8fe6fc2a90e1de611abe216febc6 --- /dev/null +++ b/src/main/java/org/etsi/osl/tmf/util/ServiceSpecCharacteristicValueValidator.java @@ -0,0 +1,87 @@ +package org.etsi.osl.tmf.util; + +import org.etsi.osl.tmf.common.model.Any; +import org.etsi.osl.tmf.common.model.ERangeInterval; +import org.etsi.osl.tmf.common.model.EValueType; +import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Objects; + +public class ServiceSpecCharacteristicValueValidator { + private final ServiceSpecCharacteristicValue serviceSpecCharacteristicValue; + + public ServiceSpecCharacteristicValueValidator(ServiceSpecCharacteristicValue serviceSpecCharacteristicValue) { + this.serviceSpecCharacteristicValue = serviceSpecCharacteristicValue; + } + + public boolean validateType() { + final String INTEGER_REGEX = "[-+]?\\d+"; + final String FLOAT_REGEX = "[-+]?\\d*([.,]\\d+)?([eE][-+]?\\d+)?"; + final String BOOLEAN_REGEX = "(?i)true|false"; + final DateTimeFormatter ISO_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + if (serviceSpecCharacteristicValue.getValueType() == null) { + return true; + } + Any value = serviceSpecCharacteristicValue.getValue(); + if (value == null) { + return true; + } + String stringValue = value.getValue(); + if (stringValue == null || stringValue.isBlank()) { + return true; + } + try { + return switch (EValueType.getEnum(serviceSpecCharacteristicValue.getValueType())) { + case INTEGER, SMALLINT, lONGINT -> stringValue.matches(INTEGER_REGEX); + case FLOAT -> stringValue.matches(FLOAT_REGEX); + case BOOLEAN -> stringValue.matches(BOOLEAN_REGEX) || stringValue.matches(INTEGER_REGEX); + case TIMESTAMP -> { + try { + LocalDateTime.parse(stringValue, ISO_DATE_TIME); + yield true; + } catch (DateTimeParseException e) { + yield false; + } + } + default -> true; + }; + } catch (IllegalArgumentException e) { + return false; + } + } + + public boolean isWithinRangeInterval() { + if (serviceSpecCharacteristicValue.getRangeInterval() == null) { + return true; + } + if (!Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.INTEGER.getValue()) && + !Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.SMALLINT.getValue()) && + !Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.lONGINT.getValue())) { + return true; + } + Any value = serviceSpecCharacteristicValue.getValue(); + if (value == null) { + return true; + } + String stringValue = value.getValue(); + if (stringValue == null || stringValue.isBlank()) { + return true; + } + int valueFrom = serviceSpecCharacteristicValue.getValueFrom() != null ? serviceSpecCharacteristicValue.getValueFrom() : Integer.MIN_VALUE; + int valueTo = serviceSpecCharacteristicValue.getValueTo() != null ? serviceSpecCharacteristicValue.getValueTo() : Integer.MAX_VALUE; + try { + int intValue = Integer.parseInt(stringValue); + return switch (ERangeInterval.getEnum(serviceSpecCharacteristicValue.getRangeInterval())) { + case OPEN -> intValue > valueFrom && intValue < valueTo; + case CLOSED -> intValue >= valueFrom && intValue <= valueTo; + case CLOSED_BOTTOM -> intValue >= valueFrom && intValue < valueTo; + case CLOSED_TOP -> intValue > valueFrom && intValue <= valueTo; + }; + } catch (IllegalArgumentException e) { + return false; + } + } +} diff --git a/src/main/java/org/etsi/osl/tmf/util/ServiceSpecificationValidator.java b/src/main/java/org/etsi/osl/tmf/util/ServiceSpecificationValidator.java index 9608902282fc0379b56e4018024e6899eef58d91..0c3d2b3970c74b444c45256d286c63b030ea49c4 100644 --- a/src/main/java/org/etsi/osl/tmf/util/ServiceSpecificationValidator.java +++ b/src/main/java/org/etsi/osl/tmf/util/ServiceSpecificationValidator.java @@ -1,19 +1,10 @@ package org.etsi.osl.tmf.util; -import org.etsi.osl.tmf.common.model.Any; -import org.etsi.osl.tmf.common.model.ERangeInterval; -import org.etsi.osl.tmf.common.model.EValueType; -import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristicValue; import org.etsi.osl.tmf.scm633.model.ServiceSpecificationUpdate; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.Objects; - @Component public class ServiceSpecificationValidator implements Validator { @@ -31,78 +22,13 @@ public class ServiceSpecificationValidator implements Validator { boolean invalid = update.getServiceSpecCharacteristic().stream() .flatMap(serviceSpecCharacteristic -> serviceSpecCharacteristic.getServiceSpecCharacteristicValue().stream()) - .anyMatch(serviceSpecCharacteristicValue -> - !validateType(serviceSpecCharacteristicValue) || !isWithinRangeInterval(serviceSpecCharacteristicValue)); + .anyMatch(serviceSpecCharacteristicValue -> { + ServiceSpecCharacteristicValueValidator serviceSpecCharacteristicValueValidator = + new ServiceSpecCharacteristicValueValidator(serviceSpecCharacteristicValue); + return !serviceSpecCharacteristicValueValidator.validateType() || !serviceSpecCharacteristicValueValidator.isWithinRangeInterval(); + }); if (invalid) { errors.reject("invalid.request"); } } - - private boolean validateType(ServiceSpecCharacteristicValue serviceSpecCharacteristicValue) { - final String INTEGER_REGEX = "[-+]?\\d+"; - final String FLOAT_REGEX = "[-+]?\\d*([.,]\\d+)?([eE][-+]?\\d+)?"; - final String BOOLEAN_REGEX = "(?i)true|false"; - final DateTimeFormatter ISO_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - if (serviceSpecCharacteristicValue.getValueType() == null) { - return true; - } - Any value = serviceSpecCharacteristicValue.getValue(); - if (value == null) { - return true; - } - String stringValue = value.getValue(); - if (stringValue == null || stringValue.isBlank()) { - return true; - } - try { - return switch (EValueType.getEnum(serviceSpecCharacteristicValue.getValueType())) { - case INTEGER, SMALLINT, lONGINT -> stringValue.matches(INTEGER_REGEX); - case FLOAT -> stringValue.matches(FLOAT_REGEX); - case BOOLEAN -> stringValue.matches(BOOLEAN_REGEX) || stringValue.matches(INTEGER_REGEX); - case TIMESTAMP -> { - try { - LocalDateTime.parse(stringValue, ISO_DATE_TIME); - yield true; - } catch (DateTimeParseException e) { - yield false; - } - } - default -> true; - }; - } catch (IllegalArgumentException e) { - return false; - } - } - - private boolean isWithinRangeInterval(ServiceSpecCharacteristicValue serviceSpecCharacteristicValue) { - if (serviceSpecCharacteristicValue.getRangeInterval() == null) { - return true; - } - if (!Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.INTEGER.getValue()) && - !Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.SMALLINT.getValue()) && - !Objects.equals(serviceSpecCharacteristicValue.getValueType(), EValueType.lONGINT.getValue())) { - return true; - } - Any value = serviceSpecCharacteristicValue.getValue(); - if (value == null) { - return true; - } - String stringValue = value.getValue(); - if (stringValue == null || stringValue.isBlank()) { - return true; - } - int valueFrom = serviceSpecCharacteristicValue.getValueFrom() != null ? serviceSpecCharacteristicValue.getValueFrom() : Integer.MIN_VALUE; - int valueTo = serviceSpecCharacteristicValue.getValueTo() != null ? serviceSpecCharacteristicValue.getValueTo() : Integer.MAX_VALUE; - try { - int intValue = Integer.parseInt(stringValue); - return switch (ERangeInterval.getEnum(serviceSpecCharacteristicValue.getRangeInterval())) { - case OPEN -> intValue > valueFrom && intValue < valueTo; - case CLOSED -> intValue >= valueFrom && intValue <= valueTo; - case CLOSED_BOTTOM -> intValue >= valueFrom && intValue < valueTo; - case CLOSED_TOP -> intValue > valueFrom && intValue <= valueTo; - }; - } catch (IllegalArgumentException e) { - return false; - } - } } diff --git a/src/test/java/org/etsi/osl/services/api/sim638/ServiceApiControllerTest.java b/src/test/java/org/etsi/osl/services/api/sim638/ServiceApiControllerTest.java index 5f5b3f68cac0cdfbf7c483b022a572fe578b1305..6f3f17613f16e90df2a571fb7634750aac078095 100644 --- a/src/test/java/org/etsi/osl/services/api/sim638/ServiceApiControllerTest.java +++ b/src/test/java/org/etsi/osl/services/api/sim638/ServiceApiControllerTest.java @@ -7,16 +7,19 @@ import static org.mockito.Mockito.when; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; + +import java.io.*; import java.security.Principal; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.List; +import java.util.Set; + import org.apache.commons.io.IOUtils; import org.etsi.osl.services.api.BaseIT; import org.etsi.osl.tmf.JsonUtils; +import org.etsi.osl.tmf.common.model.Any; +import org.etsi.osl.tmf.common.model.service.Characteristic; import org.etsi.osl.tmf.common.model.service.ServiceSpecificationRef; import org.etsi.osl.tmf.scm633.model.ServiceSpecification; import org.etsi.osl.tmf.scm633.model.ServiceSpecificationCreate; @@ -24,10 +27,7 @@ import org.etsi.osl.tmf.sim638.api.ServiceApiController; import org.etsi.osl.tmf.sim638.model.Service; import org.etsi.osl.tmf.sim638.model.ServiceCreate; import org.etsi.osl.tmf.sim638.service.ServiceRepoService; -import org.etsi.osl.tmf.so641.model.ServiceOrderCreate; -import org.etsi.osl.tmf.so641.model.ServiceOrderItem; -import org.etsi.osl.tmf.so641.model.ServiceOrderStateType; -import org.etsi.osl.tmf.so641.model.ServiceRestriction; +import org.etsi.osl.tmf.so641.model.*; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -177,6 +177,28 @@ public class ServiceApiControllerTest extends BaseIT { } + @WithMockUser(username="osadmin", roles = {"ADMIN","USER"}) + @Test + public void testServiceInvalidRangeIntervalIsBadRequest() throws Exception { + ServiceCreate service = createServiceWithCharacteristicValue("9000"); + mvc.perform(MockMvcRequestBuilders.post("/serviceInventory/v4/service") + .with(SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJson(service))) + .andExpect(status().isBadRequest()); + } + + + @WithMockUser(username="osadmin", roles = {"ADMIN","USER"}) + @Test + public void testServiceInvalidTypesIsBadRequest() throws Exception { + ServiceCreate service = createServiceWithCharacteristicValue("not an integer"); + mvc.perform(MockMvcRequestBuilders.post("/serviceInventory/v4/service") + .with(SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJson(service))) + .andExpect(status().isBadRequest()); + } + + private String createService() throws Exception { int servicesCount = serviceRepoService.findAll().size(); @@ -224,6 +246,29 @@ public class ServiceApiControllerTest extends BaseIT { } + private ServiceCreate createServiceWithCharacteristicValue(String characteristicValue) throws Exception { + File sspec = new File("src/test/resources/reposervices/scm633/testServiceSpecValidRangeInterval.json"); + InputStream in = new FileInputStream(sspec); + String sspectext = IOUtils.toString(in, "UTF-8"); + ServiceCreate service = new ServiceCreate(); + + ServiceSpecificationCreate sspeccr = JsonUtils.toJsonObj(sspectext, ServiceSpecificationCreate.class); + sspeccr.setName("Spec1"); + ServiceSpecification responsesSpec = createServiceSpec(sspeccr); + ServiceSpecificationRef aServiceSpecificationRef = new ServiceSpecificationRef(); + aServiceSpecificationRef.setId(responsesSpec.getId()); + aServiceSpecificationRef.setName(responsesSpec.getName()); + service.setServiceSpecificationRef(aServiceSpecificationRef); + + Characteristic characteristic = new Characteristic(); + characteristic.setName("Port"); + characteristic.setValue(new Any(characteristicValue)); + service.setServiceCharacteristic(List.of(characteristic)); + + return service; + } + + private ServiceSpecification createServiceSpec( ServiceSpecificationCreate serviceSpecificationCreate) throws Exception { String response = mvc .perform(MockMvcRequestBuilders.post("/serviceCatalogManagement/v4/serviceSpecification") diff --git a/src/test/java/org/etsi/osl/services/api/so641/ServiceOrderApiControllerTest.java b/src/test/java/org/etsi/osl/services/api/so641/ServiceOrderApiControllerTest.java index 21f2429463a27b2d6a4f9f1cdeaaa77265e4ee6a..7318123d8bbd1d9602ba1e6f8262d9598b29c001 100644 --- a/src/test/java/org/etsi/osl/services/api/so641/ServiceOrderApiControllerTest.java +++ b/src/test/java/org/etsi/osl/services/api/so641/ServiceOrderApiControllerTest.java @@ -18,6 +18,8 @@ import java.util.Set; import org.apache.commons.io.IOUtils; import org.etsi.osl.services.api.BaseIT; import org.etsi.osl.tmf.JsonUtils; +import org.etsi.osl.tmf.common.model.Any; +import org.etsi.osl.tmf.common.model.service.Characteristic; import org.etsi.osl.tmf.common.model.service.Place; import org.etsi.osl.tmf.common.model.service.ServiceSpecificationRef; import org.etsi.osl.tmf.pm632.model.ContactMedium; @@ -303,6 +305,28 @@ public class ServiceOrderApiControllerTest extends BaseIT { } + @WithMockUser(username="osadmin", roles = {"ADMIN","USER"}) + @Test + public void testCreateServiceOrderInvalidRangeIntervalIsBadRequest() throws Exception { + ServiceOrderCreate serviceOrder = createServiceOrderWithCharacteristicValue("9000"); + mvc.perform(MockMvcRequestBuilders.post("/serviceOrdering/v4/serviceOrder") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJson(serviceOrder))) + .andExpect(status().isBadRequest()); + } + + + @WithMockUser(username="osadmin", roles = {"ADMIN","USER"}) + @Test + public void testCreateServiceOrderInvalidTypesIsBadRequest() throws Exception { + ServiceOrderCreate serviceOrder = createServiceOrderWithCharacteristicValue("not an integer"); + mvc.perform(MockMvcRequestBuilders.post("/serviceOrdering/v4/serviceOrder") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJson(serviceOrder))) + .andExpect(status().isBadRequest()); + } + + private String createServiceOrder() throws Exception { @@ -404,4 +428,38 @@ public class ServiceOrderApiControllerTest extends BaseIT { .contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJson(serviceOrder))) .andExpect(status().isBadRequest()).andReturn().getResponse().getContentAsString(); } + + + private ServiceOrderCreate createServiceOrderWithCharacteristicValue(String characteristicValue) throws Exception { + File sspec = new File("src/test/resources/reposervices/scm633/testServiceSpecValidRangeInterval.json"); + InputStream in = new FileInputStream(sspec); + String sspectext = IOUtils.toString(in, "UTF-8"); + + ServiceSpecificationCreate sspeccr = JsonUtils.toJsonObj(sspectext, ServiceSpecificationCreate.class); + ServiceSpecification responsesSpec = createServiceSpec(sspeccr); + + ServiceOrderCreate serviceOrder = new ServiceOrderCreate(); + serviceOrder.setCategory("Test Category"); + serviceOrder.setDescription("A Test Service"); + serviceOrder.setRequestedStartDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); + serviceOrder.setRequestedCompletionDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); + + ServiceOrderItem soi = new ServiceOrderItem(); + serviceOrder.getOrderItem().add(soi); + soi.setState(ServiceOrderStateType.ACKNOWLEDGED); + + ServiceRestriction serviceRestriction = new ServiceRestriction(); + ServiceSpecificationRef aServiceSpecificationRef = new ServiceSpecificationRef(); + aServiceSpecificationRef.setId(responsesSpec.getId()); + aServiceSpecificationRef.setName(responsesSpec.getName()); + + serviceRestriction.setServiceSpecification(aServiceSpecificationRef); + serviceRestriction.setName("aServiceRestriction"); + Characteristic characteristic = new Characteristic(); + characteristic.setName("Port"); + characteristic.setValue(new Any(characteristicValue)); + serviceRestriction.setServiceCharacteristic(Set.of(characteristic)); + soi.setService(serviceRestriction); + return serviceOrder; + } } \ No newline at end of file