/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
+ * Modifications Copyright (C) 2023 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.cps.ncmp.api.impl;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID;
import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.DMI_PROPERTY;
import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.PUBLIC_PROPERTY;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_PARENT;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP;
-import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.UPDATE;
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
import com.google.common.collect.ImmutableMap;
+import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.impl.event.NcmpEventsService;
+import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
-import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError;
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
-import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeBuilder;
-import org.onap.cps.utils.CpsValidator;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Service;
@Slf4j
@SuppressWarnings("squid:S5852")
public class NetworkCmProxyDataServicePropertyHandler {
- private static final String CM_HANDLE_XPATH_TEMPLATE = NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='%s']";
-
+ private final InventoryPersistence inventoryPersistence;
private final CpsDataService cpsDataService;
-
- private final NcmpEventsService ncmpEventsService;
+ private final JsonObjectMapper jsonObjectMapper;
+ private final CmHandleIdMapper cmHandleIdMapper;
/**
* Iterates over incoming ncmpServiceCmHandles and update the dataNodes based on the updated attributes.
final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles) {
final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>();
for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
- final String cmHandle = ncmpServiceCmHandle.getCmHandleId();
+ final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
try {
- CpsValidator.validateNameCharacters(cmHandle);
- final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandle);
- final DataNode existingCmHandleDataNode =
- cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandleXpath,
- FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
- processUpdates(existingCmHandleDataNode, ncmpServiceCmHandle);
- cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandle));
+ if (cmHandleIdMapper.isDuplicateId(ncmpServiceCmHandle.getCmHandleId(),
+ ncmpServiceCmHandle.getAlternateId())) {
+ cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createFailureResponse(cmHandleId,
+ ALTERNATE_ID_ALREADY_ASSOCIATED));
+ } else {
+ final DataNode existingCmHandleDataNode = inventoryPersistence.getCmHandleDataNode(cmHandleId)
+ .iterator().next();
+ updateAlternateId(existingCmHandleDataNode, ncmpServiceCmHandle);
+ processUpdates(existingCmHandleDataNode, ncmpServiceCmHandle);
+ cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId));
+ }
} catch (final DataNodeNotFoundException e) {
- log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
- cmHandle, e.getMessage());
- cmHandleRegistrationResponses.add(CmHandleRegistrationResponse
- .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_DOES_NOT_EXIST));
+ log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", cmHandleId, e.getMessage());
+ cmHandleRegistrationResponses.add(
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND));
} catch (final DataValidationException e) {
- log.error("Unable to update cm handle : {}, caused by : {}",
- cmHandle, e.getMessage());
+ log.error("Unable to update cm handle : {}, caused by : {}", cmHandleId, e.getMessage());
cmHandleRegistrationResponses.add(
- CmHandleRegistrationResponse.createFailureResponse(cmHandle,
- RegistrationError.CM_HANDLE_INVALID_ID));
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID));
} catch (final Exception exception) {
- log.error("Unable to update cmHandle : {} , caused by : {}",
- cmHandle, exception.getMessage());
+ log.error("Unable to update cmHandle : {} , caused by : {}", cmHandleId, exception.getMessage());
cmHandleRegistrationResponses.add(
- CmHandleRegistrationResponse.createFailureResponse(cmHandle, exception));
+ CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception));
}
}
return cmHandleRegistrationResponses;
}
+ private void updateAlternateId(final DataNode existingCmHandleDataNode,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final String newAlternateId = ncmpServiceCmHandle.getAlternateId();
+ if (cmHandleIdMapper.addMapping(ncmpServiceCmHandle.getCmHandleId(), newAlternateId)) {
+ try {
+ final YangModelCmHandle yangModelCmHandle =
+ YangDataConverter.convertCmHandleToYangModel(existingCmHandleDataNode,
+ ncmpServiceCmHandle.getCmHandleId());
+ setAndUpdateAlternateId(yangModelCmHandle, newAlternateId);
+ } catch (final Exception e) {
+ cmHandleIdMapper.removeMapping(ncmpServiceCmHandle.getCmHandleId());
+ throw e;
+ }
+ }
+ }
+
private void processUpdates(final DataNode existingCmHandleDataNode, final NcmpServiceCmHandle incomingCmHandle) {
if (!incomingCmHandle.getPublicProperties().isEmpty()) {
updateProperties(existingCmHandleDataNode, PUBLIC_PROPERTY, incomingCmHandle.getPublicProperties());
- publishLcmEventOnPublicPropertiesUpdate(incomingCmHandle.getCmHandleId());
}
if (!incomingCmHandle.getDmiProperties().isEmpty()) {
updateProperties(existingCmHandleDataNode, DMI_PROPERTY, incomingCmHandle.getDmiProperties());
if (replacementPropertyDataNodes.isEmpty()) {
removeAllProperties(existingCmHandleDataNode, propertyType);
} else {
- cpsDataService.replaceListContent(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- existingCmHandleDataNode.getXpath(), replacementPropertyDataNodes, NO_TIMESTAMP);
+ inventoryPersistence.replaceListContent(existingCmHandleDataNode.getXpath(), replacementPropertyDataNodes);
}
}
final Matcher matcher = propertyType.propertyXpathPattern.matcher(dataNode.getXpath());
if (matcher.find()) {
log.info("Deleting dataNode with xpath : [{}]", dataNode.getXpath());
- cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNode.getXpath(),
- NO_TIMESTAMP);
+ inventoryPersistence.deleteDataNode(dataNode.getXpath());
}
});
}
return new DataNodeBuilder().withXpath(xpath).withLeaves(ImmutableMap.copyOf(updatedLeaves)).build();
}
- private void publishLcmEventOnPublicPropertiesUpdate(final String cmHandleId) {
- log.debug("Publishing LCM Update event for cmHandleId : {}", cmHandleId);
- ncmpEventsService.publishNcmpEvent(cmHandleId, UPDATE);
+ private void setAndUpdateAlternateId(final YangModelCmHandle upgradedCmHandle, final String alternateId) {
+ final Map<String, Map<String, String>> dmiRegistryProperties = new HashMap<>(1);
+ final Map<String, String> cmHandleProperties = new HashMap<>(2);
+ cmHandleProperties.put("id", upgradedCmHandle.getId());
+ cmHandleProperties.put("alternate-id", alternateId);
+ dmiRegistryProperties.put("cm-handles", cmHandleProperties);
+ cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
+ jsonObjectMapper.asJsonString(dmiRegistryProperties), OffsetDateTime.now());
+ log.info("Updating alternateId for cmHandle {} with value : {})", upgradedCmHandle.getId(), alternateId);
}
enum PropertyType {