Refactor Get Modules by CMHandle flow
- Used jayway to convert sdnc response to POJO to clean up classes
- Moved SDNC error handling to the SDNCOperation
- Added SdncException
- Added spring-security test Mock user in the controllerSpec
Issue-ID: CPS-571
Signed-off-by: Renu Kumari <renu.kumari@bell.ca>
Change-Id: Ice91e48536dd2e309721440b61d37a49ce43b403
diff --git a/pom.xml b/pom.xml
index 53969b4..552d30f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,10 @@
<artifactId>groovy</artifactId>
</dependency>
<dependency>
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
@@ -99,6 +103,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.2</version>
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java
new file mode 100644
index 0000000..a83485a
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/SdncException.java
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Bell Canada
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.dmi.exception;
+
+import org.springframework.http.HttpStatus;
+
+/*
+Use this exception when SDNC contract fails
+ */
+public class SdncException extends DmiException {
+
+ private static final long serialVersionUID = -2076096996672060566L;
+
+ /**
+ * Constructor.
+ *
+ * @param message message
+ * @param httpStatus httpStatus
+ * @param responseBody responseBody
+ */
+ public SdncException(final String message, final HttpStatus httpStatus, final String responseBody) {
+ super(message, String.format("sdnc http status: %s, response body : %s ",
+ httpStatus.toString(),
+ responseBody));
+ }
+
+ public SdncException(final String message, final String details, final Throwable cause) {
+ super(message, details, cause);
+ }
+
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
index b66e5c1..10ae1cf 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,12 +26,12 @@
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
-import org.apache.groovy.parser.antlr4.util.StringUtils;
import org.onap.cps.ncmp.dmi.config.DmiPluginConfig.DmiPluginProperties;
import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException;
import org.onap.cps.ncmp.dmi.exception.DmiException;
@@ -45,8 +46,7 @@
import org.onap.cps.ncmp.dmi.service.model.CmHandleOperation;
import org.onap.cps.ncmp.dmi.service.model.CreatedCmHandle;
import org.onap.cps.ncmp.dmi.service.model.ModuleReference;
-import org.onap.cps.ncmp.dmi.service.model.ModuleSchemaProperties;
-import org.onap.cps.ncmp.dmi.service.model.ModuleSchemas;
+import org.onap.cps.ncmp.dmi.service.model.ModuleSchema;
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -75,8 +75,8 @@
* @param objectMapper objectMapper
*/
public DmiServiceImpl(final DmiPluginProperties dmiPluginProperties,
- final NcmpRestClient ncmpRestClient,
- final SdncOperations sdncOperations, final ObjectMapper objectMapper) {
+ final NcmpRestClient ncmpRestClient,
+ final SdncOperations sdncOperations, final ObjectMapper objectMapper) {
this.dmiPluginProperties = dmiPluginProperties;
this.ncmpRestClient = ncmpRestClient;
this.objectMapper = objectMapper;
@@ -85,16 +85,14 @@
@Override
public ModuleSet getModulesForCmHandle(final String cmHandle) throws DmiException {
- final ResponseEntity<String> responseEntity = sdncOperations.getModulesFromNode(cmHandle);
- if (responseEntity.getStatusCode() == HttpStatus.OK) {
- final String responseBody = responseEntity.getBody();
- if (StringUtils.isEmpty(responseBody)) {
- throw new ModulesNotFoundException(cmHandle, "SDNC returned no modules for given cm-handle.");
- }
- return createModuleSchema(responseBody);
+ final Collection<ModuleSchema> moduleSchemas = sdncOperations.getModuleSchemasFromNode(cmHandle);
+ if (moduleSchemas.isEmpty()) {
+ throw new ModulesNotFoundException(cmHandle, "SDNC returned no modules for given cm-handle.");
} else {
- throw new DmiException("SDNC is not able to process request.",
- RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
+ final ModuleSet moduleSet = new ModuleSet();
+ moduleSchemas.forEach(moduleSchema ->
+ moduleSet.addSchemasItem(toModuleSetSchemas(moduleSchema)));
+ return moduleSet;
}
}
@@ -109,11 +107,11 @@
} else if (responseEntity.getStatusCode() == HttpStatus.NOT_FOUND) {
log.error("SDNC did not return a module resource for the given cmHandle {}", cmHandle);
throw new ModuleResourceNotFoundException(cmHandle,
- "SDNC did not return a module resource for the given cmHandle.");
+ "SDNC did not return a module resource for the given cmHandle.");
} else {
log.error("Error occurred when getting module resources from SDNC for the given cmHandle {}", cmHandle);
throw new DmiException(cmHandle,
- RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
+ RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
}
}
return yangResources;
@@ -136,7 +134,7 @@
} catch (final JsonProcessingException e) {
log.error("Parsing error occurred while converting cm-handles to JSON {}", cmHandles);
throw new DmiException("Internal Server Error.",
- "Parsing error occurred while converting given cm-handles object list to JSON ");
+ "Parsing error occurred while converting given cm-handles object list to JSON ");
}
final ResponseEntity<String> responseEntity = ncmpRestClient.registerCmHandlesWithNcmp(cmHandlesJson);
if ((responseEntity.getStatusCode() != HttpStatus.CREATED)) {
@@ -144,76 +142,54 @@
}
}
- private ModuleSet createModuleSchema(final String responseBody) {
- final var moduleSchemas = convertModulesToNodeSchema(responseBody);
- final List<ModuleSetSchemas> moduleSetSchemas = new ArrayList<>();
- for (final ModuleSchemaProperties schemaProperties : moduleSchemas.getSchemas().getSchema()) {
- moduleSetSchemas.add(convertModulesToModuleSchemas(schemaProperties));
- }
- final var moduleSet = new ModuleSet();
- moduleSet.setSchemas(moduleSetSchemas);
- return moduleSet;
- }
-
- private ModuleSetSchemas convertModulesToModuleSchemas(final ModuleSchemaProperties moduleSchemaProperties) {
+ private ModuleSetSchemas toModuleSetSchemas(final ModuleSchema moduleSchema) {
final var moduleSetSchemas = new ModuleSetSchemas();
- moduleSetSchemas.setModuleName(moduleSchemaProperties.getIdentifier());
- moduleSetSchemas.setNamespace(moduleSchemaProperties.getNamespace());
- moduleSetSchemas.setRevision(moduleSchemaProperties.getVersion());
+ moduleSetSchemas.setModuleName(moduleSchema.getIdentifier());
+ moduleSetSchemas.setNamespace(moduleSchema.getNamespace());
+ moduleSetSchemas.setRevision(moduleSchema.getVersion());
return moduleSetSchemas;
}
- private ModuleSchemas convertModulesToNodeSchema(final String modulesListAsJson) {
- try {
- return objectMapper.readValue(modulesListAsJson, ModuleSchemas.class);
- } catch (final JsonProcessingException e) {
- log.error("JSON exception occurred when converting the following modules to node schema "
- + "{}", modulesListAsJson);
- throw new DmiException("Unable to process JSON.",
- "JSON exception occurred when mapping modules.", e);
- }
- }
-
@Override
public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle,
- final @NotNull String resourceIdentifier,
- final String acceptParamInHeader,
- final String optionsParamInQuery,
- final Map<String, String> cmHandlePropertyMap) {
+ final @NotNull String resourceIdentifier,
+ final String acceptParamInHeader,
+ final String optionsParamInQuery,
+ final Map<String, String> cmHandlePropertyMap) {
// not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this.
final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperationalAndRunning(cmHandle,
- resourceIdentifier,
- optionsParamInQuery,
- acceptParamInHeader,
- RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM);
+ resourceIdentifier,
+ optionsParamInQuery,
+ acceptParamInHeader,
+ RESTCONF_CONTENT_PASSTHROUGH_OPERATIONAL_QUERY_PARAM);
return prepareAndSendResponse(responseEntity, cmHandle);
}
@Override
public Object getResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle,
- final @NotNull String resourceIdentifier,
- final String acceptParamInHeader,
- final String optionsParamInQuery,
- final Map<String, String> cmHandlePropertyMap) {
+ final @NotNull String resourceIdentifier,
+ final String acceptParamInHeader,
+ final String optionsParamInQuery,
+ final Map<String, String> cmHandlePropertyMap) {
// not using cmHandlePropertyMap of onap dmi impl , other dmi impl might use this.
final ResponseEntity<String> responseEntity = sdncOperations.getResouceDataForOperationalAndRunning(cmHandle,
- resourceIdentifier,
- optionsParamInQuery,
- acceptParamInHeader,
- REST_CONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM);
+ resourceIdentifier,
+ optionsParamInQuery,
+ acceptParamInHeader,
+ REST_CONF_CONTENT_PASSTHROUGH_RUNNING_QUERY_PARAM);
return prepareAndSendResponse(responseEntity, cmHandle);
}
@Override
public String writeResourceDataPassthroughForCmHandle(final String cmHandle, final String resourceIdentifier,
- final String dataType, final String data) {
+ final String dataType, final String data) {
final ResponseEntity<String> responseEntity =
- sdncOperations.writeResourceDataPassthroughRunning(cmHandle, resourceIdentifier, dataType, data);
+ sdncOperations.writeResourceDataPassthroughRunning(cmHandle, resourceIdentifier, dataType, data);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
return responseEntity.getBody();
} else {
throw new DmiException(cmHandle,
- RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
+ RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
}
}
@@ -222,7 +198,7 @@
return responseEntity.getBody();
} else {
throw new ResourceDataNotFound(cmHandle,
- RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
+ RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody());
}
}
@@ -236,15 +212,15 @@
moduleRequest = writer.writeValueAsString(ietfNetconfModuleReferences);
} catch (final JsonProcessingException e) {
log.error("JSON exception occurred when creating the module request for the given module reference {}",
- moduleReference.getName());
+ moduleReference.getName());
throw new DmiException("Unable to process JSON.",
- "JSON exception occurred when creating the module request.", e);
+ "JSON exception occurred when creating the module request.", e);
}
return moduleRequest;
}
private YangResource toYangResource(final ModuleReference moduleReference,
- final ResponseEntity<String> response) {
+ final ResponseEntity<String> response) {
final YangResource yangResource = new YangResource();
yangResource.setModuleName(moduleReference.getName());
yangResource.setRevision(moduleReference.getRevision());
@@ -255,13 +231,13 @@
private String extractYangSourceFromBody(final ResponseEntity<String> responseEntity) {
final var responseBodyAsJsonObject = new Gson().fromJson(responseEntity.getBody(), JsonObject.class);
if (responseBodyAsJsonObject.getAsJsonObject(IETF_NETCONF_MONITORING_OUTPUT) == null
- || responseBodyAsJsonObject.getAsJsonObject(IETF_NETCONF_MONITORING_OUTPUT)
- .getAsJsonPrimitive("data") == null) {
+ || responseBodyAsJsonObject.getAsJsonObject(IETF_NETCONF_MONITORING_OUTPUT)
+ .getAsJsonPrimitive("data") == null) {
log.error("Error occurred when trying to parse the response body from sdnc {}", responseEntity.getBody());
throw new ModuleResourceNotFoundException(responseEntity.getBody(),
- "Error occurred when trying to parse the response body from sdnc.");
+ "Error occurred when trying to parse the response body from sdnc.");
}
return responseBodyAsJsonObject.getAsJsonObject(IETF_NETCONF_MONITORING_OUTPUT).getAsJsonPrimitive("data")
- .toString();
+ .toString();
}
}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaProperties.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java
similarity index 89%
rename from src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaProperties.java
rename to src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java
index 6de7d13..c77e0e4 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaProperties.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchema.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,15 +22,10 @@
package org.onap.cps.ncmp.dmi.service.model;
import java.util.List;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
-/**
- * ModuleSchemaProperties.
- */
-@Getter
-@Setter
-public class ModuleSchemaProperties {
+@Data
+public class ModuleSchema {
private String identifier;
private String version;
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaList.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaList.java
deleted file mode 100644
index a4af176..0000000
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemaList.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
- * ================================================================================
- * 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.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.dmi.service.model;
-
-import java.util.List;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * ModuleSchemaList.
- */
-@Getter
-@Setter
-public class ModuleSchemaList {
-
- private List<ModuleSchemaProperties> schema;
-
-}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemas.java b/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemas.java
deleted file mode 100644
index a7b2430..0000000
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/model/ModuleSchemas.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
- * ================================================================================
- * 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.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.dmi.service.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * ModuleSchemas.
- */
-@Getter
-@Setter
-public class ModuleSchemas {
-
- @JsonProperty("ietf-netconf-monitoring:schemas")
- private ModuleSchemaList schemas;
-}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
index bdbc3b3..43e2a5e 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,13 +21,24 @@
package org.onap.cps.ncmp.dmi.service.operation;
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.JsonPathException;
+import com.jayway.jsonpath.TypeRef;
+import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
+import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.apache.groovy.parser.antlr4.util.StringUtils;
import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties;
+import org.onap.cps.ncmp.dmi.exception.SdncException;
import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient;
+import org.onap.cps.ncmp.dmi.service.model.ModuleSchema;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
@@ -41,12 +53,18 @@
private static final String MOUNT_URL_TEMPLATE = "/node={nodeId}/yang-ext:mount";
private static final String GET_SCHEMA_URL = "/ietf-netconf-monitoring:netconf-state/schemas";
private static final String GET_SCHEMA_SOURCES_URL = "/ietf-netconf-monitoring:get-schema";
+ private static final String PATH_TO_MODULE_SCHEMAS = "$.ietf-netconf-monitoring:schemas.schema";
private SdncProperties sdncProperties;
private SdncRestconfClient sdncRestconfClient;
private final String topologyUrlData;
private final String topologyUrlOperational;
+ private Configuration jsonPathConfiguration = Configuration.builder()
+ .mappingProvider(new JacksonMappingProvider())
+ .jsonProvider(new JacksonJsonProvider())
+ .build();
+
/**
* Constructor for {@code SdncOperations}. This method also manipulates url properties.
*
@@ -65,11 +83,20 @@
* This method fetches list of modules usind sdnc client.
*
* @param nodeId node id for node
- * @return returns {@code ResponseEntity} which contains list of modules
+ * @return a collection of module schemas
*/
- public ResponseEntity<String> getModulesFromNode(final String nodeId) {
+ public Collection<ModuleSchema> getModuleSchemasFromNode(final String nodeId) {
final String urlWithNodeId = prepareGetSchemaUrl(nodeId);
- return sdncRestconfClient.getOperation(urlWithNodeId);
+ final ResponseEntity<String> modulesResponseEntity = sdncRestconfClient.getOperation(urlWithNodeId);
+ if (modulesResponseEntity.getStatusCode() == HttpStatus.OK) {
+ final String modulesResponseBody = modulesResponseEntity.getBody();
+ return (StringUtils.isEmpty(modulesResponseBody)) ? Collections.emptyList()
+ : convertToModuleSchemas(modulesResponseBody);
+ } else {
+ throw new SdncException(
+ String.format("SDNC failed to get Modules Schema for node %s", nodeId),
+ modulesResponseEntity.getStatusCode(), modulesResponseEntity.getBody());
+ }
}
/**
@@ -90,10 +117,10 @@
/**
* This method fetches the resource data for given node identifier on given resource using sdnc client.
*
- * @param nodeId network resource identifier
- * @param resourceId resource identifier
- * @param optionsParamInQuery fields query
- * @param acceptParamInHeader accept parameter
+ * @param nodeId network resource identifier
+ * @param resourceId resource identifier
+ * @param optionsParamInQuery fields query
+ * @param acceptParamInHeader accept parameter
* @param restconfContentQueryParam restconf content query param
* @return {@code ResponseEntity} response entity
*/
@@ -194,4 +221,16 @@
final String topologyMountUrl = topologyUrlData + MOUNT_URL_TEMPLATE;
return topologyMountUrl.replace("{nodeId}", nodeId);
}
+
+ private List<ModuleSchema> convertToModuleSchemas(final String modulesListAsJson) {
+ try {
+ return JsonPath.using(jsonPathConfiguration).parse(modulesListAsJson).read(
+ PATH_TO_MODULE_SCHEMAS, new TypeRef<>() {
+ });
+ } catch (final JsonPathException jsonPathException) {
+ throw new SdncException("SDNC Response processing failed",
+ "SDNC response is not in the expected format.", jsonPathException);
+ }
+ }
+
}
\ No newline at end of file
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/model/ModuleSchemaPropertiesSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/model/ModuleSchemaPropertiesSpec.groovy
deleted file mode 100644
index 51dddc7..0000000
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/model/ModuleSchemaPropertiesSpec.groovy
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
- * ================================================================================
- * 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.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.dmi.model
-
-import org.onap.cps.ncmp.dmi.service.model.ModuleSchemaProperties
-import spock.lang.Specification
-
-class ModuleSchemaPropertiesSpec extends Specification {
- def objectUnderTest = new ModuleSchemaProperties(identifier:'some id',
- version:'some version',
- format:'some format',
- namespace:'some namespace',
- location: ['some','locations'])
-
- def 'Reading all properties.'() {
- expect: 'all properties return the expected values'
- objectUnderTest.identifier == 'some id'
- objectUnderTest.version == 'some version'
- objectUnderTest.format == 'some format'
- objectUnderTest.namespace == 'some namespace'
- objectUnderTest.location == ['some','locations']
- }
-}
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
index ac78928..1446a5a 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +27,6 @@
import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException
import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException
import org.onap.cps.ncmp.dmi.service.model.ModuleReference
-import org.onap.cps.ncmp.dmi.service.model.ModuleSchemaList
import org.onap.cps.ncmp.dmi.model.ModuleSet
import org.onap.cps.ncmp.dmi.model.ModuleSetSchemas
import org.onap.cps.ncmp.dmi.model.YangResource
@@ -35,26 +35,25 @@
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
+import org.springframework.context.annotation.Import
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
+import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.web.servlet.MockMvc
import spock.lang.Specification
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
-@WebMvcTest
-@AutoConfigureMockMvc(addFilters = false)
+@WebMvcTest(DmiRestController)
+@WithMockUser
+@Import(ObjectMapper)
class DmiRestControllerSpec extends Specification {
@SpringBean
DmiService mockDmiService = Mock()
- @SpringBean
- ObjectMapper mockObjectMapper = Spy()
-
@Autowired
private MockMvc mvc
@@ -83,20 +82,6 @@
response.getContentAsString() == '{"schemas":[{"moduleName":"some-moduleName","revision":"some-revision","namespace":"some-namespace"}]}'
}
- def 'Get all modules for given cm handle with invalid json.'() {
- given: 'REST endpoint for getting all modules'
- def getModuleUrl = "$basePathV1/ch/node1/modules"
- and: 'get modules for cmHandle throws an exception'
- mockObjectMapper.readValue(_ as String, _ as ModuleSchemaList) >> { throw Mock(DmiException.class) }
- mockDmiService.getModulesForCmHandle('node1') >> 'some-value'
- when: 'post is being called'
- def response = mvc.perform(post(getModuleUrl)
- .contentType(MediaType.APPLICATION_JSON))
- .andReturn().response
- then: 'the status is as expected'
- response.status == HttpStatus.INTERNAL_SERVER_ERROR.value()
- }
-
def 'Get all modules for given cm handle with exception handling of #scenario.'() {
given: 'REST endpoint for getting all modules'
def getModuleUrl = "$basePathV1/ch/node1/modules"
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
index 9325d59..d535375 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +24,6 @@
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ObjectWriter
-import org.onap.cps.ncmp.dmi.TestUtils
import org.onap.cps.ncmp.dmi.config.DmiPluginConfig
import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException
import org.onap.cps.ncmp.dmi.exception.DmiException
@@ -34,6 +34,7 @@
import org.onap.cps.ncmp.dmi.model.YangResource
import org.onap.cps.ncmp.dmi.model.YangResources
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient
+import org.onap.cps.ncmp.dmi.service.model.ModuleSchema
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
@@ -49,50 +50,35 @@
def mockSdncOperations = Mock(SdncOperations)
def objectUnderTest = new DmiServiceImpl(mockDmiPluginProperties, mockNcmpRestClient, mockSdncOperations, spyObjectMapper)
- def 'Call get modules for cm-handle on dmi Service.'() {
- given: 'cm handle id'
+ def ' Get modules for a cm-handle.'() {
+ given: 'a cm handle'
def cmHandle = 'node1'
- and: 'request operation returns OK'
- def body = TestUtils.getResourceFileContent('ModuleSchema.json')
- mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>(body, HttpStatus.OK)
+ and: 'sdnc operations returns one module schema for the cmhandle'
+ def moduleSchema = new ModuleSchema(
+ identifier: "example-identifier",
+ namespace: "example:namespace",
+ version: "example-version")
+ mockSdncOperations.getModuleSchemasFromNode(cmHandle) >> List.of(moduleSchema)
when: 'get modules for cm-handle is called'
def result = objectUnderTest.getModulesForCmHandle(cmHandle)
- then: 'result is equal to the response from the SDNC service'
- result.toString().contains('moduleName: example-identifier')
- result.toString().contains('revision: example-version')
+ then: 'one module is returned'
+ result.schemas.size() == 1
+ and: 'module has expected values'
+ with(result.schemas[0]) {
+ it.getRevision() == moduleSchema.getVersion()
+ it.getModuleName() == moduleSchema.getIdentifier()
+ it.getNamespace() == moduleSchema.getNamespace();
+ }
}
- def 'Call get modules for cm-handle with invalid json.'() {
+ def 'no modules found for the cmhandle.'() {
given: 'cm handle id'
def cmHandle = 'node1'
- and: 'request operation returns invalid json'
- def body = TestUtils.getResourceFileContent('ModuleSchema.json')
- mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>('invalid json', HttpStatus.OK)
- when: 'get modules for cm-handle is called'
- def result = objectUnderTest.getModulesForCmHandle(cmHandle)
- then: 'a dmi exception is thrown'
- thrown(DmiException)
- }
-
- def 'Call get modules for cm-handle and SDNC returns "bad request" status.'() {
- given: 'cm handle id'
- def cmHandle = 'node1'
- and: 'get modules from node returns "bad request" status'
- mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>('body', HttpStatus.BAD_REQUEST)
+ and: 'sdnc operations returns no modules'
+ mockSdncOperations.getModuleSchemasFromNode(cmHandle) >> Collections.emptyList();
when: 'get modules for cm-handle is called'
objectUnderTest.getModulesForCmHandle(cmHandle)
- then: 'dmi exception is thrown'
- thrown(DmiException)
- }
-
- def 'Call get modules for cm-handle and SDNC returns OK with empty body.'() {
- given: 'cm handle id'
- def cmHandle = 'node1'
- and: 'get modules for cm-handle returns OK with empty body'
- mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>('', HttpStatus.OK)
- when: 'get modules for cm-handle is called'
- objectUnderTest.getModulesForCmHandle(cmHandle)
- then: 'ModulesNotFoundException is thrown'
+ then: 'module not found exception is thrown'
thrown(ModulesNotFoundException)
}
@@ -140,14 +126,14 @@
def 'Get multiple module resources.'() {
given: 'a cmHandle and module reference list'
def cmHandle = 'some-cmHandle'
- def moduleReference1 = new ModuleReference(name: 'name-1',revision: 'revision-1')
- def moduleReference2 = new ModuleReference(name: 'name-2',revision: 'revision-2')
+ def moduleReference1 = new ModuleReference(name: 'name-1', revision: 'revision-1')
+ def moduleReference2 = new ModuleReference(name: 'name-2', revision: 'revision-2')
def moduleList = [moduleReference1, moduleReference2]
when: 'get module resources is invoked with the given cm handle and a module list'
def result = objectUnderTest.getModuleResources(cmHandle, moduleList)
then: 'get modules resources is called twice'
2 * mockSdncOperations.getModuleResource(cmHandle, _) >>> [new ResponseEntity<String>('{"ietf-netconf-monitoring:output": {"data": "some-data1"}}', HttpStatus.OK),
- new ResponseEntity<String>('{"ietf-netconf-monitoring:output": {"data": "some-data2"}}', HttpStatus.OK)]
+ new ResponseEntity<String>('{"ietf-netconf-monitoring:output": {"data": "some-data2"}}', HttpStatus.OK)]
and: 'the result is a yang resources object with the expected names, revisions and yang-sources'
def yangResources = new YangResources()
def yangResource1 = new YangResource(yangSource: '"some-data1"', moduleName: 'name-1', revision: 'revision-1')
@@ -160,7 +146,7 @@
def 'Get a module resource with module resource not found exception for #scenario.'() {
given: 'a cmHandle and module reference list'
def cmHandle = 'some-cmHandle'
- def moduleReference = new ModuleReference(name: 'NAME',revision: 'REVISION')
+ def moduleReference = new ModuleReference(name: 'NAME', revision: 'REVISION')
def moduleList = [moduleReference]
when: 'get module resources is invoked with the given cm handle and a module list'
objectUnderTest.getModuleResources(cmHandle, moduleList)
@@ -216,8 +202,8 @@
mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam, acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
when: 'get resource data from cm handles service method invoked'
def response = objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
- resourceId, acceptHeaderParam,
- optionsParam, null)
+ resourceId, acceptHeaderParam,
+ optionsParam, null)
then: 'response have expected json'
response == 'response json'
}
@@ -232,8 +218,8 @@
mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam, acceptHeaderParam, _ as String) >> new ResponseEntity<>(HttpStatus.NOT_FOUND)
when: 'get resource data from cm handles service method invoked'
objectUnderTest.getResourceDataOperationalForCmHandle(cmHandle,
- resourceId, acceptHeaderParam,
- optionsParam, null)
+ resourceId, acceptHeaderParam,
+ optionsParam, null)
then: 'resource data not found'
thrown(ResourceDataNotFound.class)
}
@@ -247,11 +233,11 @@
def contentQuery = 'content=config'
and: 'sdnc operation returns OK response'
mockSdncOperations.getResouceDataForOperationalAndRunning(cmHandle, resourceId, optionsParam,
- acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
+ acceptHeaderParam, contentQuery) >> new ResponseEntity<>('response json', HttpStatus.OK)
when: 'get resource data from cm handles service method invoked'
def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceId, acceptHeaderParam,
- optionsParam, null)
+ resourceId, acceptHeaderParam,
+ optionsParam, null)
then: 'response have expected json'
response == 'response json'
}
@@ -261,7 +247,7 @@
mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> new ResponseEntity<String>('response json', httpResponse)
when: 'write resource data for cm handle method invoked'
def response = objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
- 'some-resourceIdentifier', 'some-dataType', '{some-data}')
+ 'some-resourceIdentifier', 'some-dataType', '{some-data}')
then: 'the response contains the expected json data from sdnc'
response == 'response json'
where: 'the following values are used'
@@ -273,10 +259,10 @@
def 'Write resource data using for passthrough running for the given cm handle with #scenario.'() {
given: 'sdnc returns a created response'
mockSdncOperations.writeResourceDataPassthroughRunning('some-cmHandle',
- 'some-resourceIdentifier', 'some-dataType', requestBody) >> new ResponseEntity<String>('response json', HttpStatus.CREATED)
+ 'some-resourceIdentifier', 'some-dataType', requestBody) >> new ResponseEntity<String>('response json', HttpStatus.CREATED)
when: 'write resource data from cm handles service method invoked'
def response = objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
- 'some-resourceIdentifier', 'some-dataType', requestBody)
+ 'some-resourceIdentifier', 'some-dataType', requestBody)
then: 'response have expected json'
response == 'response json'
where: 'given request body'
@@ -290,7 +276,7 @@
mockSdncOperations.writeResourceDataPassthroughRunning(_, _, _, _) >> new ResponseEntity<String>('response json', HttpStatus.INTERNAL_SERVER_ERROR)
when: 'write resource data for pass through method is invoked'
objectUnderTest.writeResourceDataPassthroughForCmHandle('some-cmHandle',
- 'some-resourceIdentifier', 'some-dataType', _ as String)
+ 'some-resourceIdentifier', 'some-dataType', _ as String)
then: 'a dmi exception is thrown'
thrown(DmiException.class)
}
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
index 4411971..2ce870a 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/operation/SdncOperationsSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,12 +21,16 @@
package org.onap.cps.ncmp.dmi.service.operation
+import org.onap.cps.ncmp.dmi.TestUtils
import org.onap.cps.ncmp.dmi.config.DmiConfiguration
+import org.onap.cps.ncmp.dmi.exception.SdncException
import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpHeaders
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
@@ -39,14 +44,59 @@
@Autowired
SdncOperations objectUnderTest
- def 'call get modules from node to SDNC.'() {
+ def 'get modules from node.'() {
given: 'node id and url'
def nodeId = 'node1'
def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas'
- when: 'called get modules from node'
- objectUnderTest.getModulesFromNode(nodeId)
- then: 'the get operation is executed with the correct URL'
- 1 * mockSdncRestClient.getOperation(expectedUrl)
+ and: 'sdnc returns one module in response'
+ mockSdncRestClient.getOperation(expectedUrl) >>
+ ResponseEntity.ok(TestUtils.getResourceFileContent('ModuleSchema.json'))
+ when: 'get modules from node is called'
+ def moduleSchemas = objectUnderTest.getModuleSchemasFromNode(nodeId)
+ then: 'one module is found'
+ moduleSchemas.size() == 1
+ and: 'module schema has expected values'
+ with(moduleSchemas[0]) {
+ it.getIdentifier() == "example-identifier"
+ it.getNamespace() == "example:namespace"
+ it.getVersion() == "example-version"
+ it.getFormat() == "example-format"
+ it.getLocation() == ["example-location"]
+ }
+ }
+
+ def 'No modules from Node: SDNC Response - #scenario .'() {
+ given: 'node id and url'
+ def nodeId = 'node1'
+ def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas'
+ and: 'sdnc operation returns #scenario'
+ mockSdncRestClient.getOperation(expectedUrl) >> ResponseEntity.ok(responseBody)
+ when: 'modules from node is called'
+ def moduleSchemas = objectUnderTest.getModuleSchemasFromNode(nodeId)
+ then: 'no modules are returned'
+ moduleSchemas.size() == 0
+ where:
+ scenario | responseBody
+ 'empty response body ' | ''
+ 'no module schema' | '{ "ietf-netconf-monitoring:schemas" : { "schema" : [] } } '
+ }
+
+ def 'Error handling - modules from node: #scenario'() {
+ given: 'node id and url'
+ def nodeId = 'node1'
+ def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/ietf-netconf-monitoring:netconf-state/schemas'
+ and: 'sdnc operation returns configured response'
+ mockSdncRestClient.getOperation(expectedUrl) >> new ResponseEntity<>(sdncResponseBody, sdncHttpStatus)
+ when: 'modules for node are fetched'
+ objectUnderTest.getModuleSchemasFromNode(nodeId)
+ then: 'SDNCException is thrown'
+ def thrownException = thrown(SdncException)
+ thrownException.getDetails().contains(expectedExceptionDetails)
+ where:
+ scenario | sdncHttpStatus | sdncResponseBody || expectedExceptionDetails
+ 'failed response from SDNC' | HttpStatus.BAD_REQUEST | '{ "errorMessage" : "incorrect input"}' || '{ "errorMessage" : "incorrect input"}'
+ 'invalid json response' | HttpStatus.OK | 'invalid-json' || 'SDNC response is not in the expected format'
+ 'response in unexpected json schema' | HttpStatus.OK | '{ "format" : "incorrect" }' || 'SDNC response is not in the expected format'
}
def 'Get module resources from SDNC.'() {
@@ -64,7 +114,7 @@
def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/testResourceId?a=1&b=2&content=testContent'
when: 'called get modules from node'
objectUnderTest.getResouceDataForOperationalAndRunning('node1', 'testResourceId',
- '(a=1,b=2)', 'testAcceptParam', 'content=testContent')
+ '(a=1,b=2)', 'testAcceptParam', 'content=testContent')
then: 'the get operation is executed with the correct URL'
1 * mockSdncRestClient.getOperation(expectedUrl, _ as HttpHeaders)
}
@@ -73,30 +123,30 @@
given: 'expected url, topology-id, sdncOperation object'
def expectedUrl = '/rests/data/network-topology:network-topology/topology=test-topology/node=node1/yang-ext:mount/testResourceId'
when: 'write resource data for pass through running is called'
- objectUnderTest.writeResourceDataPassthroughRunning('node1','testResourceId','application/json','requestData')
+ objectUnderTest.writeResourceDataPassthroughRunning('node1', 'testResourceId', 'application/json', 'requestData')
then: 'the post operation is executed with the correct URL and data'
1 * mockSdncRestClient.postOperationWithJsonData(expectedUrl, 'requestData', _ as HttpHeaders)
}
def 'build query param list for SDNC where options contains a #scenario'() {
when: 'build query param list is called with #scenario'
- def result = objectUnderTest.buildQueryParamList(optionsParamInQuery,'d=4')
+ def result = objectUnderTest.buildQueryParamList(optionsParamInQuery, 'd=4')
then: 'result equals to expected result'
result == expectedResult
where: 'following parameters are used'
- scenario | optionsParamInQuery || expectedResult
- 'single key-value pair' | '(a=x)' || ['a=x','d=4']
- 'multiple key-value pairs'| '(a=x,b=y,c=z)' || ['a=x','b=y','c=z','d=4']
- '/ as special char' | '(a=x,b=y,c=t/z)' || ['a=x','b=y','c=t/z','d=4']
- '" as special char' | '(a=x,b=y,c="z")' || ['a=x','b=y','c="z"','d=4']
- '[] as special char' | '(a=x,b=y,c=[z])' || ['a=x','b=y','c=[z]','d=4']
- '= in value' | '(a=(x=y),b=x=y)' || ['a=(x=y)','b=x=y','d=4']
+ scenario | optionsParamInQuery || expectedResult
+ 'single key-value pair' | '(a=x)' || ['a=x', 'd=4']
+ 'multiple key-value pairs' | '(a=x,b=y,c=z)' || ['a=x', 'b=y', 'c=z', 'd=4']
+ '/ as special char' | '(a=x,b=y,c=t/z)' || ['a=x', 'b=y', 'c=t/z', 'd=4']
+ '" as special char' | '(a=x,b=y,c="z")' || ['a=x', 'b=y', 'c="z"', 'd=4']
+ '[] as special char' | '(a=x,b=y,c=[z])' || ['a=x', 'b=y', 'c=[z]', 'd=4']
+ '= in value' | '(a=(x=y),b=x=y)' || ['a=(x=y)', 'b=x=y', 'd=4']
}
def 'options parameters contains a comma #scenario'() {
// https://jira.onap.org/browse/CPS-719
when: 'build query param list is called with #scenario'
- def result = objectUnderTest.buildQueryParamList(optionsParamInQuery,'d=4')
+ def result = objectUnderTest.buildQueryParamList(optionsParamInQuery, 'd=4')
then: 'expect 2 elements from options +1 from content query param (2+1) = 3 elements'
def expectedNoOfElements = 3
and: 'results contains more elements than expected'