X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ncmp-rest%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fncmp%2Frest%2Fcontroller%2FNetworkCmProxyController.java;h=01b892218d92746ea7e5041a9cd5dc19b746e20a;hb=0a1b4b12b6c2809d30c4bb1f3e862c855f21a316;hp=3d771b6c511106b87519b66f00fc178f45775cb3;hpb=2ff8b7c6c11e56f6104ed529cc858f5fc128ea25;p=cps.git diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java index 3d771b6c5..b567ba2e7 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java @@ -1,14 +1,16 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Modifications (C) 2021 Nordix Foundation - * Modification Copyright (C) 2021 highstreet technologies GmbH + * Modifications Copyright (C) 2021-2024 Nordix Foundation + * Modifications Copyright (C) 2021 highstreet technologies GmbH + * Modifications Copyright (C) 2021-2022 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. @@ -21,140 +23,399 @@ package org.onap.cps.ncmp.rest.controller; +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL; +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import io.micrometer.core.annotation.Timed; +import java.util.ArrayList; import java.util.Collection; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; -import org.onap.cps.ncmp.api.models.DmiPluginRegistration; +import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState; +import org.onap.cps.ncmp.api.impl.operations.DatastoreType; +import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel; +import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; -import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration; -import org.onap.cps.spi.FetchDescendantsOption; -import org.onap.cps.spi.model.DataNode; -import org.onap.cps.utils.DataMapUtils; +import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler; +import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreRequestHandler; +import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler; +import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper; +import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper; +import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; +import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; +import org.onap.cps.ncmp.rest.model.DataOperationRequest; +import org.onap.cps.ncmp.rest.model.RestModuleDefinition; +import org.onap.cps.ncmp.rest.model.RestModuleReference; +import org.onap.cps.ncmp.rest.model.RestOutputCmHandle; +import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState; +import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties; +import org.onap.cps.ncmp.rest.util.DeprecationHelper; +import org.onap.cps.spi.model.ModuleDefinition; +import org.onap.cps.utils.JsonObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Slf4j @RestController @RequestMapping("${rest.api.ncmp-base-path}") +@RequiredArgsConstructor public class NetworkCmProxyController implements NetworkCmProxyApi { - private static final Gson GSON = new GsonBuilder().create(); - + private static final String NO_BODY = null; private final NetworkCmProxyDataService networkCmProxyDataService; + private final JsonObjectMapper jsonObjectMapper; + private final DeprecationHelper deprecationHelper; + private final NcmpRestInputMapper ncmpRestInputMapper; + private final CmHandleStateMapper cmHandleStateMapper; + private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler; + private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler; + private final DataOperationRequestMapper dataOperationRequestMapper; + private final Map trustLevelPerCmHandle; + + /** + * Get resource data from datastore. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param resourceIdentifier resource identifier + * @param optionsParamInQuery options query parameter + * @param topicParamInQuery topic query parameter + * @param includeDescendants whether to include descendants or not + * @param authorization contents of Authorization header, or null if not present + * @return {@code ResponseEntity} response from dmi plugin + */ + @Override + @Timed(value = "cps.ncmp.controller.get", description = "Time taken to get resource data from datastore") + public ResponseEntity getResourceDataForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final String optionsParamInQuery, + final String topicParamInQuery, + final Boolean includeDescendants, + final String authorization) { + final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName); + return ncmpDatastoreRequestHandler.executeRequest(datastoreName, cmHandle, resourceIdentifier, + optionsParamInQuery, topicParamInQuery, includeDescendants, authorization); + } - private final ObjectMapper objectMapper; + @Override + public ResponseEntity executeDataOperationForCmHandles(final String topicParamInQuery, + final DataOperationRequest dataOperationRequest, + final String authorization) { + return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery, + dataOperationRequestMapper.toDataOperationRequest(dataOperationRequest), authorization); + } /** - * Constructor Injection for Dependencies. - * @param networkCmProxyDataService Data Service Interface - * @param objectMapper Object Mapper + * Query resource data from datastore. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param cpsPath CPS Path + * @param optionsParamInQuery options query parameter + * @param topicParamInQuery topic query parameter + * @param includeDescendants whether to include descendants or not + * @return {@code ResponseEntity} response from dmi plugin */ - public NetworkCmProxyController(final NetworkCmProxyDataService networkCmProxyDataService, - final ObjectMapper objectMapper) { - this.networkCmProxyDataService = networkCmProxyDataService; - this.objectMapper = objectMapper; + + @Override + public ResponseEntity queryResourceDataForCmHandle(final String datastoreName, + final String cmHandle, + final String cpsPath, + final String optionsParamInQuery, + final String topicParamInQuery, + final Boolean includeDescendants) { + validateDataStore(OPERATIONAL, datastoreName); + return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants); } /** - * Create Node. - * @deprecated This Method is no longer used as part of NCMP. + * Patch resource data from passthrough-running. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param resourceIdentifier resource identifier + * @param requestBody the request body + * @param contentType content type of body + * @param authorization contents of Authorization header, or null if not present + * @return {@code ResponseEntity} response from dmi plugin */ + @Override - @Deprecated(forRemoval = false) - public ResponseEntity createNode(final String cmHandle, @Valid final String jsonData, - @Valid final String parentNodeXpath) { - networkCmProxyDataService.createDataNode(cmHandle, parentNodeXpath, jsonData); - return new ResponseEntity<>(HttpStatus.CREATED); + public ResponseEntity patchResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final Object requestBody, + final String contentType, + final String authorization) { + + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + + final Object responseObject = networkCmProxyDataService + .writeResourceDataPassThroughRunningForCmHandle( + cmHandle, resourceIdentifier, PATCH, + jsonObjectMapper.asJsonString(requestBody), contentType, authorization); + return ResponseEntity.ok(responseObject); } /** - * Add List-node Child Element. - * @deprecated This Method is no longer used as part of NCMP. + * Create resource data in datastore pass-through running for given cm-handle. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param resourceIdentifier resource identifier + * @param requestBody the request body + * @param contentType content type of body + * @param authorization contents of Authorization header, or null if not present + * @return {@code ResponseEntity} response from dmi plugin */ @Override - @Deprecated(forRemoval = false) - public ResponseEntity addListNodeElements(@NotNull @Valid final String parentNodeXpath, - final String cmHandle, @Valid final String jsonData) { - networkCmProxyDataService.addListNodeElements(cmHandle, parentNodeXpath, jsonData); + public ResponseEntity createResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final Object requestBody, + final String contentType, + final String authorization) { + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + + networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, + resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization); return new ResponseEntity<>(HttpStatus.CREATED); } /** - * Get Node By CM Handle and X-Path. - * @deprecated This Method is no longer used as part of NCMP. + * Update resource data in datastore pass-through running for given cm-handle. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param resourceIdentifier resource identifier + * @param requestBody the request body + * @param contentType content type of the body + * @param authorization contents of Authorization header, or null if not present + * @return response entity */ + @Override - @Deprecated(forRemoval = false) - public ResponseEntity getNodeByCmHandleAndXpath(final String cmHandle, @Valid final String xpath, - @Valid final Boolean includeDescendants) { - final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants) - ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS; - final var dataNode = networkCmProxyDataService.getDataNode(cmHandle, xpath, fetchDescendantsOption); - return new ResponseEntity<>(DataMapUtils.toDataMap(dataNode), HttpStatus.OK); + public ResponseEntity updateResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final Object requestBody, + final String contentType, + final String authorization) { + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + + networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, + resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization); + return new ResponseEntity<>(HttpStatus.OK); } /** - * Update DMI Plugin Registration (used for first registration also). - * @param restDmiPluginRegistration the registration data + * Delete resource data in datastore pass-through running for a given cm-handle. + * + * @param datastoreName name of the datastore + * @param cmHandle cm handle identifier + * @param resourceIdentifier resource identifier + * @param contentType content type of the body + * @param authorization contents of Authorization header, or null if not present + * @return response entity no content if request is successful */ @Override - public ResponseEntity updateDmiPluginRegistration( - final @Valid RestDmiPluginRegistration restDmiPluginRegistration) { - final DmiPluginRegistration dmiPluginRegistration = - convertRestObjectToJavaApiObject(restDmiPluginRegistration); - networkCmProxyDataService.updateDmiPluginRegistration(dmiPluginRegistration); - return new ResponseEntity<>(HttpStatus.CREATED); + public ResponseEntity deleteResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final String contentType, + final String authorization) { + + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + + networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, + resourceIdentifier, DELETE, NO_BODY, contentType, authorization); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } /** - * Query Data Nodes. - * @deprecated This Method is no longer used as part of NCMP. + * Query and return cm handles that match the given query parameters. + * + * @param cmHandleQueryParameters the cm handle query parameters + * @return collection of cm handles */ @Override - @Deprecated(forRemoval = false) - public ResponseEntity queryNodesByCmHandleAndCpsPath(final String cmHandle, @Valid final String cpsPath, - @Valid final Boolean includeDescendants) { - final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants) - ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS; - final Collection dataNodes = - networkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption); - return new ResponseEntity<>(GSON.toJson(dataNodes), HttpStatus.OK); + @SuppressWarnings("deprecation") // mapOldConditionProperties method will be removed in Release 12 + public ResponseEntity> searchCmHandles( + final CmHandleQueryParameters cmHandleQueryParameters) { + final CmHandleQueryApiParameters cmHandleQueryApiParameters = + deprecationHelper.mapOldConditionProperties(cmHandleQueryParameters); + final Collection cmHandles = networkCmProxyDataService + .executeCmHandleSearch(cmHandleQueryApiParameters); + final List outputCmHandles = + cmHandles.stream().map(this::toRestOutputCmHandle).collect(Collectors.toList()); + return ResponseEntity.ok(outputCmHandles); } /** - * Replace Node With Descendants. - * @deprecated This Method is no longer used as part of NCMP. + * Query and return cm handle ids that match the given query parameters. + * + * @param cmHandleQueryParameters the cm handle query parameters + * @return collection of cm handle ids */ @Override - @Deprecated(forRemoval = false) - public ResponseEntity replaceNode(final String cmHandle, @Valid final String jsonData, - @Valid final String parentNodeXpath) { - networkCmProxyDataService.replaceNodeTree(cmHandle, parentNodeXpath, jsonData); - return new ResponseEntity<>(HttpStatus.OK); + public ResponseEntity> searchCmHandleIds( + final CmHandleQueryParameters cmHandleQueryParameters) { + final CmHandleQueryApiParameters cmHandleQueryApiParameters = + jsonObjectMapper.convertToValueType(cmHandleQueryParameters, CmHandleQueryApiParameters.class); + final Collection cmHandleIds + = networkCmProxyDataService.executeCmHandleIdSearch(cmHandleQueryApiParameters); + return ResponseEntity.ok(List.copyOf(cmHandleIds)); + } + + /** + * Search for Cm Handle and Properties by Name. + * + * @param cmHandleId cm-handle identifier + * @return cm handle and its properties + */ + @Override + public ResponseEntity retrieveCmHandleDetailsById(final String cmHandleId) { + final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId); + final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle); + return ResponseEntity.ok(restOutputCmHandle); + } + + /** + * Get Cm Handle Properties by Cm Handle Id. + * + * @param cmHandleId cm-handle identifier + * @return cm handle properties + */ + @Override + public ResponseEntity getCmHandlePublicPropertiesByCmHandleId( + final String cmHandleId) { + final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties(); + cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId)); + final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties = + new RestOutputCmHandlePublicProperties(); + restOutputCmHandlePublicProperties.setPublicCmHandleProperties(cmHandlePublicProperties); + return ResponseEntity.ok(restOutputCmHandlePublicProperties); + } + + /** + * Get Cm Handle State by Cm Handle Id. + * + * @param cmHandleId cm-handle identifier + * @return cm handle state + */ + @Override + public ResponseEntity getCmHandleStateByCmHandleId( + final String cmHandleId) { + final CompositeState cmHandleState = networkCmProxyDataService.getCmHandleCompositeState(cmHandleId); + final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState = + new RestOutputCmHandleCompositeState(); + restOutputCmHandleCompositeState.setState( + cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason(cmHandleState)); + return ResponseEntity.ok(restOutputCmHandleCompositeState); } /** - * Update Node Leaves. - * @deprecated This Method is no longer used as part of NCMP. + * Return module definitions. + * + * @param cmHandleId cm-handle identifier + * @param moduleName module name + * @param revision the revision of the module + * @return list of module definitions (module name, revision, yang resource content) */ @Override - @Deprecated(forRemoval = false) - public ResponseEntity updateNodeLeaves(final String cmHandle, @Valid final String jsonData, - @Valid final String parentNodeXpath) { - networkCmProxyDataService.updateNodeLeaves(cmHandle, parentNodeXpath, jsonData); + public ResponseEntity> getModuleDefinitions(final String cmHandleId, + final String moduleName, + final String revision) { + final Collection moduleDefinitions; + if (StringUtils.hasText(moduleName)) { + moduleDefinitions = + networkCmProxyDataService.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, revision); + } else { + moduleDefinitions = networkCmProxyDataService.getModuleDefinitionsByCmHandleId(cmHandleId); + if (StringUtils.hasText(revision)) { + log.warn("Ignoring revision filter as no module name is provided"); + } + } + final List response = new ArrayList<>(); + for (final ModuleDefinition moduleDefinition: moduleDefinitions) { + response.add(ncmpRestInputMapper.toRestModuleDefinition(moduleDefinition)); + } + return new ResponseEntity<>(response, HttpStatus.OK); + } + + /** + * Return module references for a cm handle. + * + * @param cmHandle the cm handle + * @return module references for cm handle. Namespace will be always blank because restConf does not include this. + */ + public ResponseEntity> getModuleReferencesByCmHandle(final String cmHandle) { + final List restModuleReferences = + networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream() + .map(ncmpRestInputMapper::toRestModuleReference) + .collect(Collectors.toList()); + return new ResponseEntity<>(restModuleReferences, HttpStatus.OK); + } + + /** + * Set the data sync enabled flag, along with the data sync state for the specified cm handle. + * + * @param cmHandleId cm handle id + * @param dataSyncEnabledFlag data sync enabled flag + * @return response entity ok if request is successful + */ + @Override + public ResponseEntity setDataSyncEnabledFlagForCmHandle(final String cmHandleId, + final Boolean dataSyncEnabledFlag) { + networkCmProxyDataService.setDataSyncEnabled(cmHandleId, dataSyncEnabledFlag); return new ResponseEntity<>(HttpStatus.OK); } - private DmiPluginRegistration convertRestObjectToJavaApiObject( - final RestDmiPluginRegistration restDmiPluginRegistration) { - return objectMapper.convertValue(restDmiPluginRegistration, DmiPluginRegistration.class); + private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) { + final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle(); + final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties(); + final TrustLevel cmHandleCurrentTrustLevel = trustLevelPerCmHandle.get(ncmpServiceCmHandle.getCmHandleId()); + restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleId()); + cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties()); + restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties); + restOutputCmHandle.setState(cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason( + ncmpServiceCmHandle.getCompositeState())); + if (cmHandleCurrentTrustLevel != null) { + restOutputCmHandle.setTrustLevel(cmHandleCurrentTrustLevel.toString()); + } + return restOutputCmHandle; } + private void validateDataStore(final DatastoreType acceptableDataStoreType, final String requestedDatastoreName) { + final DatastoreType datastoreType = DatastoreType.fromDatastoreName(requestedDatastoreName); + + if (acceptableDataStoreType != datastoreType) { + throw new InvalidDatastoreException(requestedDatastoreName + " is not supported"); + } + } + + private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) { + if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) { + return ncmpCachedResourceRequestHandler; + } + return ncmpPassthroughResourceRequestHandler; + } + + } +