diff options
Diffstat (limited to 'cps-ncmp-service/src/main/java')
8 files changed, 223 insertions, 23 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java index f8d51feba8..92b1e82c3e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandlerQueryService.java @@ -21,15 +21,15 @@ package org.onap.cps.ncmp.api; import java.util.Collection; -import org.onap.cps.spi.model.CmHandleQueryParameters; +import org.onap.cps.spi.model.CmHandleQueryServiceParameters; import org.onap.cps.spi.model.DataNode; public interface NetworkCmProxyCmHandlerQueryService { /** * Query and return cm handles that match the given query parameters. * - * @param cmHandleQueryParameters the cm handle query parameters + * @param cmHandleQueryServiceParameters the cm handle query parameters * @return collection of cm handles */ - Collection<DataNode> queryCmHandles(CmHandleQueryParameters cmHandleQueryParameters); + Collection<DataNode> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java index ef6e953e2f..00cbe69f54 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandlerQueryServiceImpl.java @@ -37,7 +37,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService; import org.onap.cps.spi.CpsAdminPersistenceService; import org.onap.cps.spi.CpsDataPersistenceService; import org.onap.cps.spi.model.Anchor; -import org.onap.cps.spi.model.CmHandleQueryParameters; +import org.onap.cps.spi.model.CmHandleQueryServiceParameters; import org.onap.cps.spi.model.ConditionProperties; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DataNodeIdentifier; @@ -58,23 +58,23 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm /** * Query and return cm handles that match the given query parameters. * - * @param cmHandleQueryParameters the cm handle query parameters + * @param cmHandleQueryServiceParameters the cm handle query parameters * @return collection of cm handles */ @Override - public Collection<DataNode> queryCmHandles(final CmHandleQueryParameters cmHandleQueryParameters) { + public Collection<DataNode> queryCmHandles(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) { - if (cmHandleQueryParameters.getCmHandleQueryParameters().isEmpty()) { + if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) { return getAllCmHandles(); } final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers = new ArrayList<>(); final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults = new HashMap<>(); - final boolean firstQuery = moduleNameQuery(cmHandleQueryParameters, + final boolean firstQuery = moduleNameQuery(cmHandleQueryServiceParameters, amalgamatedQueryResultIdentifiers, amalgamatedQueryResults); - publicPropertyQuery(cmHandleQueryParameters, amalgamatedQueryResultIdentifiers, + publicPropertyQuery(cmHandleQueryServiceParameters, amalgamatedQueryResultIdentifiers, amalgamatedQueryResults, firstQuery); final Collection<DataNode> filteredDataNodes = new ArrayList<>(); @@ -85,12 +85,12 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm return filteredDataNodes; } - private void publicPropertyQuery(final CmHandleQueryParameters cmHandleQueryParameters, + private void publicPropertyQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers, final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults, boolean firstQuery) { for (final Map.Entry<String, String> entry : - getPublicPropertyPairs(cmHandleQueryParameters.getCmHandleQueryParameters()).entrySet()) { + getPublicPropertyPairs(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).entrySet()) { final String cmHandlePath = "//public-properties[@name='" + entry.getKey() + "' " + "and @value='" + entry.getValue() + "']" + "/ancestor::cm-handles"; @@ -121,13 +121,13 @@ public class NetworkCmProxyCmHandlerQueryServiceImpl implements NetworkCmProxyCm } } - private boolean moduleNameQuery(final CmHandleQueryParameters cmHandleQueryParameters, + private boolean moduleNameQuery(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final Collection<DataNodeIdentifier> amalgamatedQueryResultIdentifiers, final Map<DataNodeIdentifier, DataNode> amalgamatedQueryResults) { boolean firstQuery = true; - if (!getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters()).isEmpty()) { + if (!getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters()).isEmpty()) { final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors("NFP-Operational", - getModuleNames(cmHandleQueryParameters.getCmHandleQueryParameters())); + getModuleNames(cmHandleQueryServiceParameters.getCmHandleQueryParameters())); anchors.forEach(anchor -> { final List<DataNode> dataNodes = getDataNodes("//cm-handles[@id='" + anchor.getName() + "']"); dataNodes.parallelStream().forEach(dataNode -> { 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 d1f72a5ef4..f8cab4f1ca 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 @@ -63,7 +63,7 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException; import org.onap.cps.spi.exceptions.DataNodeNotFoundException; import org.onap.cps.spi.exceptions.DataValidationException; import org.onap.cps.spi.exceptions.SchemaSetNotFoundException; -import org.onap.cps.spi.model.CmHandleQueryParameters; +import org.onap.cps.spi.model.CmHandleQueryServiceParameters; import org.onap.cps.spi.model.ModuleReference; import org.onap.cps.utils.CpsValidator; import org.onap.cps.utils.JsonObjectMapper; @@ -167,12 +167,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService @Override public Set<NcmpServiceCmHandle> executeCmHandleSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { - final CmHandleQueryParameters cmHandleQueryParameters = jsonObjectMapper.convertToValueType( - cmHandleQueryApiParameters, CmHandleQueryParameters.class); + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType( + cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class); - validateCmHandleQueryParameters(cmHandleQueryParameters); + validateCmHandleQueryParameters(cmHandleQueryServiceParameters); - return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryParameters).stream() + return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryServiceParameters).stream() .map(dataNode -> YangDataConverter .convertCmHandleToYangModel(dataNode, dataNode.getLeaves().get("id").toString())) .map(YangDataConverter::convertYangModelCmHandleToNcmpServiceCmHandle).collect(Collectors.toSet()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java new file mode 100644 index 0000000000..609306f08e --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCreator.java @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.api.impl.event; + +import static org.onap.ncmp.cmhandle.lcm.event.Event.CmhandleState.READY; +import static org.onap.ncmp.cmhandle.lcm.event.Event.Operation.DELETE; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; +import org.onap.ncmp.cmhandle.lcm.event.Event; +import org.onap.ncmp.cmhandle.lcm.event.Event.Operation; +import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.springframework.stereotype.Component; + + +/** + * NcmpEventsCreator to create NcmpEvent based on relevant operation. + */ +@Slf4j +@Component +public class NcmpEventsCreator { + + + /** + * Populate NcmpEvent. + * + * @param cmHandleId Cm Handle Identifier + * @param operation Relevant Operation + * @param ncmpServiceCmHandle Ncmp CmHandle Data + * @return Populated NcmpEvent + */ + public NcmpEvent populateNcmpEvent(final String cmHandleId, final Operation operation, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + return createNcmpEvent(cmHandleId, operation, ncmpServiceCmHandle); + } + + private NcmpEvent createNcmpEvent(final String cmHandleId, final Operation operation, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + final NcmpEvent ncmpEvent = ncmpEventHeader(cmHandleId); + ncmpEvent.setEvent(ncmpEventPayload(cmHandleId, operation, ncmpServiceCmHandle)); + return ncmpEvent; + } + + private Event ncmpEventPayload(final String eventCorrelationId, final Operation operation, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + final Event event = new Event(); + event.setOperation(operation); + event.setCmHandleId(eventCorrelationId); + + if (!DELETE.equals(operation)) { + event.setCmhandleState(READY); + event.setCmhandleProperties(List.of(ncmpServiceCmHandle.getPublicProperties())); + } + return event; + } + + private NcmpEvent ncmpEventHeader(final String eventCorrelationId) { + final NcmpEvent ncmpEvent = new NcmpEvent(); + ncmpEvent.setEventId(UUID.randomUUID().toString()); + ncmpEvent.setEventCorrelationId(eventCorrelationId); + ncmpEvent.setEventTime(ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))); + ncmpEvent.setEventSource("org.onap.ncmp"); + ncmpEvent.setEventType("org.onap.ncmp.cmhandle-lcm-event"); + ncmpEvent.setEventSchema("org.onap.ncmp:cmhandle-lcm-event:v1"); + return ncmpEvent; + } + +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java new file mode 100644 index 0000000000..045a67a104 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.api.impl.event; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; +import org.onap.cps.ncmp.api.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; +import org.onap.ncmp.cmhandle.lcm.event.Event.Operation; +import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * NcmpEventService to map the event correctly and publish to the public topic. + */ + +@Slf4j +@Service +@RequiredArgsConstructor +public class NcmpEventsService { + + private final InventoryPersistence inventoryPersistence; + + private final NcmpEventsPublisher ncmpEventsPublisher; + + private final NcmpEventsCreator ncmpEventsCreator; + + @Value("${app.ncmp.events.topic:ncmp-events}") + private String topicName; + + /** + * Publish the NcmpEvent to the public topic. + * + * @param cmHandleId Cm Handle Id + * @param operation Relevant operation(CREATE,UPDATE or DELETE) + */ + public void publishNcmpEvent(final String cmHandleId, final Operation operation) { + + final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle( + inventoryPersistence.getYangModelCmHandle(cmHandleId)); + final NcmpEvent ncmpEvent = ncmpEventsCreator.populateNcmpEvent(cmHandleId, operation, ncmpServiceCmHandle); + ncmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent); + + } +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java index 2fc2dc5c1a..ce34154b9b 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 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. @@ -92,6 +93,17 @@ public class InventoryPersistence { } /** + * Method to return cm handles from the cps path. + * + * @param cpsPath cps path for which the cmHandle is requested + * @return a list of cm handles + */ + public List<DataNode> getCmHandlesByCpsPath(final String cpsPath) { + return cpsDataPersistenceService.queryDataNodes( + NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, FetchDescendantsOption.OMIT_DESCENDANTS); + } + + /** * This method retrieves DMI service name, DMI properties and the state for a given cm handle. * @param cmHandleId the id of the cm handle * @return yang model cm handle diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java index bcc7daa39d..dbc7dd4f2c 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java @@ -1,6 +1,7 @@ /* - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 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. @@ -20,11 +21,13 @@ package org.onap.cps.ncmp.api.inventory.sync; +import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.inventory.CmHandleState; import org.onap.cps.ncmp.api.inventory.CompositeState; +import org.onap.cps.ncmp.api.inventory.CompositeState.LockReason; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.inventory.LockReasonCategory; import org.springframework.scheduling.annotation.Scheduled; @@ -44,7 +47,7 @@ public class ModuleSyncWatchdog { /** * Execute Cm Handle poll which changes the cm handle state from 'ADVISED' to 'READY'. */ - @Scheduled(fixedDelayString = "${timers.advised-modules-sync.sleep-time-ms}") + @Scheduled(fixedDelayString = "${timers.advised-modules-sync.sleep-time-ms:30000}") public void executeAdvisedCmHandlePoll() { YangModelCmHandle advisedCmHandle = syncUtils.getAnAdvisedCmHandle(); while (advisedCmHandle != null) { @@ -68,4 +71,20 @@ public class ModuleSyncWatchdog { log.debug("No Cm-Handles currently found in an ADVISED state"); } + /** + * Execute Cm Handle poll which changes the cm handle state from 'LOCKED' to 'ADVISED'. + */ + @Scheduled(fixedDelayString = "${timers.locked-modules-sync.sleep-time-ms:300000}") + public void executeLockedMisbehavingCmHandlePoll() { + final List<YangModelCmHandle> lockedMisbehavingCmHandles = syncUtils.getLockedMisbehavingCmHandles(); + for (final YangModelCmHandle lockedMisbehavingModelCmHandle: lockedMisbehavingCmHandles) { + final CompositeState updatedCompositeState = lockedMisbehavingModelCmHandle.getCompositeState(); + updatedCompositeState.setCmHandleState(CmHandleState.ADVISED); + updatedCompositeState.setLastUpdateTimeNow(); + updatedCompositeState.setLockReason(LockReason.builder() + .details(updatedCompositeState.getLockReason().getDetails()).build()); + log.debug("Locked misbehaving cm handle {} is being recycled", lockedMisbehavingModelCmHandle.getId()); + inventoryPersistence.saveCmHandleState(lockedMisbehavingModelCmHandle.getId(), updatedCompositeState); + } + } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java index a4f29de3e8..22eeabb0df 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Nordix Foundation + * Modifications Copyright (C) 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. @@ -24,8 +25,10 @@ import java.security.SecureRandom; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +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.CmHandleState; import org.onap.cps.ncmp.api.inventory.CompositeState; @@ -41,7 +44,6 @@ public class SyncUtils { private static final SecureRandom secureRandom = new SecureRandom(); - private final InventoryPersistence inventoryPersistence; private static final Pattern retryAttemptPattern = Pattern.compile("^Attempt #(\\d+) failed:"); @@ -64,6 +66,19 @@ public class SyncUtils { /** + * Query data nodes for cm handles with an "LOCKED" cm handle state with reason LOCKED_MISBEHAVING". + * + * @return a random yang model cm handle with an ADVISED state, return null if not found + */ + public List<YangModelCmHandle> getLockedMisbehavingCmHandles() { + final List<DataNode> lockedCmHandleAsDataNodeList = inventoryPersistence.getCmHandlesByCpsPath( + "//lock-reason[@reason=\"LOCKED_MISBEHAVING\"]/ancestor::cm-handles"); + return lockedCmHandleAsDataNodeList.stream() + .map(cmHandle -> YangDataConverter.convertCmHandleToYangModel(cmHandle, + cmHandle.getLeaves().get("id").toString())).collect(Collectors.toList()); + } + + /** * Update Composite State attempts counter and set new lock reason and details. * * @param lockReasonCategory lock reason category @@ -84,5 +99,4 @@ public class SyncUtils { .lockReasonCategory(lockReasonCategory).build()); } - } |