X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ncmp-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fncmp%2Fapi%2Fimpl%2FNetworkCmProxyDataServiceImpl.java;h=6a156b897218f05392817992a963ee25184aa2ee;hb=0e7970a1ec12eac0f45fa016f98148da7a2266a8;hp=5aadb3f0fe1b2c7311bae7fb07440c9f6277f458;hpb=e3f7305a421e075eef97d4eefdd590ca95a2a4f6;p=cps.git 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 5aadb3f0f..098388980 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 @@ -1,14 +1,16 @@ /* - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * Copyright (C) 2021 highstreet technologies GmbH - * Copyright (C) 2021 Nordix Foundation + * Modifications Copyright (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech + * 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,64 +23,357 @@ package org.onap.cps.ncmp.api.impl; +import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; +import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum; +import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters; + +import com.hazelcast.map.IMap; +import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsDataService; -import org.onap.cps.api.CpsQueryService; +import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; +import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler; +import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations; +import org.onap.cps.ncmp.api.impl.operations.DmiOperations; +import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; +import org.onap.cps.ncmp.api.inventory.CmHandleQueries; +import org.onap.cps.ncmp.api.inventory.CmHandleState; +import org.onap.cps.ncmp.api.inventory.CompositeState; +import org.onap.cps.ncmp.api.inventory.CompositeStateUtils; +import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; +import org.onap.cps.ncmp.api.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; +import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse; +import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError; +import org.onap.cps.ncmp.api.models.DmiPluginRegistration; +import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.spi.FetchDescendantsOption; -import org.onap.cps.spi.model.DataNode; -import org.springframework.beans.factory.annotation.Autowired; +import org.onap.cps.spi.exceptions.AlreadyDefinedExceptionBatch; +import org.onap.cps.spi.exceptions.CpsException; +import org.onap.cps.spi.exceptions.DataNodeNotFoundException; +import org.onap.cps.spi.exceptions.DataValidationException; +import org.onap.cps.spi.model.CmHandleQueryServiceParameters; +import org.onap.cps.spi.model.ModuleDefinition; +import org.onap.cps.spi.model.ModuleReference; +import org.onap.cps.utils.CpsValidator; +import org.onap.cps.utils.JsonObjectMapper; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; +@Slf4j @Service +@RequiredArgsConstructor public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService { - private static final String NF_PROXY_DATASPACE_NAME = "NFP-Operational"; + private final JsonObjectMapper jsonObjectMapper; + private final DmiDataOperations dmiDataOperations; + private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler; + private final InventoryPersistence inventoryPersistence; + private final CmHandleQueries cmHandleQueries; + private final NetworkCmProxyCmHandlerQueryService networkCmProxyCmHandlerQueryService; + private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler; + private final CpsDataService cpsDataService; + private final IMap moduleSyncStartedOnCmHandles; - @Autowired - private CpsDataService cpsDataService; + @Override + public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule( + final DmiPluginRegistration dmiPluginRegistration) { + dmiPluginRegistration.validateDmiPluginRegistration(); + final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse(); + dmiPluginRegistrationResponse.setRemovedCmHandles( + parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration.getRemovedCmHandles())); + if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) { + dmiPluginRegistrationResponse.setCreatedCmHandles( + parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration)); + } + if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) { + dmiPluginRegistrationResponse.setUpdatedCmHandles( + networkCmProxyDataServicePropertyHandler + .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles())); + } + return dmiPluginRegistrationResponse; + } - @Autowired - private CpsQueryService cpsQueryService; + @Override + public Object getResourceDataOperationalForCmHandle(final String cmHandleId, + final String resourceIdentifier, + final String optionsParamInQuery, + final String topicParamInQuery, + final String requestId) { + final ResponseEntity responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId, + resourceIdentifier, + optionsParamInQuery, + DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL, + requestId, topicParamInQuery); + return responseEntity.getBody(); + } + + @Override + public Object getResourceDataOperational(final String cmHandleId, + final String resourceIdentifier, + final FetchDescendantsOption fetchDescendantsOption) { + return cpsDataService.getDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, resourceIdentifier, + fetchDescendantsOption); + } - private String getDataspaceName() { - return NF_PROXY_DATASPACE_NAME; + @Override + public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId, + final String resourceIdentifier, + final String optionsParamInQuery, + final String topicParamInQuery, + final String requestId) { + final ResponseEntity responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId, + resourceIdentifier, + optionsParamInQuery, + DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING, + requestId, topicParamInQuery); + return responseEntity.getBody(); + } + + @Override + public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId, + final String resourceIdentifier, + final OperationEnum operation, + final String requestData, + final String dataType) { + CpsValidator.validateNameCharacters(cmHandleId); + return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, operation, + requestData, dataType); + } + + @Override + public Collection getYangResourcesModuleReferences(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId); + } + + @Override + public Collection getModuleDefinitionsByCmHandleId(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId); } + /** + * Retrieve cm handles with details for the given query parameters. + * + * @param cmHandleQueryApiParameters cm handle query parameters + * @return cm handles with details + */ @Override - public DataNode getDataNode(final String cmHandle, final String xpath, - final FetchDescendantsOption fetchDescendantsOption) { - return cpsDataService.getDataNode(getDataspaceName(), cmHandle, xpath, fetchDescendantsOption); + public Set executeCmHandleSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType( + cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class); + + validateCmHandleQueryParameters(cmHandleQueryServiceParameters); + + return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryServiceParameters); } + /** + * Retrieve cm handle ids for the given query parameters. + * + * @param cmHandleQueryApiParameters cm handle query parameters + * @return cm handle ids + */ @Override - public Collection queryDataNodes(final String cmHandle, final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { - return cpsQueryService.queryDataNodes(getDataspaceName(), cmHandle, cpsPath, fetchDescendantsOption); + public Set executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType( + cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class); + + validateCmHandleQueryParameters(cmHandleQueryServiceParameters); + + return networkCmProxyCmHandlerQueryService.queryCmHandleIds(cmHandleQueryServiceParameters); } + /** + * Set the data sync enabled flag, along with the data sync state + * based on the data sync enabled boolean for the cm handle id provided. + * + * @param cmHandleId cm handle id + * @param dataSyncEnabled data sync enabled flag + */ @Override - public void createDataNode(final String cmHandle, final String parentNodeXpath, final String jsonData) { - if (!StringUtils.hasText(parentNodeXpath) || "/".equals(parentNodeXpath)) { - cpsDataService.saveData(getDataspaceName(), cmHandle, jsonData); + public void setDataSyncEnabled(final String cmHandleId, final boolean dataSyncEnabled) { + CpsValidator.validateNameCharacters(cmHandleId); + final CompositeState compositeState = inventoryPersistence + .getCmHandleState(cmHandleId); + if (compositeState.getDataSyncEnabled().equals(dataSyncEnabled)) { + log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabled); + } else if (compositeState.getCmHandleState() != CmHandleState.READY) { + throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: " + + compositeState.getCmHandleState()); } else { - cpsDataService.saveData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores() + .getOperationalDataStore().getDataStoreSyncState(); + if (!dataSyncEnabled && dataStoreSyncState == DataStoreSyncState.SYNCHRONIZED) { + cpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, + "/netconf-state", OffsetDateTime.now()); + } + CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabled, compositeState); + inventoryPersistence.saveCmHandleState(cmHandleId, + compositeState); } } + /** + * Get all cm handle IDs by DMI plugin identifier. + * + * @param dmiPluginIdentifier DMI plugin identifier + * @return set of cm handle IDs + */ @Override - public void addListNodeElements(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.saveListNodeData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + public Set getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) { + final Set ncmpServiceCmHandles = + cmHandleQueries.getCmHandlesByDmiPluginIdentifier(dmiPluginIdentifier); + final Set cmHandleIds = new HashSet<>(ncmpServiceCmHandles.size()); + ncmpServiceCmHandles.forEach(cmHandle -> cmHandleIds.add(cmHandle.getCmHandleId())); + return cmHandleIds; } + /** + * Retrieve cm handle details for a given cm handle. + * + * @param cmHandleId cm handle identifier + * @return cm handle details + */ @Override - public void updateNodeLeaves(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.updateNodeLeaves(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle( + inventoryPersistence.getYangModelCmHandle(cmHandleId)); } + /** + * Get cm handle public properties for a given cm handle id. + * + * @param cmHandleId cm handle identifier + * @return cm handle public properties + */ @Override - public void replaceNodeTree(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.replaceNodeTree(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + public Map getCmHandlePublicProperties(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + final YangModelCmHandle yangModelCmHandle = + inventoryPersistence.getYangModelCmHandle(cmHandleId); + final List yangModelPublicProperties = yangModelCmHandle.getPublicProperties(); + final Map cmHandlePublicProperties = new HashMap<>(); + YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties); + return cmHandlePublicProperties; + } + + /** + * Get cm handle composite state for a given cm handle id. + * + * @param cmHandleId cm handle identifier + * @return cm handle state + */ + @Override + public CompositeState getCmHandleCompositeState(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState(); + } + + /** + * THis method registers a cm handle and initiates modules sync. + * + * @param dmiPluginRegistration dmi plugin registration information. + * @return cm-handle registration response for create cm-handle requests. + */ + public List parseAndCreateCmHandlesInDmiRegistrationAndSyncModules( + final DmiPluginRegistration dmiPluginRegistration) { + List cmHandleRegistrationResponses = new ArrayList<>(); + final Map cmHandleStatePerCmHandle = new HashMap<>(); + try { + dmiPluginRegistration.getCreatedCmHandles() + .forEach(cmHandle -> { + final YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle( + dmiPluginRegistration.getDmiPlugin(), + dmiPluginRegistration.getDmiDataPlugin(), + dmiPluginRegistration.getDmiModelPlugin(), + cmHandle); + cmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.ADVISED); + }); + cmHandleRegistrationResponses = registerNewCmHandles(cmHandleStatePerCmHandle); + } catch (final DataValidationException dataValidationException) { + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createFailureResponse(dmiPluginRegistration + .getCreatedCmHandles().stream() + .map(NcmpServiceCmHandle::getCmHandleId).findFirst().orElse(null), + RegistrationError.CM_HANDLE_INVALID_ID)); + } + return cmHandleRegistrationResponses; + } + + protected List parseAndRemoveCmHandlesInDmiRegistration( + final List tobeRemovedCmHandles) { + final List cmHandleRegistrationResponses = + new ArrayList<>(tobeRemovedCmHandles.size()); + for (final String cmHandleId : tobeRemovedCmHandles) { + try { + CpsValidator.validateNameCharacters(cmHandleId); + final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId); + lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle, + CmHandleState.DELETING); + deleteCmHandleFromDbAndModuleSyncMap(cmHandleId); + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)); + lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle, + CmHandleState.DELETED); + } catch (final DataNodeNotFoundException dataNodeNotFoundException) { + log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", + cmHandleId, dataNodeNotFoundException.getMessage()); + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse + .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_DOES_NOT_EXIST)); + } catch (final DataValidationException dataValidationException) { + log.error("Unable to de-register cm-handle id: {}, caused by: {}", + cmHandleId, dataValidationException.getMessage()); + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse + .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_INVALID_ID)); + } catch (final Exception exception) { + log.error("Unable to de-register cm-handle id : {} , caused by : {}", + cmHandleId, exception.getMessage()); + cmHandleRegistrationResponses.add( + CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception)); + } + } + return cmHandleRegistrationResponses; + } + + private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) { + inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId); + inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandleId + "']"); + removeDeletedCmHandleFromModuleSyncMap(cmHandleId); + } + + // CPS-1239 Robustness cleaning of in progress cache + private void removeDeletedCmHandleFromModuleSyncMap(final String deletedCmHandleId) { + if (moduleSyncStartedOnCmHandles.remove(deletedCmHandleId) != null) { + log.debug("{} removed from in progress map", deletedCmHandleId); + } + } + + private List registerNewCmHandles(final Map + cmHandleStatePerCmHandle) { + final List cmHandleIds = cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId) + .collect(Collectors.toList()); + try { + lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); + return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); + } catch (final AlreadyDefinedExceptionBatch alreadyDefinedExceptionBatch) { + return CmHandleRegistrationResponse.createFailureResponses( + alreadyDefinedExceptionBatch.getAlreadyDefinedXpaths(), + RegistrationError.CM_HANDLE_ALREADY_EXIST); + } catch (final Exception exception) { + return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception); + } } }