summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorniamhcore <niamh.core@est.tech>2021-07-30 16:25:16 +0100
committerniamhcore <niamh.core@est.tech>2021-08-10 13:33:52 +0100
commit3139ece993c68ce7e40d166acdd5d9572a3a8a1e (patch)
tree4a9ee12234815d6f5bc14557d5228c53b66f3b81 /src/main
parent2270d76e4f33ad231cdae317e88ea1769297cfec (diff)
Retrieve yang-resources for one or more modules
Updating openapi to add a new rest endpoint Updating restconf client to support post with json Adding a ModuleResourceNotFound exception Adding a test util class Fixing merge conflict Refactoring SDNC operations Issue-ID: CPS-484 Signed-off-by: niamhcore <niamh.core@est.tech> Change-Id: Id76dfe4cb12053771883e0271153d7bf7cd98548
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java2
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java38
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/model/ModuleReference.java37
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java32
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java9
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java56
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java27
-rw-r--r--src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java45
8 files changed, 214 insertions, 32 deletions
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java
index a6ec6dfa..49db7d8b 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java
@@ -46,7 +46,7 @@ public class DmiExceptionHandler {
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
- @ExceptionHandler({ModulesNotFoundException.class})
+ @ExceptionHandler({ModulesNotFoundException.class, ModuleResourceNotFoundException.class})
public static ResponseEntity<Object> handleNotFoundExceptions(final DmiException exception) {
return buildErrorResponse(HttpStatus.NOT_FOUND, exception);
}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java
new file mode 100644
index 00000000..65db2712
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModuleResourceNotFoundException.java
@@ -0,0 +1,38 @@
+/*
+ * ============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.exception;
+
+public class ModuleResourceNotFoundException extends DmiException {
+
+ private static final long serialVersionUID = 4764849097602543408L;
+
+ private static final String ERROR_MESSAGE = "Module resource not found for given cmHandle: ";
+
+ /**
+ * Constructor.
+ *
+ * @param cmHandle the cm handle
+ * @param details the details of the error
+ */
+ public ModuleResourceNotFoundException(final String cmHandle, final String details) {
+ super(ERROR_MESSAGE + cmHandle, details);
+ }
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleReference.java b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleReference.java
new file mode 100644
index 00000000..cb9b7cbb
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleReference.java
@@ -0,0 +1,37 @@
+/*
+ * ============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 lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * Module Reference.
+ */
+@Getter
+@Setter
+@EqualsAndHashCode
+public class ModuleReference {
+
+ private String name;
+ private String revision;
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
index 0e1d3d67..5725f094 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
@@ -20,14 +20,17 @@
package org.onap.cps.ncmp.dmi.rest.controller;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.dmi.model.CmHandles;
+import org.onap.cps.ncmp.dmi.model.ModuleReference;
+import org.onap.cps.ncmp.dmi.model.ModuleRequestParent;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginInternalApi;
import org.onap.cps.ncmp.dmi.service.DmiService;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -40,9 +43,11 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
private DmiService dmiService;
- @Autowired
- public DmiRestController(final DmiService dmiService) {
+ private ObjectMapper objectMapper;
+
+ public DmiRestController(final DmiService dmiService, final ObjectMapper objectMapper) {
this.dmiService = dmiService;
+ this.objectMapper = objectMapper;
}
@Override
@@ -52,11 +57,25 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
return new ResponseEntity<>(modulesListAsJson, HttpStatus.OK);
}
+ @Override
+ public ResponseEntity<Object> retrieveModuleResources(@Valid final ModuleRequestParent moduleRequestParent,
+ final String cmHandle) {
+ if (moduleRequestParent.getOperation().toString().equals("read")) {
+ final var moduleReferenceList = convertRestObjectToJavaApiObject(moduleRequestParent);
+ final var response = dmiService.getModuleResources(cmHandle, moduleReferenceList);
+ if (response.isEmpty()) {
+ return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
+ }
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+ return new ResponseEntity<>("Unsupported operation", HttpStatus.CONFLICT);
+ }
+
/**
* This method register given list of cm-handles to ncmp.
*
* @param cmHandles list of cm-handles
- * @return (@code ResponseEntity) response entity
+ * @return (@ code ResponseEntity) response entity
*/
public ResponseEntity<String> registerCmHandles(final @Valid CmHandles cmHandles) {
final List<String> cmHandlesList = cmHandles.getCmHandles();
@@ -66,4 +85,9 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi {
dmiService.registerCmHandles(cmHandlesList);
return new ResponseEntity<>("cm-handle registered successfully.", HttpStatus.CREATED);
}
+
+ private List<ModuleReference> convertRestObjectToJavaApiObject(final ModuleRequestParent moduleRequestParent) {
+ return objectMapper
+ .convertValue(moduleRequestParent.getData().getModules(), new TypeReference<List<ModuleReference>>() {});
+ }
}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
index d9196ecb..aeff3dc6 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
@@ -22,6 +22,7 @@ package org.onap.cps.ncmp.dmi.service;
import java.util.List;
import org.onap.cps.ncmp.dmi.exception.DmiException;
+import org.onap.cps.ncmp.dmi.model.ModuleReference;
/**
* Interface for handling Dmi plugin Data.
@@ -45,4 +46,12 @@ public interface DmiService {
*/
void registerCmHandles(List<String> cmHandles);
+ /**
+ * Get module resources for the given cm handle and modules.
+ *
+ * @param cmHandle cmHandle
+ * @param modules a list of module data
+ * @return returns all module resources
+ */
+ String getModuleResources(String cmHandle, List<ModuleReference> modules);
}
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 990a421e..bf0689ca 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
@@ -23,15 +23,19 @@ package org.onap.cps.ncmp.dmi.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
+import net.minidev.json.JSONArray;
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;
+import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException;
import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException;
import org.onap.cps.ncmp.dmi.model.CmHandleOperation;
import org.onap.cps.ncmp.dmi.model.CreatedCmHandle;
+import org.onap.cps.ncmp.dmi.model.ModuleReference;
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient;
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,7 +43,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
-
@Service
@Slf4j
public class DmiServiceImpl implements DmiService {
@@ -53,19 +56,19 @@ public class DmiServiceImpl implements DmiService {
* Constructor.
*
* @param dmiPluginProperties dmiPluginProperties
- * @param ncmpRestClient ncmpRestClient
- * @param objectMapper objectMapper
- * @param sdncOperations sdncOperations
+ * @param ncmpRestClient ncmpRestClient
+ * @param sdncOperations sdncOperations
+ * @param objectMapper objectMapper
*/
@Autowired
public DmiServiceImpl(final DmiPluginProperties dmiPluginProperties,
- final NcmpRestClient ncmpRestClient,
- final ObjectMapper objectMapper,
- final SdncOperations sdncOperations) {
+ final NcmpRestClient ncmpRestClient,
+ final SdncOperations sdncOperations, final ObjectMapper objectMapper) {
this.dmiPluginProperties = dmiPluginProperties;
this.ncmpRestClient = ncmpRestClient;
this.objectMapper = objectMapper;
this.sdncOperations = sdncOperations;
+ this.objectMapper = objectMapper;
}
@Override
@@ -79,16 +82,33 @@ public class DmiServiceImpl implements DmiService {
return responseBody;
} else {
throw new DmiException("SDNC is not able to process request.",
- "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
+ "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
}
}
@Override
+ public String getModuleResources(final String cmHandle, final List<ModuleReference> moduleReferences) {
+ final JSONArray getModuleResponses = new JSONArray();
+ for (final var moduleReference : moduleReferences) {
+ final var moduleRequest = createModuleRequest(moduleReference);
+ final var responseEntity = sdncOperations.getModuleResource(cmHandle, moduleRequest);
+ if (responseEntity.getStatusCode() == HttpStatus.OK) {
+ getModuleResponses.add(responseEntity.getBody());
+ } else {
+ 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.");
+ }
+ }
+ return getModuleResponses.toJSONString();
+ }
+
+ @Override
public void registerCmHandles(final List<String> cmHandles) {
final CmHandleOperation cmHandleOperation = new CmHandleOperation();
cmHandleOperation.setDmiPlugin(dmiPluginProperties.getDmiServiceName());
final List<CreatedCmHandle> createdCmHandleList = new ArrayList<>();
- for (final String cmHandle: cmHandles) {
+ for (final String cmHandle : cmHandles) {
final CreatedCmHandle createdCmHandle = new CreatedCmHandle();
createdCmHandle.setCmHandle(cmHandle);
createdCmHandleList.add(createdCmHandle);
@@ -100,7 +120,7 @@ public class DmiServiceImpl implements DmiService {
} 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)) {
@@ -108,4 +128,20 @@ public class DmiServiceImpl implements DmiService {
}
}
+ private String createModuleRequest(final ModuleReference moduleReference) {
+ final var ietfNetconfModuleReferences = new LinkedHashMap<>();
+ ietfNetconfModuleReferences.put("ietf-netconf-monitoring:identifier", moduleReference.getName());
+ ietfNetconfModuleReferences.put("ietf-netconf-monitoring:version", moduleReference.getRevision());
+ final var writer = objectMapper.writer().withRootName("ietf-netconf-monitoring:input");
+ final String moduleRequest;
+ try {
+ 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());
+ throw new DmiException("Unable to process JSON.",
+ "JSON exception occurred when creating the module request.", e);
+ }
+ return moduleRequest;
+ }
}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
index cf7c50a5..adac5e64 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java
@@ -30,6 +30,7 @@ import org.springframework.web.client.RestTemplate;
@Component
public class SdncRestconfClient {
+
private SdncProperties sdncProperties;
private RestTemplate restTemplate;
@@ -42,16 +43,34 @@ public class SdncRestconfClient {
* restconf get operation on sdnc.
*
* @param getResourceUrl sdnc get url
- *
* @return the response entity
*/
public ResponseEntity<String> getOperation(final String getResourceUrl) {
final String sdncBaseUrl = sdncProperties.getBaseUrl();
final String sdncRestconfUrl = sdncBaseUrl.concat(getResourceUrl);
+ final var httpEntity = new HttpEntity<>(configureHttpHeaders());
+ return restTemplate.getForEntity(sdncRestconfUrl, String.class, httpEntity);
+ }
+
+ /**
+ * restconf post operation on sdnc.
+ *
+ * @param postResourceUrl sdnc post resource url
+ * @param jsonData json data
+ * @return the response entity
+ */
+ public ResponseEntity<String> postOperationWithJsonData(final String postResourceUrl,
+ final String jsonData) {
+ final var sdncBaseUrl = sdncProperties.getBaseUrl();
+ final var sdncRestconfUrl = sdncBaseUrl.concat(postResourceUrl);
+ final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders());
+ return restTemplate.postForEntity(sdncRestconfUrl, httpEntity, String.class);
+ }
+
+ private HttpHeaders configureHttpHeaders() {
final var httpHeaders = new HttpHeaders();
httpHeaders.setBasicAuth(sdncProperties.getAuthUsername(), sdncProperties.getAuthPassword());
- httpHeaders.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
- final var httpEntity = new HttpEntity<>(httpHeaders);
- return restTemplate.getForEntity(sdncRestconfUrl, String.class, httpEntity);
+ httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+ return httpHeaders;
}
}
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 4e4e7217..0d1c3438 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
@@ -20,7 +20,6 @@
package org.onap.cps.ncmp.dmi.service.operation;
-import org.jetbrains.annotations.NotNull;
import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties;
import org.onap.cps.ncmp.dmi.service.client.SdncRestconfClient;
import org.springframework.http.ResponseEntity;
@@ -29,29 +28,32 @@ import org.springframework.stereotype.Component;
@Component
public class SdncOperations {
- private static final String TOPOLOGY_URL_TEMPLATE = "/rests/data/network-topology:network-topology"
- + "/topology={topologyId}";
+
+ private static final String TOPOLOGY_URL_TEMPLATE_DATA =
+ "/rests/data/network-topology:network-topology/topology={topologyId}";
+ private static final String TOPOLOGY_URL_TEMPLATE_OPERATIONAL =
+ "/rests/operations/network-topology:network-topology/topology={topologyId}";
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 SdncProperties sdncProperties;
private SdncRestconfClient sdncRestconfClient;
- private final String topologyUrl;
- private final String topologyMountUrlTemplate;
+ private final String topologyUrlData;
+ private final String topologyUrlOperational;
/**
- * Constructor for {@code SdncOperations}. This method also manipulates
- * url properties.
+ * Constructor for {@code SdncOperations}. This method also manipulates url properties.
*
- * @param sdncProperties {@code SdncProperties}
+ * @param sdncProperties {@code SdncProperties}
* @param sdncRestconfClient {@code SdncRestconfClient}
*/
-
public SdncOperations(final SdncProperties sdncProperties, final SdncRestconfClient sdncRestconfClient) {
this.sdncProperties = sdncProperties;
this.sdncRestconfClient = sdncRestconfClient;
- topologyUrl = TOPOLOGY_URL_TEMPLATE.replace("{topologyId}", this.sdncProperties.getTopologyId());
- topologyMountUrlTemplate = topologyUrl + MOUNT_URL_TEMPLATE;
+ topologyUrlOperational =
+ TOPOLOGY_URL_TEMPLATE_OPERATIONAL.replace("{topologyId}", this.sdncProperties.getTopologyId());
+ topologyUrlData = TOPOLOGY_URL_TEMPLATE_DATA.replace("{topologyId}", this.sdncProperties.getTopologyId());
}
/**
@@ -65,11 +67,28 @@ public class SdncOperations {
return sdncRestconfClient.getOperation(urlWithNodeId);
}
- @NotNull
+ /**
+ * Get module schema.
+ *
+ * @param nodeId node ID
+ * @param moduleProperties module properties
+ * @return response entity
+ */
+ public ResponseEntity<String> getModuleResource(final String nodeId, final String moduleProperties) {
+ final String getYangResourceUrl = prepareGetOperationSchemaUrl(nodeId);
+ return sdncRestconfClient.postOperationWithJsonData(getYangResourceUrl, moduleProperties);
+ }
+
private String prepareGetSchemaUrl(final String nodeId) {
- final String topologyMountUrl = topologyMountUrlTemplate;
+ final var topologyMountUrl = topologyUrlData + MOUNT_URL_TEMPLATE;
final String topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId);
final String resourceUrl = topologyMountUrlWithNodeId.concat(GET_SCHEMA_URL);
return resourceUrl;
}
+
+ private String prepareGetOperationSchemaUrl(final String nodeId) {
+ final var topologyMountUrl = topologyUrlOperational + MOUNT_URL_TEMPLATE;
+ final var topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId);
+ return topologyMountUrlWithNodeId.concat(GET_SCHEMA_SOURCES_URL);
+ }
}