From 7c4a9aa88269dbdb21c5c54bc47508463548bc1e Mon Sep 17 00:00:00 2001 From: tragait Date: Mon, 19 Jul 2021 13:46:37 +0100 Subject: implement dmi get modules using sdnc client Issue-ID: CPS-483 Change-Id: Ib9b730cabeba308f11db31ef1b45bbd92e3a6ed5 Signed-off-by: tragait --- .../onap/cps/ncmp/dmi/config/CpsConfiguration.java | 55 ---------------- .../onap/cps/ncmp/dmi/config/DmiConfiguration.java | 69 ++++++++++++++++++++ .../onap/cps/ncmp/dmi/exception/DmiException.java | 59 +++++++++++++++++ .../ncmp/dmi/exception/DmiExceptionHandler.java | 74 +++++++++++++++++++++ .../dmi/exception/ModulesNotFoundException.java | 38 +++++++++++ .../dmi/rest/controller/DmiRestController.java | 16 +++-- .../org/onap/cps/ncmp/dmi/service/DmiService.java | 12 +++- .../onap/cps/ncmp/dmi/service/DmiServiceImpl.java | 28 +++++++- .../ncmp/dmi/service/client/NcmpRestClient.java | 2 +- .../dmi/service/client/SdncRestconfClient.java | 57 ++++++++++++++++ .../ncmp/dmi/service/operation/SdncOperations.java | 75 ++++++++++++++++++++++ 11 files changed, 419 insertions(+), 66 deletions(-) delete mode 100644 src/main/java/org/onap/cps/ncmp/dmi/config/CpsConfiguration.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java create mode 100644 src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java (limited to 'src/main/java') diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/CpsConfiguration.java b/src/main/java/org/onap/cps/ncmp/dmi/config/CpsConfiguration.java deleted file mode 100644 index a9970da8..00000000 --- a/src/main/java/org/onap/cps/ncmp/dmi/config/CpsConfiguration.java +++ /dev/null @@ -1,55 +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.config; - -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -/** - * Provides access to cps base url and cps authentication. - */ -@Configuration -public class CpsConfiguration { - - @Getter - @Component - public static class CpsProperties { - - @Value("${cps-core.baseUrl}") - private String baseUrl; - @Value("${cps-core.dmiRegistrationUrl}") - private String dmiRegistrationUrl; - @Value("${cps-core.auth.username}") - private String authUsername; - @Value("${cps-core.auth.password}") - private String authPassword; - } - - @Bean - public RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder.build(); - } -} \ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java b/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java new file mode 100644 index 00000000..9b8b05b2 --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/config/DmiConfiguration.java @@ -0,0 +1,69 @@ +/* + * ============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.config; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * Provides access to cps base url and cps authentication. + */ +@Configuration +public class DmiConfiguration { + + @Getter + @Component + public static class CpsProperties { + + @Value("${cps-core.baseUrl}") + private String baseUrl; + @Value("${cps-core.dmiRegistrationUrl}") + private String dmiRegistrationUrl; + @Value("${cps-core.auth.username}") + private String authUsername; + @Value("${cps-core.auth.password}") + private String authPassword; + } + + @Getter + @Component + public static class SdncProperties { + + @Value("${sdnc.baseUrl}") + private String baseUrl; + @Value("${sdnc.auth.username}") + private String authUsername; + @Value("${sdnc.auth.password}") + private String authPassword; + @Value("${sdnc.topologyId}") + public String topologyId; + } + + @Bean + public RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { + return restTemplateBuilder.build(); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java new file mode 100644 index 00000000..c099a1cc --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiException.java @@ -0,0 +1,59 @@ +/* + * ============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; + +import lombok.Getter; + +/** + * Dmi exception. + */ +public class DmiException extends RuntimeException { + + private static final long serialVersionUID = 1481520410918497487L; + + @Getter + final String details; + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + */ + public DmiException(final String message, final String details) { + super(message); + this.details = details; + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + * @param cause the cause of the exception + */ + public DmiException(final String message, final String details, final Throwable cause) { + super(message, cause); + this.details = details; + } + +} 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 new file mode 100644 index 00000000..9ad561fc --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/DmiExceptionHandler.java @@ -0,0 +1,74 @@ +/* + * ============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; + +import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.dmi.model.ErrorMessage; +import org.onap.cps.ncmp.dmi.rest.controller.DmiRestController; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice(assignableTypes = {DmiRestController.class}) +public class DmiExceptionHandler { + + private DmiExceptionHandler() { + } + + /** + * Default exception handler. + * + * @param exception the exception to handle + * @return response with response code 500. + */ + @ExceptionHandler + public static ResponseEntity handleInternalServerErrorExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); + } + + @ExceptionHandler({ModulesNotFoundException.class}) + public static ResponseEntity handleNotFoundExceptions(final DmiException exception) { + return buildErrorResponse(HttpStatus.NOT_FOUND, exception); + } + + @ExceptionHandler({DmiException.class}) + public static ResponseEntity handleAnyOtherDmiExceptions(final DmiException exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); + } + + private static ResponseEntity buildErrorResponse(final HttpStatus httpStatus, final Exception exception) { + logForNonDmiException(exception); + final var errorMessage = new ErrorMessage(); + errorMessage.setStatus(httpStatus.toString()); + errorMessage.setMessage(exception.getMessage()); + errorMessage.setDetails(exception instanceof DmiException ? ((DmiException) exception).getDetails() : + "Check logs for details."); + return new ResponseEntity<>(errorMessage, httpStatus); + } + + private static void logForNonDmiException(final Exception exception) { + if (exception.getCause() != null || !(exception instanceof DmiException)) { + log.error("Exception occurred", exception); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.java new file mode 100644 index 00000000..ded54d91 --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/exception/ModulesNotFoundException.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 ModulesNotFoundException extends DmiException { + + private static final long serialVersionUID = 980438585188332404L; + + private static final String ERROR_MESSAGE = "Not able to register the given cm-handles: "; + + /** + * Constructor. + * + * @param cmHandle cmHandle identifier + * @param details the error details + */ + public ModulesNotFoundException(final String cmHandle, final String details) { + super(ERROR_MESSAGE + cmHandle, details); + } +} 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 c4cbaece..8081b73d 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,8 +20,8 @@ package org.onap.cps.ncmp.dmi.rest.controller; +import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi; import org.onap.cps.ncmp.dmi.service.DmiService; -import org.onap.cps.ncmp.rest.api.DmiPluginApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -32,13 +32,17 @@ import org.springframework.web.bind.annotation.RestController; @RestController public class DmiRestController implements DmiPluginApi { - @Autowired private DmiService dmiService; - @Override - public ResponseEntity helloWorld() { - final var helloWorld = dmiService.getHelloWorld(); - return new ResponseEntity<>(helloWorld, HttpStatus.OK); + @Autowired + public DmiRestController(final DmiService dmiService) { + this.dmiService = dmiService; } + @Override + public ResponseEntity getModulesForCmHandle(final String cmHandle) { + + final String modulesListAsJson = dmiService.getModulesForCmHandle(cmHandle); + return new ResponseEntity<>(modulesListAsJson, HttpStatus.OK); + } } 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 84c60d55..e595bd5f 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 @@ -20,12 +20,20 @@ package org.onap.cps.ncmp.dmi.service; +import org.onap.cps.ncmp.dmi.exception.DmiException; + /** * Interface for handling Dmi plugin Data. */ public interface DmiService { + /** - * Return Simple Hello World Statement. + * This method fetches all modules for given Cm Handle. + * + * @param cmHandle cm-handle to fetch the modules information + * @return {@code String} returns all modules + * @throws DmiException can throw dmi exception */ - String getHelloWorld(); + String getModulesForCmHandle(String cmHandle) throws DmiException; + } 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 5051b1ad..4367bf45 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 @@ -20,13 +20,37 @@ package org.onap.cps.ncmp.dmi.service; +import io.micrometer.core.instrument.util.StringUtils; +import org.onap.cps.ncmp.dmi.exception.DmiException; +import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException; +import org.onap.cps.ncmp.dmi.service.operation.SdncOperations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @Service public class DmiServiceImpl implements DmiService { + private SdncOperations sdncOperations; + + @Autowired + public DmiServiceImpl(final SdncOperations sdncOperations) { + this.sdncOperations = sdncOperations; + } + @Override - public String getHelloWorld() { - return "Hello World"; + public String getModulesForCmHandle(final String cmHandle) throws DmiException { + final ResponseEntity 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 responseBody; + } else { + throw new DmiException("SDNC is not able to process request.", + "response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody()); + } } } diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java b/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java index 2158e836..47651346 100644 --- a/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java +++ b/src/main/java/org/onap/cps/ncmp/dmi/service/client/NcmpRestClient.java @@ -20,7 +20,7 @@ package org.onap.cps.ncmp.dmi.service.client; -import org.onap.cps.ncmp.dmi.config.CpsConfiguration.CpsProperties; +import org.onap.cps.ncmp.dmi.config.DmiConfiguration.CpsProperties; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; 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 new file mode 100644 index 00000000..cf7c50a5 --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/service/client/SdncRestconfClient.java @@ -0,0 +1,57 @@ +/* + * ============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.client; + +import org.onap.cps.ncmp.dmi.config.DmiConfiguration.SdncProperties; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class SdncRestconfClient { + private SdncProperties sdncProperties; + private RestTemplate restTemplate; + + public SdncRestconfClient(final SdncProperties sdncProperties, final RestTemplate restTemplate) { + this.sdncProperties = sdncProperties; + this.restTemplate = restTemplate; + } + + /** + * restconf get operation on sdnc. + * + * @param getResourceUrl sdnc get url + * + * @return the response entity + */ + public ResponseEntity getOperation(final String getResourceUrl) { + final String sdncBaseUrl = sdncProperties.getBaseUrl(); + final String sdncRestconfUrl = sdncBaseUrl.concat(getResourceUrl); + 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); + } +} 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 new file mode 100644 index 00000000..4e4e7217 --- /dev/null +++ b/src/main/java/org/onap/cps/ncmp/dmi/service/operation/SdncOperations.java @@ -0,0 +1,75 @@ +/* + * ============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.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; +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 MOUNT_URL_TEMPLATE = "/node={nodeId}/yang-ext:mount"; + private static final String GET_SCHEMA_URL = "/ietf-netconf-monitoring:netconf-state/schemas"; + + private SdncProperties sdncProperties; + private SdncRestconfClient sdncRestconfClient; + private final String topologyUrl; + private final String topologyMountUrlTemplate; + + /** + * Constructor for {@code SdncOperations}. This method also manipulates + * url properties. + * + * @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; + } + + /** + * This method fetches list of modules usind sdnc client. + * + * @param nodeId node id for node + * @return returns {@code ResponseEntity} which contains list of modules + */ + public ResponseEntity getModulesFromNode(final String nodeId) { + final String urlWithNodeId = prepareGetSchemaUrl(nodeId); + return sdncRestconfClient.getOperation(urlWithNodeId); + } + + @NotNull + private String prepareGetSchemaUrl(final String nodeId) { + final String topologyMountUrl = topologyMountUrlTemplate; + final String topologyMountUrlWithNodeId = topologyMountUrl.replace("{nodeId}", nodeId); + final String resourceUrl = topologyMountUrlWithNodeId.concat(GET_SCHEMA_URL); + return resourceUrl; + } +} -- cgit 1.2.3-korg