diff options
author | tragait <rahul.tyagi@est.tech> | 2021-08-20 15:45:58 +0100 |
---|---|---|
committer | tragait <rahul.tyagi@est.tech> | 2021-08-26 12:50:30 +0100 |
commit | c584bf2729bb6eb9229aad9dbacc65beaa5dbc2f (patch) | |
tree | 9a44c8563dc73db1a620de7053cb1eace58fefae /cps-ncmp-service/src | |
parent | 673c6d94830a1677e685cab82a76747a0808d347 (diff) |
Post impl for passthrough running (Ncmp impl.)
Issue-ID: CPS-577
Signed-off-by: tragait <rahul.tyagi@est.tech>
Change-Id: Ic8983349cf88fb123feb95ce01ec6fdf670469f4
Diffstat (limited to 'cps-ncmp-service/src')
8 files changed, 359 insertions, 230 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java index 3e715e5e75..03d70c18f6 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java @@ -130,14 +130,28 @@ public interface NetworkCmProxyDataService { * * @param cmHandle cm handle * @param resourceIdentifier resource identifier - * @param accept accept param + * @param acceptParam accept param * @param fields fields query * @param depth depth query * @return {@code Object} resource data */ Object getResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle, @NotNull String resourceIdentifier, - String accept, + String acceptParam, String fields, Integer depth); + + /** + * Create resource data for data store pass-through running + * using dmi for given cm-handle. + * + * @param cmHandle cm handle + * @param resourceIdentifier resource identifier + * @param requestBody request body to create resource + * @param contentType content type in body + */ + void createResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle, + @NotNull String resourceIdentifier, + @NotNull Object requestBody, + String contentType); } 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 b5a591401a..11477abe0d 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 @@ -53,7 +53,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; - @Slf4j @Service public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService { @@ -66,6 +65,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private static final OffsetDateTime NO_TIMESTAMP = null; + private static final String NCMP_DMI_SERVICE_NAME = "dmi-service-name"; + private CpsDataService cpsDataService; private ObjectMapper objectMapper; @@ -76,14 +77,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService /** * Constructor Injection for Dependencies. - * - * @param dmiOperations dmi operation - * @param cpsDataService Data Service Interface + * @param dmiOperations DMI operation + * @param cpsDataService Data Service Interface * @param cpsQueryService Query Service Interface - * @param objectMapper Object Mapper + * @param objectMapper Object Mapper */ public NetworkCmProxyDataServiceImpl(final DmiOperations dmiOperations, final CpsDataService cpsDataService, - final CpsQueryService cpsQueryService, final ObjectMapper objectMapper) { + final CpsQueryService cpsQueryService, final ObjectMapper objectMapper) { this.dmiOperations = dmiOperations; this.cpsDataService = cpsDataService; this.cpsQueryService = cpsQueryService; @@ -96,13 +96,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService @Override public DataNode getDataNode(final String cmHandle, final String xpath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { return cpsDataService.getDataNode(getDataspaceName(), cmHandle, xpath, fetchDescendantsOption); } @Override public Collection<DataNode> queryDataNodes(final String cmHandle, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { return cpsQueryService.queryDataNodes(getDataspaceName(), cmHandle, cpsPath, fetchDescendantsOption); } @@ -143,149 +143,132 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } } - private void parseAndCreateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { - try { - final List<PersistenceCmHandle> createdPersistenceCmHandles = - new LinkedList<>(); - for (final CmHandle cmHandle : dmiPluginRegistration.getCreatedCmHandles()) { - createdPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration, cmHandle)); - } - final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList(); - persistenceCmHandlesList.setCmHandles(createdPersistenceCmHandles); - final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); - cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry", - cmHandleJsonData, NO_TIMESTAMP); - } catch (final JsonProcessingException e) { - log.error("Parsing error occurred while converting Object to JSON for Dmi Registry."); - throw new DataValidationException( - "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e - .getMessage(), e); - } - } - - private void parseAndUpdateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { - try { - final List<PersistenceCmHandle> updatedPersistenceCmHandles = - new LinkedList<>(); - for (final CmHandle cmHandle : dmiPluginRegistration.getUpdatedCmHandles()) { - updatedPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration, cmHandle)); - } - final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList(); - persistenceCmHandlesList.setCmHandles(updatedPersistenceCmHandles); - final String cmHandlesJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); - cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP); - } catch (final JsonProcessingException e) { - log.error("Parsing error occurred while converting Object to JSON Dmi Registry."); - throw new DataValidationException( - "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e - .getMessage(), e); - } - } - - private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { - for (final String cmHandle: dmiPluginRegistration.getRemovedCmHandles()) { - try { - cpsDataService.deleteListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP); - } catch (final DataNodeNotFoundException e) { - log.warn("Datanode {} not deleted message {}", cmHandle, e.getMessage()); - } - } - } - @Override public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle, - final @NotNull String resourceIdentifier, - final String acceptParam, - final String fieldsQueryParam, - final Integer depthQueryParam) { - - final var dataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle); - final var dmiServiceName = String.valueOf(dataNode.getLeaves().get("dmi-service-name")); - final Collection<DataNode> additionalPropsList = dataNode.getChildDataNodes(); - final var jsonBody = prepareOperationBody(GenericRequestBody.OperationEnum.READ, additionalPropsList); - final ResponseEntity<Object> response = dmiOperations.getResouceDataOperationalFromDmi(dmiServiceName, - cmHandle, - resourceIdentifier, - fieldsQueryParam, - depthQueryParam, - acceptParam, - jsonBody); + final @NotNull String resourceIdentifier, + final String acceptParam, + final String fieldsQueryParam, + final Integer depthQueryParam) { + + final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle); + final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME)); + final String dmiRequestBody = getGenericRequestBody(cmHandleDataNode); + final ResponseEntity<Object> response = dmiOperations.getResourceDataOperationalFromDmi(dmiServiceName, + cmHandle, + resourceIdentifier, + fieldsQueryParam, + depthQueryParam, + acceptParam, + dmiRequestBody); return handleResponse(response); } @Override public Object getResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle, - final @NotNull String resourceIdentifier, - final String accept, - final String fields, - final Integer depth) { + final @NotNull String resourceIdentifier, + final String acceptParam, + final String fields, + final Integer depth) { final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle); - final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get("dmi-service-name")); - final Collection<DataNode> additionalPropsList = cmHandleDataNode.getChildDataNodes(); - final var dmiRequesBody = prepareOperationBody(GenericRequestBody.OperationEnum.READ, additionalPropsList); - final ResponseEntity<Object> response = dmiOperations.getResouceDataPassThroughRunningFromDmi(dmiServiceName, - cmHandle, - resourceIdentifier, - fields, - depth, - accept, - dmiRequesBody); + final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME)); + final String dmiRequestBody = getGenericRequestBody(cmHandleDataNode); + final ResponseEntity<Object> response = dmiOperations.getResourceDataPassThroughRunningFromDmi(dmiServiceName, + cmHandle, + resourceIdentifier, + fields, + depth, + acceptParam, + dmiRequestBody); return handleResponse(response); } + @Override + public void createResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle, + final @NotNull String resourceIdentifier, + final @NotNull Object requestBody, + final String contentType) { + final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle); + final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME)); + final Collection<DataNode> cmHandlePropertiesList = cmHandleDataNode.getChildDataNodes(); + final Map<String, String> cmHandlePropertiesMap = getCmHandlePropertiesAsMap(cmHandlePropertiesList); + final var dmiRequestBodyObject = GenericRequestBody.builder() + .operation(GenericRequestBody.OperationEnum.CREATE) + .dataType(contentType) + .data(requestBody) + .cmHandleProperties(cmHandlePropertiesMap) + .build(); + final var dmiRequestBody = prepareOperationBody(dmiRequestBodyObject); + final ResponseEntity<Void> responseEntity = dmiOperations + .createResourceDataPassThroughRunningFromDmi(dmiServiceName, + cmHandle, + resourceIdentifier, + dmiRequestBody); + handleResponseForPost(responseEntity); + } + private DataNode fetchDataNodeFromDmiRegistryForCmHandle(final String cmHandle) { final String xpathForDmiRegistryToFetchCmHandle = "/dmi-registry/cm-handles[@id='" + cmHandle + "']"; final var dataNode = cpsDataService.getDataNode(NCMP_DATASPACE_NAME, - NCMP_DMI_REGISTRY_ANCHOR, - xpathForDmiRegistryToFetchCmHandle, - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + NCMP_DMI_REGISTRY_ANCHOR, + xpathForDmiRegistryToFetchCmHandle, + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); return dataNode; } - private String prepareOperationBody(final GenericRequestBody.OperationEnum operation, - final Collection<DataNode> additionalPropertyList) { - final var requestBody = new GenericRequestBody(); - final Map<String, String> additionalPropertyMap = getAdditionalPropertiesMap(additionalPropertyList); - requestBody.setOperation(GenericRequestBody.OperationEnum.READ); - requestBody.setCmHandleProperties(additionalPropertyMap); + private String prepareOperationBody(final GenericRequestBody requestBodyObject) { try { - final var requestJson = objectMapper.writeValueAsString(requestBody); - return requestJson; + return objectMapper.writeValueAsString(requestBodyObject); } catch (final JsonProcessingException je) { log.error("Parsing error occurred while converting Object to JSON."); throw new NcmpException("Parsing error occurred while converting given object to JSON.", - je.getMessage()); + je.getMessage()); } } - private Map<String, String> getAdditionalPropertiesMap(final Collection<DataNode> additionalPropertyList) { - if (additionalPropertyList == null || additionalPropertyList.size() == 0) { + private Map<String, String> getCmHandlePropertiesAsMap(final Collection<DataNode> cmHandlePropertiesList) { + if (cmHandlePropertiesList == null || cmHandlePropertiesList.size() == 0) { return null; } - final Map<String, String> additionalPropertyMap = new LinkedHashMap<>(); - for (final var node : additionalPropertyList) { - additionalPropertyMap.put(String.valueOf(node.getLeaves().get("name")), - String.valueOf(node.getLeaves().get("value"))); + final Map<String, String> cmHandlePropertiesMap = new LinkedHashMap<>(); + for (final var node: cmHandlePropertiesList) { + cmHandlePropertiesMap.put(String.valueOf(node.getLeaves().get("name")), + String.valueOf(node.getLeaves().get("value"))); } - return additionalPropertyMap; + return cmHandlePropertiesMap; } - private Object handleResponse(final ResponseEntity<Object> responseEntity) { + private Object handleResponse(final @NotNull ResponseEntity<Object> responseEntity) { if (responseEntity.getStatusCode() == HttpStatus.OK) { return responseEntity.getBody(); } else { throw new NcmpException("Not able to get resource data.", - "DMI status code: " + responseEntity.getStatusCodeValue() - + ", DMI response body: " + responseEntity.getBody()); + "DMI status code: " + responseEntity.getStatusCodeValue() + + ", DMI response body: " + responseEntity.getBody()); + } + } + + private void handleResponseForPost(final @NotNull ResponseEntity<Void> responseEntity) { + if (responseEntity.getStatusCode() != HttpStatus.CREATED) { + throw new NcmpException("Not able to create resource data.", + "DMI status code: " + responseEntity.getStatusCodeValue() + + ", DMI response body: " + responseEntity.getBody()); } } - private PersistenceCmHandle toPersistenceCmHandle(final DmiPluginRegistration dmiPluginRegistration, - final CmHandle cmHandle) { + private String getGenericRequestBody(final DataNode cmHandleDataNode) { + final Collection<DataNode> cmHandlePropertiesList = cmHandleDataNode.getChildDataNodes(); + final Map<String, String> cmHandlePropertiesMap = getCmHandlePropertiesAsMap(cmHandlePropertiesList); + final var requetBodyObject = GenericRequestBody.builder() + .operation(GenericRequestBody.OperationEnum.READ) + .cmHandleProperties(cmHandlePropertiesMap) + .build(); + return prepareOperationBody(requetBodyObject); + } + + private PersistenceCmHandle toPersistenceCmHandle(final String dmiPluginService, + final CmHandle cmHandle) { final PersistenceCmHandle persistenceCmHandle = new PersistenceCmHandle(); - persistenceCmHandle.setDmiServiceName(dmiPluginRegistration.getDmiPlugin()); + persistenceCmHandle.setDmiServiceName(dmiPluginService); persistenceCmHandle.setId(cmHandle.getCmHandleID()); if (cmHandle.getCmHandleProperties() == null) { persistenceCmHandle.setAdditionalProperties(Collections.EMPTY_MAP); @@ -295,4 +278,54 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return persistenceCmHandle; } + private void parseAndCreateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { + try { + final List<PersistenceCmHandle> createdPersistenceCmHandles = + new LinkedList<>(); + for (final CmHandle cmHandle: dmiPluginRegistration.getCreatedCmHandles()) { + createdPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration.getDmiPlugin(), cmHandle)); + } + final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList(); + persistenceCmHandlesList.setCmHandles(createdPersistenceCmHandles); + final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); + cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry", + cmHandleJsonData, NO_TIMESTAMP); + } catch (final JsonProcessingException e) { + log.error("Parsing error occurred while converting Object to JSON for DMI Registry."); + throw new DataValidationException( + "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e + .getMessage(), e); + } + } + + private void parseAndUpdateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { + try { + final List<PersistenceCmHandle> updatedPersistenceCmHandles = + new LinkedList<>(); + for (final CmHandle cmHandle: dmiPluginRegistration.getUpdatedCmHandles()) { + updatedPersistenceCmHandles.add(toPersistenceCmHandle(dmiPluginRegistration.getDmiPlugin(), cmHandle)); + } + final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList(); + persistenceCmHandlesList.setCmHandles(updatedPersistenceCmHandles); + final String cmHandlesJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); + cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, + "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP); + } catch (final JsonProcessingException e) { + log.error("Parsing error occurred while converting Object to JSON DMI Registry."); + throw new DataValidationException( + "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e + .getMessage(), e); + } + } + + private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { + for (final String cmHandle: dmiPluginRegistration.getRemovedCmHandles()) { + try { + cpsDataService.deleteListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, + "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP); + } catch (final DataNodeNotFoundException e) { + log.warn("Datanode {} not deleted message {}", cmHandle, e.getMessage()); + } + } + } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java index 3e4f03dfdb..cc4e2c7881 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java @@ -24,6 +24,7 @@ import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration.DmiProperties; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @@ -45,8 +46,15 @@ public class DmiRestClient { return restTemplate.exchange(dmiResourceUrl, HttpMethod.PUT, httpEntity, Object.class); } + public ResponseEntity<Void> postOperationWithJsonData(final String dmiResourceUrl, + final String jsonData, final HttpHeaders headers) { + final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders(headers)); + return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Void.class); + } + private HttpHeaders configureHttpHeaders(final HttpHeaders httpHeaders) { httpHeaders.setBasicAuth(dmiProperties.getAuthUsername(), dmiProperties.getAuthPassword()); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); return httpHeaders; } }
\ No newline at end of file diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java index 2b13d165f2..63c4d49a91 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java @@ -32,26 +32,27 @@ import org.springframework.stereotype.Component; public class DmiOperations { @Getter - public enum PassThroughEnum { - OPERATIONAL("/ncmp-datastore:passthrough-operational/"), - RUNNING("/ncmp-datastore:passthrough-running/"); + public enum DataStoreEnum { + PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational"), + PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running"); private String value; - PassThroughEnum(final String value) { + DataStoreEnum(final String value) { this.value = value; } @Override @JsonValue public String toString() { - return String.valueOf(value); + return value; } } private DmiRestClient dmiRestClient; + private static final String DMI_BASE_PATH = "/dmi/api"; private static final String PARENT_CM_HANDLE_URI = "/v1/ch/{cmHandle}/data/ds"; - private final int indexCmHandleInUri; + private static final String URL_SEPARATOR = "/"; /** * Constructor for {@code DmiOperations}. This method also manipulates url properties. @@ -60,7 +61,6 @@ public class DmiOperations { */ public DmiOperations(final DmiRestClient dmiRestClient) { this.dmiRestClient = dmiRestClient; - indexCmHandleInUri = PARENT_CM_HANDLE_URI.indexOf("{cmHandle}"); } /** @@ -76,17 +76,17 @@ public class DmiOperations { * @param jsonBody json body for put operation * @return {@code ResponseEntity} response entity */ - public ResponseEntity<Object> getResouceDataOperationalFromDmi(final String dmiBasePath, - final String cmHandle, - final String resourceId, - final String fieldsQuery, - final Integer depthQuery, - final String acceptParam, - final String jsonBody) { - final var builder = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId, - fieldsQuery, depthQuery, PassThroughEnum.OPERATIONAL); + public ResponseEntity<Object> getResourceDataOperationalFromDmi(final String dmiBasePath, + final String cmHandle, + final String resourceId, + final String fieldsQuery, + final Integer depthQuery, + final String acceptParam, + final String jsonBody) { + final var dmiResourceDataUrl = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId, + fieldsQuery, depthQuery, DataStoreEnum.PASSTHROUGH_OPERATIONAL); final var httpHeaders = prepareHeader(acceptParam); - return dmiRestClient.putOperationWithJsonData(builder.toString(), jsonBody, httpHeaders); + return dmiRestClient.putOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders); } /** @@ -102,46 +102,78 @@ public class DmiOperations { * @param jsonBody json body for put operation * @return {@code ResponseEntity} response entity */ - public ResponseEntity<Object> getResouceDataPassThroughRunningFromDmi(final String dmiBasePath, - final String cmHandle, - final String resourceId, - final String fieldsQuery, - final Integer depthQuery, - final String acceptParam, - final String jsonBody) { - final var builder = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId, - fieldsQuery, depthQuery, PassThroughEnum.RUNNING); + public ResponseEntity<Object> getResourceDataPassThroughRunningFromDmi(final String dmiBasePath, + final String cmHandle, + final String resourceId, + final String fieldsQuery, + final Integer depthQuery, + final String acceptParam, + final String jsonBody) { + final var dmiResourceDataUrl = getDmiResourceDataUrl(dmiBasePath, cmHandle, resourceId, + fieldsQuery, depthQuery, DataStoreEnum.PASSTHROUGH_RUNNING); final var httpHeaders = prepareHeader(acceptParam); - return dmiRestClient.putOperationWithJsonData(builder.toString(), jsonBody, httpHeaders); + return dmiRestClient.putOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders); + } + + /** + * This method creates the resource data from pass-through running data store for given cm handle + * identifier on given resource using dmi client. + * + * @param dmiBasePath dmi base path + * @param cmHandle network resource identifier + * @param resourceId resource identifier + * @param jsonBody json body for put operation + * @return {@code ResponseEntity} response entity + */ + public ResponseEntity<Void> createResourceDataPassThroughRunningFromDmi(final String dmiBasePath, + final String cmHandle, + final String resourceId, + final String jsonBody) { + final var stringBuilder = getStringBuilderForPassThroughRunningUrl(dmiBasePath, + cmHandle, resourceId, DataStoreEnum.PASSTHROUGH_RUNNING); + return dmiRestClient.postOperationWithJsonData(stringBuilder.toString(), jsonBody, new HttpHeaders()); } @NotNull - private StringBuilder getDmiResourceDataUrl(final String dmiBasePath, + private String getDmiResourceDataUrl(final String dmiBasePath, final String cmHandle, final String resourceId, final String fieldsQuery, final Integer depthQuery, - final PassThroughEnum passThrough) { - final var builder = new StringBuilder(PARENT_CM_HANDLE_URI.replace("{cmHandle}", cmHandle)); - builder.append(passThrough.getValue()); - builder.insert(builder.length(), resourceId); - appendFieldsAndDepth(fieldsQuery, depthQuery, builder); - builder.insert(0, dmiBasePath); - return builder; + final DataStoreEnum dataStoreEnum) { + final var stringBuilder = getStringBuilderForPassThroughRunningUrl(dmiBasePath, + cmHandle, resourceId, dataStoreEnum); + appendFieldsAndDepth(stringBuilder, fieldsQuery, depthQuery); + return stringBuilder.toString(); + } + + @NotNull + private StringBuilder getStringBuilderForPassThroughRunningUrl(final String dmiServiceName, + final String cmHandle, + final String resourceId, + final DataStoreEnum dataStoreEnum) { + final var stringBuilder = new StringBuilder(dmiServiceName); + stringBuilder.append(DMI_BASE_PATH); + stringBuilder.append(PARENT_CM_HANDLE_URI.replace("{cmHandle}", cmHandle)); + stringBuilder.append(URL_SEPARATOR + dataStoreEnum.getValue()); + stringBuilder.insert(stringBuilder.length(), URL_SEPARATOR + resourceId); + return stringBuilder; } - private void appendFieldsAndDepth(final String fieldsQuery, final Integer depthQuery, final StringBuilder builder) { + private void appendFieldsAndDepth(final StringBuilder stringBuilder, + final String fieldsQuery, + final Integer depthQuery) { final var doesFieldExists = (fieldsQuery != null && !fieldsQuery.isEmpty()); if (doesFieldExists) { - builder.append("?").append("fields=").append(fieldsQuery); + stringBuilder.append("?").append("fields=").append(fieldsQuery); } if (depthQuery != null) { - if (!doesFieldExists) { - builder.append("?"); + if (doesFieldExists) { + stringBuilder.append("&"); } else { - builder.append("&"); + stringBuilder.append("?"); } - builder.append("depth=").append(depthQuery); + stringBuilder.append("depth=").append(depthQuery); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java index 5b82c51b35..9ed78de6e7 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java @@ -24,15 +24,16 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonValue; import java.util.Map; +import lombok.Builder; import lombok.Getter; -import lombok.Setter; -@Getter -@Setter @JsonInclude(Include.NON_NULL) +@Getter +@Builder public class GenericRequestBody { public enum OperationEnum { - READ("read"); + READ("read"), + CREATE("create"); private String value; OperationEnum(final String value) { @@ -48,6 +49,6 @@ public class GenericRequestBody { private OperationEnum operation; private String dataType; - private String data; + private Object data; private Map<String, String> cmHandleProperties; } 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 45fa0af454..8a32ad5925 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 @@ -51,6 +51,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def cmHandle = 'some handle' def noTimestamp = null + def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']" def expectedDataspaceName = 'NFP-Operational' def 'Query data nodes by cps path with #fetchDescendantsOption.'() { @@ -159,14 +160,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { } def 'Get resource data for pass-through operational from dmi.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() when: 'get resource data is called' def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle', 'testResourceId', @@ -175,9 +170,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 5) then: 'cps data service is being called once to get data node' 1 * mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'dmi operation is being called to get resource data' - 1 * mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService', + 1 * mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService', 'testCmHandle', 'testResourceId', 'testFieldQuery', @@ -188,17 +183,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { and: 'dmi returns ok response' response == 'result-json' } + def 'Get resource data for pass-through operational from dmi threw parsing exception.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() + and: 'cps data service returns valid cmHandle data node' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'objectMapper not able to parse object' def mockObjectMapper = Mock(ObjectMapper) objectUnderTest.objectMapper = mockObjectMapper @@ -212,19 +203,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'exception is thrown' thrown(NcmpException.class) } + def 'Get resource data for pass-through operational from dmi return NOK response.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() + and: 'cps data service returns valid cmHandle data node' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'dmi returns NOK response' - mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService', + mockDmiOperations.getResourceDataOperationalFromDmi('testDmiService', 'testCmHandle', 'testResourceId', 'testFieldQuery', @@ -241,20 +228,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'exception is thrown' thrown(NcmpException.class) } + def 'Get resource data for pass-through running from dmi.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node representing cmhandle and its properties' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() and: 'cpsDataService returns valid dataNode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'dmi returns valid response and data' - mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService', + mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService', 'testCmHandle', 'testResourceId', 'testFieldQuery', @@ -270,18 +252,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'get resource data returns expected response' response == '{result-json}' } + def 'Get resource data for pass-through running from dmi threw parsing exception.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node representing cmhandle and its properties' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() and: 'cpsDataService returns valid dataNode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'objectMapper not able to parse object' def mockObjectMapper = Mock(ObjectMapper) objectUnderTest.objectMapper = mockObjectMapper @@ -295,20 +272,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'exception is thrown' thrown(NcmpException.class) } + def 'Get resource data for pass-through running from dmi return NOK response.'() { - given: 'xpath' - def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']" - and: 'data node representing cmhandle and its properties' - def dataNode = new DataNode() - dataNode.leaves = ['dmi-service-name':'testDmiService'] - def childDataNode = new DataNode() - childDataNode.leaves = ['name':'testName','value':'testValue'] - dataNode.childDataNodes = [childDataNode] + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() and: 'cpsDataService returns valid dataNode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', - xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode and: 'dmi returns NOK response' - mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService', + mockDmiOperations.getResourceDataPassThroughRunningFromDmi('testDmiService', 'testCmHandle', 'testResourceId', 'testFieldQuery', @@ -325,4 +297,48 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'exception is thrown' thrown(NcmpException.class) } + + def 'Write resource data for pass-through running from dmi using POST.'() { + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() + and: 'cpsDataService returns valid dataNode' + mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode + when: 'get resource data is called' + objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle', + 'testResourceId', + '{some-json}', 'application/json') + then: 'dmi called with correct data' + 1 * mockDmiOperations.createResourceDataPassThroughRunningFromDmi('testDmiService', + 'testCmHandle', + 'testResourceId', + '{"operation":"create","dataType":"application/json","data":"{some-json}","cmHandleProperties":{"testName":"testValue"}}') + >> { new ResponseEntity<>(HttpStatus.CREATED) } + } + + def 'Write resource data for pass-through running from dmi using POST "not found" response (from DMI).'() { + given: 'data node representing cmHandle and its properties' + def cmHandleDataNode = prepareCmHandleDataNode() + and: 'cpsDataService returns valid dataNode' + mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode + and: 'dmi throws exception' + 1 * mockDmiOperations.createResourceDataPassThroughRunningFromDmi(_ as String, _ as String, _ as String, _ as String) + >> { new ResponseEntity<>(HttpStatus.NOT_FOUND) } + when: 'get resource data is called' + objectUnderTest.createResourceDataPassThroughRunningForCmHandle('testCmHandle', + 'testResourceId', + '{some-json}', 'application/json') + then: 'exception is thrown' + thrown(NcmpException.class) + } + + private DataNode prepareCmHandleDataNode() { + def cmHandleDataNode = new DataNode() + cmHandleDataNode.leaves = ['dmi-service-name': 'testDmiService'] + def cmHandlePropertyDataNode = new DataNode() + cmHandlePropertyDataNode.leaves = ['name': 'testName', 'value': 'testValue'] + cmHandleDataNode.childDataNodes = [cmHandlePropertyDataNode] + cmHandleDataNode + } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy index 98bbe8748f..879c73c27e 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy @@ -35,7 +35,7 @@ class DmiRestClientSpec extends Specification { def objectUnderTest = new DmiRestClient(mockRestTemplate, mockDmiProperties) def 'DMI PUT operation.'() { - given: 'a get url' + given: 'a PUT url' def getResourceDataUrl = 'http://some-uri/getResourceDataUrl' and: 'dmi properties' setupTestConfigurationData() @@ -48,6 +48,20 @@ class DmiRestClientSpec extends Specification { result == mockResponseEntity } + def 'DMI POST operation.'() { + given: 'a POST url' + def getResourceDataUrl = 'http://some-uri/createResourceDataUrl' + and: 'dmi properties' + setupTestConfigurationData() + and: 'the rest template returns a valid response entity' + def mockResponseEntity = Mock(ResponseEntity) + mockRestTemplate.postForEntity(getResourceDataUrl, _ as HttpEntity, Void.class) >> mockResponseEntity + when: 'POST operation is invoked' + def result = objectUnderTest.postOperationWithJsonData(getResourceDataUrl, 'json-data', new HttpHeaders()) + then: 'the output of the method is equal to the output from the test template' + result == mockResponseEntity + } + def setupTestConfigurationData() { mockDmiProperties.authUsername >> 'some-username' mockDmiProperties.authPassword >> 'some-password' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy index ceb35696a9..c2a135e670 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy @@ -22,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.operation 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.operation.DmiOperations import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -40,12 +39,12 @@ class DmiOperationsSpec extends Specification { @Autowired DmiOperations objectUnderTest = new DmiOperations(mockDmiRestClient) - def 'call get resource data for pass-through:operational datastore from dmi.'() { + def 'call get resource data for pass-through:operational datastore from DMI.'() { given: 'expected url' - def expectedUrl = 'testDmiBasePath/v1/ch/testCmhandle/data/ds' + + def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' + '/ncmp-datastore:passthrough-operational/testResourceId?fields=testFieldsQuery&depth=10' - when: 'get resource data is called to dmi' - objectUnderTest.getResouceDataOperationalFromDmi('testDmiBasePath', + when: 'get resource data is called to DMI' + objectUnderTest.getResourceDataOperationalFromDmi('testDmiBasePath', 'testCmhandle', 'testResourceId', 'testFieldsQuery', @@ -55,12 +54,12 @@ class DmiOperationsSpec extends Specification { then: 'the put operation is executed with the correct URL' 1 * mockDmiRestClient.putOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders) } - def 'call get resource data for pass-through:running datastore from dmi.'() { + def 'call get resource data for pass-through:running datastore from DMI.'() { given: 'expected url' - def expectedUrl = 'testDmiBasePath/v1/ch/testCmhandle/data/ds' + + def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' + '/ncmp-datastore:passthrough-running/testResourceId?fields=testFieldsQuery&depth=10' - when: 'get resource data is called to dmi' - objectUnderTest.getResouceDataPassThroughRunningFromDmi('testDmiBasePath', + when: 'get resource data is called to DMI' + objectUnderTest.getResourceDataPassThroughRunningFromDmi('testDmiBasePath', 'testCmhandle', 'testResourceId', 'testFieldsQuery', @@ -70,4 +69,16 @@ class DmiOperationsSpec extends Specification { then: 'the put operation is executed with the correct URL' 1 * mockDmiRestClient.putOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders) } + def 'call create resource data for pass-through:running datastore from DMI.'() { + given: 'expected url' + def expectedUrl = 'testDmiBasePath/dmi/api/v1/ch/testCmhandle/data/ds' + + '/ncmp-datastore:passthrough-running/testResourceId' + when: 'get resource data is called to DMI' + objectUnderTest.createResourceDataPassThroughRunningFromDmi('testDmiBasePath', + 'testCmhandle', + 'testResourceId', + 'testJsonbody') + then: 'the put operation is executed with the correct URL' + 1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders) + } }
\ No newline at end of file |