diff options
Diffstat (limited to 'cps-ncmp-service')
15 files changed, 184 insertions, 106 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index 9c3d9448ef..f498e5d4fb 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -188,33 +188,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId); final List<YangModelCmHandle.Property> dmiProperties = yangModelCmHandle.getDmiProperties(); final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties(); - ncmpServiceCmHandle.setCmHandleID(yangModelCmHandle.getId()); + ncmpServiceCmHandle.setCmHandleId(yangModelCmHandle.getId()); setDmiProperties(dmiProperties, ncmpServiceCmHandle); setPublicProperties(publicProperties, ncmpServiceCmHandle); return ncmpServiceCmHandle; } - private void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties, - final NcmpServiceCmHandle ncmpServiceCmHandle) { - final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size()); - asPropertiesMap(dmiProperties, dmiPropertiesMap); - ncmpServiceCmHandle.setDmiProperties(dmiPropertiesMap); - } - - private void setPublicProperties(final List<YangModelCmHandle.Property> publicProperties, - final NcmpServiceCmHandle ncmpServiceCmHandle) { - final Map<String, String> publicPropertiesMap = new LinkedHashMap<>(); - asPropertiesMap(publicProperties, publicPropertiesMap); - ncmpServiceCmHandle.setPublicProperties(publicPropertiesMap); - } - - private void asPropertiesMap(final List<YangModelCmHandle.Property> properties, - final Map<String, String> propertiesMap) { - for (final YangModelCmHandle.Property property: properties) { - propertiesMap.put(property.getName(), property.getValue()); - } - } - /** * THis method registers a cm handle and initiates modules sync. * @@ -223,45 +202,24 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ public List<CmHandleRegistrationResponse> parseAndCreateCmHandlesInDmiRegistrationAndSyncModules( final DmiPluginRegistration dmiPluginRegistration) { - return dmiPluginRegistration.getCreatedCmHandles().stream() - .map(cmHandle -> - YangModelCmHandle.toYangModelCmHandle( - dmiPluginRegistration.getDmiPlugin(), - dmiPluginRegistration.getDmiDataPlugin(), - dmiPluginRegistration.getDmiModelPlugin(), cmHandle) - ) - .map(this::registerAndSyncNewCmHandle) - .collect(Collectors.toList()); - } - - private static Object handleResponse(final ResponseEntity<?> responseEntity, final OperationEnum operation) { - if (responseEntity.getStatusCode().is2xxSuccessful()) { - return responseEntity.getBody(); - } else { - final String exceptionMessage = "Unable to " + operation.toString() + " resource data."; - throw new HttpClientRequestException(exceptionMessage, (String) responseEntity.getBody(), - responseEntity.getStatusCodeValue()); - } - } - - private CmHandleRegistrationResponse registerAndSyncNewCmHandle(final YangModelCmHandle yangModelCmHandle) { + List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(); try { - CpsValidator.validateNameCharacters(yangModelCmHandle.getId()); - final String cmHandleJsonData = String.format("{\"cm-handles\":[%s]}", - jsonObjectMapper.asJsonString(yangModelCmHandle)); - cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT, - cmHandleJsonData, NO_TIMESTAMP); - syncModulesAndCreateAnchor(yangModelCmHandle); - return CmHandleRegistrationResponse.createSuccessResponse(yangModelCmHandle.getId()); - } catch (final AlreadyDefinedException alreadyDefinedException) { - return CmHandleRegistrationResponse.createFailureResponse( - yangModelCmHandle.getId(), RegistrationError.CM_HANDLE_ALREADY_EXIST); + cmHandleRegistrationResponses = dmiPluginRegistration.getCreatedCmHandles().stream() + .map(cmHandle -> + YangModelCmHandle.toYangModelCmHandle( + dmiPluginRegistration.getDmiPlugin(), + dmiPluginRegistration.getDmiDataPlugin(), + dmiPluginRegistration.getDmiModelPlugin(), cmHandle) + ) + .map(this::registerAndSyncNewCmHandle) + .collect(Collectors.toList()); } catch (final DataValidationException dataValidationException) { - return CmHandleRegistrationResponse.createFailureResponse(yangModelCmHandle.getId(), - RegistrationError.CM_HANDLE_INVALID_ID); - } catch (final Exception exception) { - return CmHandleRegistrationResponse.createFailureResponse(yangModelCmHandle.getId(), exception); + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createFailureResponse(dmiPluginRegistration + .getCreatedCmHandles().stream() + .map(NcmpServiceCmHandle::getCmHandleId).findFirst().orElse(null), + RegistrationError.CM_HANDLE_INVALID_ID)); } + return cmHandleRegistrationResponses; } protected void syncModulesAndCreateAnchor(final YangModelCmHandle yangModelCmHandle) { @@ -348,4 +306,53 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService cmHandleId, resourceIdentifier, optionsParamInQuery, dataStore, requestId, topicParamInQuery); return handleResponse(responseEntity, OperationEnum.READ); } + + private void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size()); + asPropertiesMap(dmiProperties, dmiPropertiesMap); + ncmpServiceCmHandle.setDmiProperties(dmiPropertiesMap); + } + + private void setPublicProperties(final List<YangModelCmHandle.Property> publicProperties, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + final Map<String, String> publicPropertiesMap = new LinkedHashMap<>(); + asPropertiesMap(publicProperties, publicPropertiesMap); + ncmpServiceCmHandle.setPublicProperties(publicPropertiesMap); + } + + private void asPropertiesMap(final List<YangModelCmHandle.Property> properties, + final Map<String, String> propertiesMap) { + for (final YangModelCmHandle.Property property: properties) { + propertiesMap.put(property.getName(), property.getValue()); + } + } + + + private CmHandleRegistrationResponse registerAndSyncNewCmHandle(final YangModelCmHandle yangModelCmHandle) { + try { + final String cmHandleJsonData = String.format("{\"cm-handles\":[%s]}", + jsonObjectMapper.asJsonString(yangModelCmHandle)); + cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT, + cmHandleJsonData, NO_TIMESTAMP); + syncModulesAndCreateAnchor(yangModelCmHandle); + return CmHandleRegistrationResponse.createSuccessResponse(yangModelCmHandle.getId()); + } catch (final AlreadyDefinedException alreadyDefinedException) { + return CmHandleRegistrationResponse.createFailureResponse( + yangModelCmHandle.getId(), RegistrationError.CM_HANDLE_ALREADY_EXIST); + } catch (final Exception exception) { + return CmHandleRegistrationResponse.createFailureResponse(yangModelCmHandle.getId(), exception); + } + } + + private static Object handleResponse(final ResponseEntity<?> responseEntity, final OperationEnum operation) { + if (responseEntity.getStatusCode().is2xxSuccessful()) { + return responseEntity.getBody(); + } else { + final String exceptionMessage = "Unable to " + operation.toString() + " resource data."; + throw new HttpClientRequestException(exceptionMessage, (String) responseEntity.getBody(), + responseEntity.getStatusCodeValue()); + } + } + }
\ No newline at end of file diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java index ff79f87245..aae2f209ae 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java @@ -72,7 +72,7 @@ public class NetworkCmProxyDataServicePropertyHandler { final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles) { final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(); for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) { - final String cmHandle = ncmpServiceCmHandle.getCmHandleID(); + final String cmHandle = ncmpServiceCmHandle.getCmHandleId(); try { CpsValidator.validateNameCharacters(cmHandle); final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandle); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java index 855e52dcda..ad85edde7b 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java @@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.client.DmiRestClient; import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration; import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; +import org.onap.cps.utils.CpsValidator; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -69,6 +70,7 @@ public class DmiDataOperations extends DmiOperations { final DataStoreEnum dataStore, final String requestId, final String topicParamInQuery) { + CpsValidator.validateNameCharacters(cmHandleId); final YangModelCmHandle yangModelCmHandle = yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId); final DmiRequestBody dmiRequestBody = DmiRequestBody.builder() @@ -77,7 +79,7 @@ public class DmiDataOperations extends DmiOperations { .build(); dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties()); final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody); - final var dmiResourceDataUrl = dmiServiceUrlBuilder.getDmiDatastoreUrl( + final String dmiResourceDataUrl = dmiServiceUrlBuilder.getDmiDatastoreUrl( dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery, topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables( yangModelCmHandle, cmHandleId, dataStore)); @@ -100,6 +102,7 @@ public class DmiDataOperations extends DmiOperations { final OperationEnum operation, final String requestData, final String dataType) { + CpsValidator.validateNameCharacters(cmHandleId); final YangModelCmHandle yangModelCmHandle = yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId); final DmiRequestBody dmiRequestBody = DmiRequestBody.builder() @@ -110,9 +113,9 @@ public class DmiDataOperations extends DmiOperations { dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties()); final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody); final String dmiUrl = - dmiServiceUrlBuilder.getDmiDatastoreUrl(dmiServiceUrlBuilder.populateQueryParams(resourceId, - null, null), - dmiServiceUrlBuilder.populateUriVariables(yangModelCmHandle, cmHandleId, PASSTHROUGH_RUNNING)); + dmiServiceUrlBuilder.getDmiDatastoreUrl(dmiServiceUrlBuilder.populateQueryParams(resourceId, + null, null), + dmiServiceUrlBuilder.populateUriVariables(yangModelCmHandle, cmHandleId, PASSTHROUGH_RUNNING)); return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java index 6b6bdf5be4..0efe8d5b62 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java @@ -28,6 +28,7 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; +import org.onap.cps.utils.CpsValidator; import org.springframework.stereotype.Component; /** @@ -48,9 +49,10 @@ public class YangModelCmHandleRetriever { * @return yang model cm handle */ public YangModelCmHandle getDmiServiceNamesAndProperties(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); final DataNode cmHandleDataNode = getCmHandleDataNode(cmHandleId); final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle(); - ncmpServiceCmHandle.setCmHandleID(cmHandleId); + ncmpServiceCmHandle.setCmHandleId(cmHandleId); populateCmHandleProperties(cmHandleDataNode, ncmpServiceCmHandle); return YangModelCmHandle.toYangModelCmHandle( String.valueOf(cmHandleDataNode.getLeaves().get("dmi-service-name")), diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java index b60aac9518..b679107251 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java @@ -30,6 +30,7 @@ import org.apache.logging.log4j.util.TriConsumer; import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration; import org.onap.cps.ncmp.api.impl.operations.DmiOperations; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; +import org.onap.cps.utils.CpsValidator; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -70,25 +71,26 @@ public class DmiServiceUrlBuilder { .pathSegment("{dmiBasePath}") .pathSegment("v1") .pathSegment("ch") - .pathSegment("{cmHandle}"); + .pathSegment("{cmHandleId}"); } /** * This method populates uri variables. * * @param yangModelCmHandle get dmi service name - * @param cmHandle cm handle name for dmi registration + * @param cmHandleId cm handle id for dmi registration * @return {@code String} dmi service url as string */ public Map<String, Object> populateUriVariables(final YangModelCmHandle yangModelCmHandle, - final String cmHandle, + final String cmHandleId, final DmiOperations.DataStoreEnum dataStore) { + CpsValidator.validateNameCharacters(cmHandleId); final Map<String, Object> uriVariables = new HashMap<>(); final String dmiBasePath = dmiProperties.getDmiBasePath(); uriVariables.put("dmiServiceName", yangModelCmHandle.resolveDmiServiceName(DATA)); uriVariables.put("dmiBasePath", dmiBasePath); - uriVariables.put("cmHandle", cmHandle); + uriVariables.put("cmHandleId", cmHandleId); uriVariables.put("dataStore", dataStore.getValue()); return uriVariables; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java index e46b9e3da5..fd3528187e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java @@ -35,6 +35,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; +import org.onap.cps.utils.CpsValidator; /** * Cm Handle which follows the Yang resource dmi registry model when persisting data to DMI or the DB. @@ -75,8 +76,9 @@ public class YangModelCmHandle { final String dmiDataServiceName, final String dmiModelServiceName, final NcmpServiceCmHandle ncmpServiceCmHandle) { + CpsValidator.validateNameCharacters(ncmpServiceCmHandle.getCmHandleId()); final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle(); - yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleID()); + yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleId()); yangModelCmHandle.setDmiServiceName(dmiServiceName); yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName); yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java index 938127020c..6811b59e00 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java @@ -39,7 +39,7 @@ import org.springframework.validation.annotation.Validated; @NoArgsConstructor public class NcmpServiceCmHandle { - private String cmHandleID; + private String cmHandleId; @JsonSetter(nulls = Nulls.AS_EMPTY) private Map<String, String> dmiProperties = Collections.emptyMap(); diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy index 553ac72790..673230e74c 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy @@ -51,7 +51,7 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification { given: 'a cm handle' def ncmpServiceCmHandle = new NcmpServiceCmHandle() def dmiServiceName = 'some service name' - ncmpServiceCmHandle.cmHandleID = 'cm handle id 1' + ncmpServiceCmHandle.cmHandleId = 'cm-handle-id-1' def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '' , '', ncmpServiceCmHandle) and: 'DMI operations returns some module references' def moduleReferences = [ new ModuleReference(moduleName:'module1',revision:'1'), diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy index cb4d5ef406..1f41c6b8c9 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy @@ -51,7 +51,7 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { @Shared - def ncmpServiceCmHandle = new NcmpServiceCmHandle() + def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id') @Shared def cmHandlesArray = ['cmHandle001'] @@ -71,8 +71,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'DMI Registration: Create, Update & Delete operations are processed in the right order'() { given: 'a registration with operations of all three types' def dmiRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleID: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) - dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleID: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) + dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) + dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) dmiRegistration.setRemovedCmHandles(['cmhandle-2']) when: 'registration is processed' objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration) @@ -88,8 +88,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'DMI Registration: Response from all operations types are in response'() { given: 'a registration with operations of all three types' def dmiRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleID: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) - dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleID: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) + dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) + dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) dmiRegistration.setRemovedCmHandles(['cmhandle-2']) and: 'update cm-handles can be processed successfully' def updateResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-2')] @@ -153,7 +153,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'Create CM-Handle Successfully: #scenario.'() { given: 'a registration without cm-handle properties' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleID: 'cmhandle', dmiProperties: dmiProperties, publicProperties: publicProperties)] + dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: 'cmhandle', dmiProperties: dmiProperties, publicProperties: publicProperties)] when: 'registration is updated' def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) then: 'a successful response is received' @@ -190,9 +190,9 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'Create CM-Handle Multiple Requests: All cm-handles creation requests are processed'() { given: 'a registration with three cm-handles to be created' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', - createdCmHandles: [new NcmpServiceCmHandle(cmHandleID: 'cmhandle1'), - new NcmpServiceCmHandle(cmHandleID: 'cmhandle2'), - new NcmpServiceCmHandle(cmHandleID: 'cmhandle3')]) + createdCmHandles: [new NcmpServiceCmHandle(cmHandleId: 'cmhandle1'), + new NcmpServiceCmHandle(cmHandleId: 'cmhandle2'), + new NcmpServiceCmHandle(cmHandleId: 'cmhandle3')]) and: 'cm-handle creation is successful for 1st and 3rd; failed for 2nd' mockCpsDataService.saveListElements(_, _, _, _, _) >> {} >> { throw new RuntimeException("Failed") } >> {} when: 'registration is updated to create cm-handles' @@ -220,7 +220,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'Create CM-Handle Error Handling: Registration fails: #scenario'() { given: 'a registration without cm-handle properties' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleID: cmHandleId)] + dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: cmHandleId)] and: 'cm-handler registration fails: #scenario' mockCpsDataService.saveListElements(_, _, _, _, _) >> { throw exception } when: 'registration is updated' @@ -247,7 +247,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def objectUnderTest = getObjectUnderTest() and: 'a registration without cm-handle properties' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleID: 'cmhandle')] + dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: 'cmhandle')] and: 'cm-handler models sync fails' objectUnderTest.syncModulesAndCreateAnchor(*_) >> { throw new RuntimeException('Model-Sync failed') } when: 'registration is updated' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 2d01dba522..7ddbbb21d2 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -25,6 +25,7 @@ package org.onap.cps.ncmp.api.impl import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.spi.exceptions.DataValidationException import spock.lang.Shared import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL @@ -83,6 +84,17 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { >> { new ResponseEntity<>(HttpStatus.CREATED) } } + def 'Write resource data for pass-through running from DMI using an invalid id.'() { + when: 'write resource data is called' + objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('invalid cm handle name', + 'testResourceId', CREATE, + '{some-json}', 'application/json') + then: 'exception is thrown' + thrown(DataValidationException.class) + and: 'DMI is not invoked' + 0 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi(_, _, _, _, _) + } + def 'Write resource data for pass-through running from DMI using POST "not found" response (from DMI).'() { given: 'cpsDataService returns valid dataNode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', @@ -124,6 +136,17 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { response == 'dmi-response' } + def 'Get resource data for pass-through operational from DMI with invalid name.'() {\ + when: 'get resource data operational for cm-handle is called' + objectUnderTest.getResourceDataOperationalForCmHandle('invalid test cm handle', + 'testResourceId', + OPTIONS_PARAM, + NO_TOPIC, + NO_REQUEST_ID) + then: 'A data validation Exception is thrown' + thrown(DataValidationException) + } + def 'Get resource data for pass-through operational from DMI with Json Processing Exception.'() { given: 'cps data service returns valid data node' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', @@ -191,6 +214,17 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { response == '{dmi-response}' } + def 'Get resource data for pass-through running from DMI with invalid name.'() { + when: 'get resource data operational for cm-handle is called' + objectUnderTest.getResourceDataPassThroughRunningForCmHandle('invalid test cm handle', + 'testResourceId', + OPTIONS_PARAM, + NO_TOPIC, + NO_REQUEST_ID) + then: 'A data validation Exception is thrown' + thrown(DataValidationException) + } + def 'Get resource data for pass-through running from DMI return NOK response.'() { given: 'cpsDataService returns valid dataNode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', @@ -223,6 +257,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 1 * mockCpsModuleService.getYangResourcesModuleReferences('NFP-Operational','some-cm-handle') } + def 'Getting Yang Resources with an invalid #scenario.'() { + when: 'yang resources is called' + objectUnderTest.getYangResourcesModuleReferences('invalid cm handle with spaces') + then: 'a data validation exception is thrown' + thrown(DataValidationException) + and: 'CPS module services is not invoked' + 0 * mockCpsModuleService.getYangResourcesModuleReferences(_, _) + } + def 'Get cm handle identifiers for the given module names.'() { when: 'execute a cm handle search for the given module names' objectUnderTest.executeCmHandleHasAllModulesSearch(['some-module-name']) @@ -240,12 +283,21 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'getting cm handle details for a given cm handle id from ncmp service' def result = objectUnderTest.getNcmpServiceCmHandle('Some-Cm-Handle') then: 'the result returns the correct data' - result.cmHandleID == 'Some-Cm-Handle' + result.cmHandleId == 'Some-Cm-Handle' result.dmiProperties ==[ Book:'Romance Novel' ] result.publicProperties == [ "Public Book":'Public Romance Novel' ] } + def 'Get a cm handle with an invalid id.'() { + when: 'getting cm handle details for a given cm handle id with an invalid name' + objectUnderTest.getNcmpServiceCmHandle('invalid cm handle with spaces') + then: 'an exception is thrown' + thrown(DataValidationException) + and: 'the yang model cm handle retriever is not invoked' + 0 * mockYangModelCmHandleRetriever.getDmiServiceNamesAndProperties(_) + } + def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() { given: 'cpsDataService returns valid datanode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy index 7aacbda513..5eba5eecd2 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy @@ -29,7 +29,6 @@ import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Registra import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status import org.onap.cps.api.CpsDataService -import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.exceptions.DataNodeNotFoundException @@ -58,7 +57,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { given: 'the CPS service return a CM handle' mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'an update cm handle request with public properties updates' - def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: updatedPublicProperties)] + def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: updatedPublicProperties)] when: 'update data node leaves is called with the update request' objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest) then: 'the replace list method is called with correct params' @@ -80,7 +79,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { given: 'the CPS service return a CM handle' mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'an update cm handle request with DMI properties updates' - def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, dmiProperties: updatedDmiProperties)] + def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: updatedDmiProperties)] when: 'update data node leaves is called with the update request' objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest) then: 'replace list method should is called with correct params' @@ -104,7 +103,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { def cmHandleDataNode = new DataNode(xpath: cmHandleXpath, childDataNodes: originalPropertyDataNodes) mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'an update cm handle request that removes all public properties(existing and non-existing)' - def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])] + def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])] when: 'update data node leaves is called with the update request' objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest) then: 'the replace list method is not called' @@ -123,7 +122,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { def '#scenario error leads to #exception when we try to update cmHandle'() { given: 'cm handles request' - def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: [:], dmiProperties: [:])] + def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: [:], dmiProperties: [:])] and: 'data node cannot be found' mockCpsDataService.getDataNode(*_) >> { throw exception } when: 'update data node leaves is called using correct parameters' @@ -146,9 +145,9 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { def 'Multiple update operations in a single request'() { given: 'cm handles request' - def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:]), - new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:]), - new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:])] + def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:]), + new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:]), + new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: ['publicProp1': "value"], dmiProperties: [:])] and: 'data node can be found for 1st and 3rd cm-handle but not for 2nd cm-handle' mockCpsDataService.getDataNode(*_) >> cmHandleDataNode >> { throw new DataNodeNotFoundException('NCMP-Admin', 'ncmp-dmi-registry') } >> cmHandleDataNode when: 'update data node leaves is called using correct parameters' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy index e6f63ce1a2..563116f402 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy @@ -48,7 +48,7 @@ abstract class DmiOperationsBaseSpec extends Specification { def yangModelCmHandle = new YangModelCmHandle() def static dmiServiceName = 'some service name' - def static cmHandleId = 'some cm handle' + def static cmHandleId = 'some-cm-handle' def static resourceIdentifier = 'parent/child' def mockYangModelCmHandleRetrieval(dmiProperties) { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy index 593a6ec936..bc30c9c777 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy @@ -22,6 +22,7 @@ package org.onap.cps.ncmp.api.impl.operations import org.onap.cps.api.CpsDataService import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.spi.exceptions.DataValidationException import spock.lang.Shared import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS @@ -34,19 +35,19 @@ class YangModelCmHandleRetrieverSpec extends Specification { def objectUnderTest = new YangModelCmHandleRetriever(mockCpsDataService) - def cmHandleId = 'some cm handle' + def cmHandleId = 'some-cm-handle' def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"] - def xpath = "/dmi-registry/cm-handles[@id='some cm handle']" + def xpath = "/dmi-registry/cm-handles[@id='some-cm-handle']" @Shared def childDataNodesForCmHandleWithAllProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"]), new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])] @Shared - def childDataNodesForCmHandleWithDMIProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"])] + def childDataNodesForCmHandleWithDMIProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some-cm-handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"])] @Shared - def childDataNodesForCmHandleWithPublicProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])] + def childDataNodesForCmHandleWithPublicProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some-cm-handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])] def "Retrieve CmHandle using datanode with #scenario."() { given: 'the cps data service returns a data node from the DMI registry' @@ -69,4 +70,13 @@ class YangModelCmHandleRetrieverSpec extends Specification { 'just DMI properties' | childDataNodesForCmHandleWithDMIProperties || [new YangModelCmHandle.Property("name1", "value1")] || [] 'just public properties' | childDataNodesForCmHandleWithPublicProperties || [] || [new YangModelCmHandle.Property("name2", "value2")] } + + def "Retrieve CmHandle using datanode with invalid CmHandle id."() { + when: 'retrieving the yang modelled cm handle with an invalid id' + def result = objectUnderTest.getDmiServiceNamesAndProperties('cm handle id with spaces') + then: 'a data validation exception is thrown' + thrown(DataValidationException) + and: 'the result is not returned' + result == null + } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy index 470015ec17..7bbc3d7533 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy @@ -31,6 +31,7 @@ class YangModelCmHandleSpec extends Specification { def 'Creating yang model cm handle from a service api cm handle.'() { given: 'a cm handle with properties' def ncmpServiceCmHandle = new NcmpServiceCmHandle() + ncmpServiceCmHandle.cmHandleId = 'cm-handle-id01' ncmpServiceCmHandle.dmiProperties = [myDmiProperty:'value1'] ncmpServiceCmHandle.publicProperties = [myPublicProperty:'value2'] when: 'it is converted to a yang model cm handle' @@ -47,7 +48,7 @@ class YangModelCmHandleSpec extends Specification { def 'Resolve DMI service name: #scenario and #requiredService service require.'() { given: 'a yang model cm handle' - def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new NcmpServiceCmHandle()) + def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1')) expect: assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService where: diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy index 1615d055db..4c8dcace7d 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy @@ -32,21 +32,21 @@ import spock.lang.Specification class DmiServiceUrlBuilderSpec extends Specification { @Shared - YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle("dmiServiceName", - "dmiDataServiceName", "dmiModuleServiceName", new NcmpServiceCmHandle()) + YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('dmiServiceName', + 'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id')) - NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties(); + NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties() def objectUnderTest = new DmiServiceUrlBuilder(dmiProperties) def 'Create the dmi service url with #scenario.'() { given: 'uri variables' - dmiProperties.dmiBasePath = 'dmi'; + dmiProperties.dmiBasePath = 'dmi' def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle, - "cmHandle", PASSTHROUGH_RUNNING); + "cmHandle", PASSTHROUGH_RUNNING) and: 'query params' def uriQueries = objectUnderTest.populateQueryParams(resourceId, - 'optionsParamInQuery', topicParamInQuery); + 'optionsParamInQuery', topicParamInQuery) when: 'a dmi datastore service url is generated' def dmiServiceUrl = objectUnderTest.getDmiDatastoreUrl(uriQueries, uriVars) then: 'service url is generated as expected' @@ -61,12 +61,12 @@ class DmiServiceUrlBuilderSpec extends Specification { def 'Populate dmi data store url #scenario.'() { given: 'uri variables are created' - dmiProperties.dmiBasePath = dmiBasePath; + dmiProperties.dmiBasePath = dmiBasePath def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle, - "cmHandle", PASSTHROUGH_RUNNING); + "cmHandle", PASSTHROUGH_RUNNING) and: 'null query params' def uriQueries = objectUnderTest.populateQueryParams(null, - null, null); + null, null) when: 'a dmi datastore service url is generated' def dmiServiceUrl = objectUnderTest.getDmiDatastoreUrl(uriQueries, uriVars) then: 'the created dmi service url matches the expected' |