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=45c7c33fd2691dafb84d9a61118b8b36ceb4ef8e;hb=ea7d1b448699d890d15fd37c69d4705a094a1b53;hp=ccb1e9bbb81bf757032a8952d4ba0e8683a13704;hpb=1410509e33142c0c79ff0e111c63abc47f5936d3;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 ccb1e9bbb..45c7c33fd 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,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021 highstreet technologies GmbH * Modifications Copyright (C) 2021-2022 Bell Canada * ================================================================================ @@ -23,39 +23,51 @@ package org.onap.cps.ncmp.rest.controller; -import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE; -import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE; -import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH; -import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE; +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 java.util.HashMap; +import io.micrometer.core.annotation.Timed; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.UUID; import java.util.stream.Collectors; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; -import org.onap.cps.ncmp.api.impl.exception.InvalidTopicException; +import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig; +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.CmResourceAddress; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; -import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor; -import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper; +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.utils.CpsValidator; +import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.utils.JsonObjectMapper; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Qualifier; 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; @@ -66,141 +78,176 @@ import org.springframework.web.bind.annotation.RestController; public class NetworkCmProxyController implements NetworkCmProxyApi { private static final String NO_BODY = null; - private static final String NO_REQUEST_ID = null; - private static final String NO_TOPIC = null; private final NetworkCmProxyDataService networkCmProxyDataService; private final JsonObjectMapper jsonObjectMapper; - private final DeprecationHelper deprecationHelper; private final NcmpRestInputMapper ncmpRestInputMapper; - private final RestOutputCmHandleStateMapper restOutputCmHandleStateMapper; - private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor; - - @Value("${notification.async.executor.time-out-value-in-ms:2000}") - private int timeOutInMilliSeconds; + private final CmHandleStateMapper cmHandleStateMapper; + private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler; + private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler; + private final DataOperationRequestMapper dataOperationRequestMapper; + @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE) + private final Map trustLevelPerCmHandle; /** - * Get resource data from operational datastore. + * Get resource data from datastore. * - * @param cmHandle cm handle identifier - * @param resourceIdentifier resource identifier - * @param optionsParamInQuery options query parameter - * @param topicParamInQuery topic query parameter + * @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 - public ResponseEntity getResourceDataOperationalForCmHandle(final String cmHandle, - final @NotNull @Valid String resourceIdentifier, - final @Valid String optionsParamInQuery, - final @Valid String topicParamInQuery) { - if (isValidTopic(topicParamInQuery)) { - final String requestId = UUID.randomUUID().toString(); - cpsNcmpTaskExecutor.executeTask(() -> - networkCmProxyDataService.getResourceDataOperationalForCmHandle( - cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, - requestId - ), timeOutInMilliSeconds - ); - return acknowledgeAsyncRequest(requestId); - } + @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); + final CmResourceAddress cmResourceAddress = new CmResourceAddress(datastoreName, cmHandle, resourceIdentifier); + return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, topicParamInQuery, + includeDescendants, authorization); + } - final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle( - cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID); + @Override + public ResponseEntity executeDataOperationForCmHandles(final String topicParamInQuery, + final DataOperationRequest dataOperationRequest, + final String authorization) { + return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery, + dataOperationRequestMapper.toDataOperationRequest(dataOperationRequest), authorization); + } - return ResponseEntity.ok(responseObject); + /** + * 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 + */ + + @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); } /** - * Get resource data from pass-through running datastore. + * Patch resource data from passthrough-running. * - * @param cmHandle cm handle identifier + * @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 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 - public ResponseEntity getResourceDataRunningForCmHandle(final String cmHandle, - final @NotNull @Valid String resourceIdentifier, - final @Valid String optionsParamInQuery, - final @Valid String topicParamInQuery) { - if (isValidTopic(topicParamInQuery)) { - final String resourceDataRequestId = UUID.randomUUID().toString(); - cpsNcmpTaskExecutor.executeTask(() -> - networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle( - cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, - resourceDataRequestId - ), timeOutInMilliSeconds - ); - return acknowledgeAsyncRequest(resourceDataRequestId); - } - final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle( - cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID); + @Override + public ResponseEntity patchResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, + final String resourceIdentifier, + final Object requestBody, + final String contentType, + final String authorization) { - return ResponseEntity.ok(responseObject); - } + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); - @Override - public ResponseEntity patchResourceDataRunningForCmHandle(final String resourceIdentifier, - final String cmHandle, - final Object requestBody, final String contentType) { - final Object responseObject = networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, - resourceIdentifier, PATCH, jsonObjectMapper.asJsonString(requestBody), contentType); + final Object responseObject = networkCmProxyDataService + .writeResourceDataPassThroughRunningForCmHandle( + cmHandle, resourceIdentifier, PATCH, + jsonObjectMapper.asJsonString(requestBody), contentType, authorization); return ResponseEntity.ok(responseObject); } /** * 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 cmHandle cm handle identifier - * @param requestBody the request body - * @param contentType content type of body + * @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 - public ResponseEntity createResourceDataRunningForCmHandle(final String resourceIdentifier, - final String cmHandle, final Object requestBody, final String contentType) { + 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); + resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization); return new ResponseEntity<>(HttpStatus.CREATED); } /** * 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 cmHandle cm handle identifier - * @param requestBody the request body - * @param contentType content type of the body + * @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 - public ResponseEntity updateResourceDataRunningForCmHandle(final String resourceIdentifier, + public ResponseEntity updateResourceDataRunningForCmHandle(final String datastoreName, final String cmHandle, + final String resourceIdentifier, final Object requestBody, - final String contentType) { + final String contentType, + final String authorization) { + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, - resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType); + resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Delete resource data in datastore pass-through running for a given cm-handle. + * 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 cmHandle cm handle identifier - * @param contentType content type of the body + * @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 deleteResourceDataRunningForCmHandle(final String cmHandle, + public ResponseEntity deleteResourceDataRunningForCmHandle(final String datastoreName, + final String cmHandle, final String resourceIdentifier, - final String contentType) { + final String contentType, + final String authorization) { + + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); + networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, - resourceIdentifier, DELETE, NO_BODY, contentType); + resourceIdentifier, DELETE, NO_BODY, contentType, authorization); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @@ -211,11 +258,12 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { * @return collection of cm handles */ @Override + @SuppressWarnings("deprecation") // mapOldConditionProperties method will be removed in Release 12 public ResponseEntity> searchCmHandles( final CmHandleQueryParameters cmHandleQueryParameters) { final CmHandleQueryApiParameters cmHandleQueryApiParameters = deprecationHelper.mapOldConditionProperties(cmHandleQueryParameters); - final Set cmHandles = networkCmProxyDataService + final Collection cmHandles = networkCmProxyDataService .executeCmHandleSearch(cmHandleQueryApiParameters); final List outputCmHandles = cmHandles.stream().map(this::toRestOutputCmHandle).collect(Collectors.toList()); @@ -230,15 +278,17 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { */ @Override public ResponseEntity> searchCmHandleIds( - final CmHandleQueryParameters cmHandleQueryParameters) { + final CmHandleQueryParameters cmHandleQueryParameters) { final CmHandleQueryApiParameters cmHandleQueryApiParameters = jsonObjectMapper.convertToValueType(cmHandleQueryParameters, CmHandleQueryApiParameters.class); - final Set cmHandleIds = networkCmProxyDataService.executeCmHandleIdSearch(cmHandleQueryApiParameters); + 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 */ @@ -251,20 +301,67 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { /** * Get Cm Handle Properties by Cm Handle Id. + * * @param cmHandleId cm-handle identifier - * @return cm handle and its properties + * @return cm handle properties */ @Override public ResponseEntity getCmHandlePublicPropertiesByCmHandleId( - final String cmHandleId) { + final String cmHandleId) { final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties(); cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId)); final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties = - new 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); + } + + /** + * 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 + 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. * @@ -273,38 +370,60 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { */ public ResponseEntity> getModuleReferencesByCmHandle(final String cmHandle) { final List restModuleReferences = - networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream() - .map(ncmpRestInputMapper::toRestModuleReference) - .collect(Collectors.toList()); + 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 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(restOutputCmHandleStateMapper.toRestOutputCmHandleState( + restOutputCmHandle.setState(cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason( ncmpServiceCmHandle.getCompositeState())); + if (cmHandleCurrentTrustLevel != null) { + restOutputCmHandle.setTrustLevel(cmHandleCurrentTrustLevel.toString()); + } + restOutputCmHandle.setModuleSetTag(ncmpServiceCmHandle.getModuleSetTag()); + restOutputCmHandle.setAlternateId(ncmpServiceCmHandle.getAlternateId()); + restOutputCmHandle.setDataProducerIdentifier(ncmpServiceCmHandle.getDataProducerIdentifier()); return restOutputCmHandle; } - private static boolean isValidTopic(final String topicName) { - if (topicName == null) { - return false; - } - if (CpsValidator.validateTopicName(topicName)) { - return true; + 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"); } - throw new InvalidTopicException("Topic name " + topicName + " is invalid", "invalid topic"); } - private ResponseEntity acknowledgeAsyncRequest(final String requestId) { - final Map acknowledgeData = new HashMap<>(1); - acknowledgeData.put("requestId", requestId); - return ResponseEntity.ok(acknowledgeData); + private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) { + if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) { + return ncmpCachedResourceRequestHandler; + } + return ncmpPassthroughResourceRequestHandler; } + }