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;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService;
import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>();
try {
cmHandleRegistrationResponses = dmiPluginRegistration.getCreatedCmHandles().stream()
- .map(cmHandle ->
- YangModelCmHandle.toYangModelCmHandle(
+ .map(cmHandle -> {
+ setCompositeStateToAdvised(cmHandle);
+ return YangModelCmHandle.toYangModelCmHandle(
dmiPluginRegistration.getDmiPlugin(),
dmiPluginRegistration.getDmiDataPlugin(),
dmiPluginRegistration.getDmiModelPlugin(),
- CmHandleState.ADVISED,
- cmHandle)
+ cmHandle);
+ }
)
.map(this::registerNewCmHandle)
.collect(Collectors.toList());
return cmHandleRegistrationResponses;
}
+ private void setCompositeStateToAdvised(final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final CompositeState compositeState = new CompositeState();
+ compositeState.setCmHandleState(CmHandleState.ADVISED);
+ compositeState.setLastUpdateTimeNow();
+ ncmpServiceCmHandle.setCompositeState(compositeState);
+ }
+
protected List<CmHandleRegistrationResponse> parseAndRemoveCmHandlesInDmiRegistration(
final List<String> tobeRemovedCmHandles) {
final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
(String) cmHandleDataNode.getLeaves().get("dmi-service-name"),
(String) cmHandleDataNode.getLeaves().get("dmi-data-service-name"),
(String) cmHandleDataNode.getLeaves().get("dmi-model-service-name"),
- ncmpServiceCmHandle.getCompositeState().getCmHandleState(),
- ncmpServiceCmHandle
+ ncmpServiceCmHandle
);
}
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
-import org.onap.cps.ncmp.api.inventory.CmHandleState;
import org.onap.cps.ncmp.api.inventory.CompositeState;
-import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder;
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.utils.CpsValidator;
@JsonProperty("public-properties")
private List<Property> publicProperties;
- private static final CompositeStateBuilder compositeStateBuilder = new CompositeStateBuilder();
-
/**
* Create a yangModelCmHandle.
*
public static YangModelCmHandle toYangModelCmHandle(final String dmiServiceName,
final String dmiDataServiceName,
final String dmiModelServiceName,
- final CmHandleState cmHandleState,
final NcmpServiceCmHandle ncmpServiceCmHandle) {
CpsValidator.validateNameCharacters(ncmpServiceCmHandle.getCmHandleId());
final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle();
yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
ncmpServiceCmHandle.getPublicProperties()));
- compositeStateBuilder.withCmHandleState(cmHandleState);
- yangModelCmHandle.setCompositeState(compositeStateBuilder.build());
+ yangModelCmHandle.setCompositeState(ncmpServiceCmHandle.getCompositeState());
return yangModelCmHandle;
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Bell Canada
- * Copyright (C) 2022 Nordix Foundation.
+ * Modifications 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.
.get("cm-handle-state"));
for (final DataNode stateChildNode : dataNode.getChildDataNodes()) {
if (stateChildNode.getXpath().endsWith("/lock-reason")) {
- this.lockReason = new LockReason(LockReasonCategory.valueOf(
- (String) stateChildNode.getLeaves().get("reason")),
- (String) stateChildNode.getLeaves().get("details"));
+ this.lockReason = getLockReason(stateChildNode);
}
if (stateChildNode.getXpath().endsWith("/datastores")) {
for (final DataNode dataStoreNodes : stateChildNode.getChildDataNodes()) {
Operational operationalDataStore = null;
if (dataStoreNodes.getXpath().contains("/operational")) {
- operationalDataStore = Operational.builder()
- .syncState(SyncState.valueOf((String) dataStoreNodes.getLeaves().get("sync-state")))
- .lastSyncTime((String) dataStoreNodes.getLeaves().get("last-sync-time"))
- .build();
+ operationalDataStore = getOperationalDataStore(dataStoreNodes);
}
this.datastores = DataStores.builder().operationalDataStore(operationalDataStore).build();
}
return this;
}
+ private Operational getOperationalDataStore(final DataNode dataStoreNodes) {
+ return Operational.builder()
+ .syncState(SyncState.valueOf((String) dataStoreNodes.getLeaves().get("sync-state")))
+ .lastSyncTime((String) dataStoreNodes.getLeaves().get("last-sync-time"))
+ .build();
+ }
+
+ private LockReason getLockReason(final DataNode stateChildNode) {
+ final boolean isLockReasonExists = stateChildNode.getLeaves().containsKey("reason");
+ return new LockReason(isLockReasonExists
+ ? LockReasonCategory.valueOf((String) stateChildNode.getLeaves().get("reason"))
+ : null, (String) stateChildNode.getLeaves().get("details"));
+ }
+
}
*/
public CompositeState getCmHandleState(final String cmHandleId) {
final DataNode stateAsDataNode = cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
- String.format(XPATH_TO_CM_HANDLE, cmHandleId) + "/state",
+ String.format(XPATH_TO_CM_HANDLE, cmHandleId) + "/state",
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
return compositeStateBuilder.fromDataNode(stateAsDataNode).build();
}
* Method to return data nodes representing the cm handles.
*
* @param cpsPath cps path for which the cmHandle is requested
+ * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes
* @return a list of data nodes representing the cm handles.
*/
- public List<DataNode> getCmHandleDataNodesByCpsPath(final String cpsPath) {
+ public List<DataNode> getCmHandleDataNodesByCpsPath(final String cpsPath,
+ final FetchDescendantsOption fetchDescendantsOption) {
return cpsDataPersistenceService.queryDataNodes(
- NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, FetchDescendantsOption.OMIT_DESCENDANTS);
+ NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, fetchDescendantsOption);
}
/**
*/
public List<DataNode> getCmHandlesByIdAndState(final String cmHandleId, final CmHandleState cmHandleState) {
return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME,
- NCMP_DMI_REGISTRY_ANCHOR, "//cm-handles[@id='" + cmHandleId + "']/state[@cm-handle-state=\""
- + cmHandleState + "\"]/ancestor::cm-handles",
- FetchDescendantsOption.OMIT_DESCENDANTS);
+ NCMP_DMI_REGISTRY_ANCHOR, "//cm-handles[@id='" + cmHandleId + "']/state[@cm-handle-state=\""
+ + cmHandleState + "\"]/ancestor::cm-handles",
+ FetchDescendantsOption.OMIT_DESCENDANTS);
}
/**
*/
public List<DataNode> getCmHandlesByOperationalSyncState(final SyncState syncState) {
return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME,
- NCMP_DMI_REGISTRY_ANCHOR, "//state/datastores"
- + "/operational[@sync-state=\"" + syncState + "\"]/ancestor::cm-handles",
- FetchDescendantsOption.OMIT_DESCENDANTS);
+ NCMP_DMI_REGISTRY_ANCHOR, "//state/datastores"
+ + "/operational[@sync-state=\"" + syncState + "\"]/ancestor::cm-handles",
+ FetchDescendantsOption.OMIT_DESCENDANTS);
}
/**
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
}
-}
+}
\ No newline at end of file
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;
@Scheduled(fixedDelayString = "${timers.locked-modules-sync.sleep-time-ms:300000}")
public void executeLockedMisbehavingCmHandlePoll() {
final List<YangModelCmHandle> lockedMisbehavingCmHandles = syncUtils.getLockedMisbehavingYangModelCmHandles();
- 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());
+ for (final YangModelCmHandle lockedMisbehavingModelCmHandle : lockedMisbehavingCmHandles) {
+ final CompositeState compositeState = lockedMisbehavingModelCmHandle.getCompositeState();
+ setCompositeStateToAdvisedAndRetainOldLockReasonDetails(compositeState);
log.debug("Locked misbehaving cm handle {} is being recycled", lockedMisbehavingModelCmHandle.getId());
- inventoryPersistence.saveCmHandleState(lockedMisbehavingModelCmHandle.getId(), updatedCompositeState);
+ inventoryPersistence.saveCmHandleState(lockedMisbehavingModelCmHandle.getId(), compositeState);
}
}
+
+ private void setCompositeStateToAdvisedAndRetainOldLockReasonDetails(final CompositeState compositeState) {
+ compositeState.setCmHandleState(CmHandleState.ADVISED);
+ compositeState.setLastUpdateTimeNow();
+ final String oldLockReasonDetails = compositeState.getLockReason().getDetails();
+ compositeState.setLockReason(CompositeState.LockReason.builder()
+ .details(oldLockReasonDetails).build());
+ }
}
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.inventory.LockReasonCategory;
import org.onap.cps.ncmp.api.inventory.SyncState;
+import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
*/
public List<YangModelCmHandle> getLockedMisbehavingYangModelCmHandles() {
final List<DataNode> lockedCmHandleAsDataNodeList = inventoryPersistence.getCmHandleDataNodesByCpsPath(
- "//lock-reason[@reason=\"LOCKED_MISBEHAVING\"]/ancestor::cm-handles");
+ "//lock-reason[@reason=\"LOCKED_MISBEHAVING\"]/ancestor::cm-handles",
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
return lockedCmHandleAsDataNodeList.stream()
.map(cmHandle -> YangDataConverter.convertCmHandleToYangModel(cmHandle,
cmHandle.getLeaves().get("id").toString())).collect(Collectors.toList());
}
and: 'save list elements is invoked with the expected parameters'
interaction {
- def expectedJsonData = """{"cm-handles":[{"id":"cmhandle","dmi-service-name":"my-server","state":{"cm-handle-state":"ADVISED"},"additional-properties":$expectedDmiProperties,"public-properties":$expectedPublicProperties}]}"""
1 * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry',
- '/dmi-registry', expectedJsonData, noTimestamp)
+ '/dmi-registry', _, noTimestamp) >> {
+ args -> {
+ assert args[3].startsWith('{"cm-handles":[{"id":"cmhandle","dmi-service-name":"my-server","state":{"cm-handle-state":"ADVISED","last-update-time":"20')
+ assert args[3].contains(expectedDmiProperties)
+ assert args[3].contains(expectedPublicProperties)
+ }
+ }
}
where:
scenario | dmiProperties | publicProperties || expectedDmiProperties | expectedPublicProperties
when: 'parse and create cm handle in dmi registration then sync module'
objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(mockDmiPluginRegistration)
then: 'validate params for creating anchor and list elements'
- 1 * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry',
- '/dmi-registry', '{"cm-handles":[{"id":"some-cm-handle-id",' +
- '"state":{"cm-handle-state":"ADVISED"},'
- + '"additional-properties":[],"public-properties":[]}]}', null)
+ 1 * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', _, null) >> {
+ args -> {
+ assert args[3].startsWith('{"cm-handles":[{"id":"some-cm-handle-id","state":{"cm-handle-state":"ADVISED","last-update-time":"20')
+ }
+ }
}
def 'Execute cm handle id search'() {
def cpsPath = '//cps-path'
and: 'cps data service returns a valid data node'
mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', 'ncmp-dmi-registry',
- cpsPath, OMIT_DESCENDANTS)
+ cpsPath, INCLUDE_ALL_DESCENDANTS)
>> Arrays.asList(cmHandleDataNode)
when: 'get cm handles by cps path is invoked'
- def result = objectUnderTest.getCmHandleDataNodesByCpsPath(cpsPath)
+ def result = objectUnderTest.getCmHandleDataNodesByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS)
then: 'the returned result is a list of data nodes returned by cps data service'
assert result.contains(cmHandleDataNode)
}
import org.onap.cps.api.CpsModuleService
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
-import org.onap.cps.ncmp.api.inventory.CmHandleState
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.model.ModuleReference
import spock.lang.Specification
def ncmpServiceCmHandle = new NcmpServiceCmHandle()
def dmiServiceName = 'some service name'
ncmpServiceCmHandle.cmHandleId = 'cmHandleId-1'
- def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '' , '', CmHandleState.ADVISED, ncmpServiceCmHandle)
+ def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle)
and: 'DMI operations returns some module references'
def moduleReferences = [ new ModuleReference(moduleName:'module1',revision:'1'),
new ModuleReference(moduleName:'module2',revision:'2') ]
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.inventory.LockReasonCategory
import org.onap.cps.ncmp.api.inventory.SyncState
+import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.DataNode
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.http.HttpStatus
def 'Get all locked Cm-Handle where Lock Reason is LOCKED_MISBEHAVING cm handle #scenario'() {
given: 'the cps (persistence service) returns a collection of data nodes'
mockInventoryPersistence.getCmHandleDataNodesByCpsPath(
- '//lock-reason[@reason="LOCKED_MISBEHAVING"]/ancestor::cm-handles') >> [dataNode ]
+ '//lock-reason[@reason="LOCKED_MISBEHAVING"]/ancestor::cm-handles',
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode ]
when: 'get locked Misbehaving cm handle is called'
def result = objectUnderTest.getLockedMisbehavingYangModelCmHandles()
then: 'the returned cm handle collection is the correct size'
/*
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
package org.onap.cps.ncmp.api.models
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
-import org.onap.cps.ncmp.api.inventory.CmHandleState
import spock.lang.Specification
import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA
ncmpServiceCmHandle.dmiProperties = [myDmiProperty:'value1']
ncmpServiceCmHandle.publicProperties = [myPublicProperty:'value2']
when: 'it is converted to a yang model cm handle'
- def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('','','', CmHandleState.ADVISED, ncmpServiceCmHandle)
+ def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle)
then: 'the result has the right size'
assert objectUnderTest.dmiProperties.size() == 1
and: 'the DMI property in the result has the correct name and value'
def 'Resolve DMI service name: #scenario and #requiredService service require.'() {
given: 'a yang model cm handle'
- def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, CmHandleState.ADVISED, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'))
+ def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'))
expect:
assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService
where:
package org.onap.cps.ncmp.api.utils
-import org.onap.cps.ncmp.api.inventory.CmHandleState
import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
@Shared
YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('dmiServiceName',
- 'dmiDataServiceName', 'dmiModuleServiceName', CmHandleState.ADVISED , new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'))
+ 'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'))
NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties()