package org.onap.cps.ncmp.api.impl
+import org.onap.cps.ncmp.api.models.UpgradedCmHandles
+
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR
+import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status
+
import com.fasterxml.jackson.databind.ObjectMapper
import com.hazelcast.map.IMap
import org.onap.cps.api.CpsDataService
import spock.lang.Shared
import spock.lang.Specification
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.CM_HANDLE_DOES_NOT_EXIST
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.CM_HANDLE_ALREADY_EXIST
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.CM_HANDLE_INVALID_ID
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError.UNKNOWN_ERROR
-import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status
-
class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
@Shared
def mockDmiDataOperations = Mock(DmiDataOperations)
def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
def mockInventoryPersistence = Mock(InventoryPersistence)
- def mockCmhandleQueries = Mock(CmHandleQueries)
+ def mockCmHandleQueries = Mock(CmHandleQueries)
def stubbedNetworkCmProxyCmHandlerQueryService = Stub(NetworkCmProxyCmHandleQueryService)
def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
def mockCpsDataService = Mock(CpsDataService)
def mockModuleSyncStartedOnCmHandles = Mock(IMap<String, Object>)
- def mockTrustLevelPerDmiPlugin = Mock(IMap<String, TrustLevel>)
+ def trustLevelPerCmHandle = [:]
def objectUnderTest = getObjectUnderTest()
- def 'DMI Registration: Create, Update & Delete operations are processed in the right order'() {
+ def 'DMI Registration: Create, Update, Delete & Upgrade operations are processed in the right order'() {
given: 'a registration with operations of all three types'
def dmiRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])])
dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])])
dmiRegistration.setRemovedCmHandles(['cmhandle-2'])
+ dmiRegistration.setUpgradedCmHandles(new UpgradedCmHandles(cmHandles: ['cmhandle-3'], moduleSetTag: 'some-module-set-tag'))
and: 'cm handles are persisted'
mockInventoryPersistence.getYangModelCmHandles(['cmhandle-2']) >> [new YangModelCmHandle()]
+ and: 'cm handle is in READY state'
+ mockCmHandleQueries.cmHandleHasState('cmhandle-3', CmHandleState.READY) >> true
when: 'registration is processed'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration)
then: 'cm-handles are removed first'
- 1 * objectUnderTest.parseAndRemoveCmHandlesInDmiRegistration(*_)
+ 1 * objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_)
and: 'de-registered cm handle entry is removed from in progress map'
1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle-2')
then: 'cm-handles are created'
- 1 * objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(*_)
+ 1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_)
then: 'cm-handles are updated'
1 * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_)
+ then: 'cm-handles are upgraded'
+ 1 * objectUnderTest.parseAndProcessUpgradedCmHandlesInRegistration(*_)
}
def 'DMI Registration: Response from all operations types are in response'() {
mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> updateResponses
and: 'create cm-handles can be processed successfully'
def createdResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-1')]
- objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(*_) >> createdResponses
+ objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_) >> createdResponses
and: 'delete cm-handles can be processed successfully'
def removeResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-3')]
- objectUnderTest.parseAndRemoveCmHandlesInDmiRegistration(*_) >> removeResponses
+ objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_) >> removeResponses
when: 'registration is processed'
def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration)
then: 'response has values from all operations'
when: 'update registration and sync module is called with correct DMI plugin information'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'create cm handles registration and sync modules is called with the correct plugin information'
- 1 * objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration)
- and: 'dmi is added to the trustLevel map'
- 1 * mockTrustLevelPerDmiPlugin.put(dmiPluginRegisteredName, TrustLevel.COMPLETE)
+ 1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration)
where:
- scenario | dmiPlugin | dmiModelPlugin | dmiDataPlugin | dmiPluginRegisteredName
- 'combined DMI plugin' | 'service1' | '' | '' | 'service1'
- 'data & model DMI plugins' | '' | 'service1' | 'service2' | 'service2'
- 'data & model using same service' | '' | 'service1' | 'service1' | 'service1'
+ scenario | dmiPlugin | dmiModelPlugin | dmiDataPlugin
+ 'combined DMI plugin' | 'service1' | '' | ''
+ 'data & model DMI plugins' | '' | 'service1' | 'service2'
+ 'data & model using same service' | '' | 'service1' | 'service1'
}
def 'Create CM-handle Validation: Invalid DMI plugin service name with #scenario'() {
def exceptionThrown = thrown(DmiRequestException.class)
assert exceptionThrown.getMessage().contains(expectedMessageDetails)
and: 'registration is not called'
- 0 * objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration)
+ 0 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration)
where:
scenario | dmiPlugin | dmiModelPlugin | dmiDataPlugin || expectedMessageDetails
'empty DMI plugins' | '' | '' | '' || 'No DMI plugin service names'
'without dmi & public properties' | [:] | [:] || '[]' | '[]'
}
+ def 'Add CM-Handle to trustLevelPerCmHandle Successfully with: #scenario.'() {
+ given: 'a registration with trustLevel and populated cache'
+ def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
+ dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: 'ch-1', registrationTrustLevel: TrustLevel.NONE),
+ new NcmpServiceCmHandle(cmHandleId: cmHandleId, registrationTrustLevel: registrationTrustLevel)]
+ when: 'registration is updated'
+ def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
+ then: 'a successful response is received'
+ assert response.createdCmHandles.size() == expectedNumberOfCreatedCmHandles
+ and: 'trustLevel is set for the created cm-handle'
+ assert trustLevelPerCmHandle.get(cmHandleId) == expectedTrustLevel
+ where:
+ scenario | cmHandleId | registrationTrustLevel || expectedNumberOfCreatedCmHandles | expectedTrustLevel
+ 'new cmHandleId and trustLevel' | 'ch-new' | TrustLevel.COMPLETE || 2 | TrustLevel.COMPLETE
+ 'existing cmHandleId with null trustLevel' | 'ch-1' | null || 1 | TrustLevel.NONE
+ 'cmHandleId with null trustLevel' | 'ch-new' | null || 2 | TrustLevel.COMPLETE
+ }
+
def 'Create CM-Handle Multiple Requests: All cm-handles creation requests are processed with some failures'() {
given: 'a registration with three cm-handles to be created'
def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server',
response.createdCmHandles.each {
assert it.cmHandle == 'cmhandle2'
assert it.status == Status.FAILURE
- assert it.registrationError == CM_HANDLE_ALREADY_EXIST
+ assert it.ncmpResponseStatus == CM_HANDLE_ALREADY_EXIST
assert it.errorText == 'cm-handle already exists'
}
}
with(response.createdCmHandles[0]) {
assert it.status == Status.FAILURE
assert it.cmHandle == 'cmhandle'
- assert it.registrationError == expectedError
+ assert it.ncmpResponseStatus == expectedError
assert it.errorText == expectedErrorText
}
where:
and: 'cm-handle updates can be processed successfully'
def updateOperationResponse = [CmHandleRegistrationResponse.createSuccessResponse('cm-handle-1'),
CmHandleRegistrationResponse.createFailureResponse('cm-handle-2', new Exception("Failed")),
- CmHandleRegistrationResponse.createFailureResponse('cm-handle-3', CM_HANDLE_DOES_NOT_EXIST),
+ CmHandleRegistrationResponse.createFailureResponse('cm-handle-3', CM_HANDLES_NOT_FOUND),
CmHandleRegistrationResponse.createFailureResponse('cm handle 4', CM_HANDLE_INVALID_ID)]
mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(_) >> updateOperationResponse
when: 'registration is updated'
and: '2nd cm-handle deletion fails'
with(response.removedCmHandles[1]) {
assert it.status == Status.FAILURE
- assert it.registrationError == UNKNOWN_ERROR
+ assert it.ncmpResponseStatus == UNKNOWN_ERROR
assert it.errorText == 'Failed'
assert it.cmHandle == 'cmhandle2'
}
assert it.status == Status.FAILURE
assert it.cmHandle == 'cmhandle'
assert it.errorText == 'Failed'
- assert it.registrationError == UNKNOWN_ERROR
+ assert it.ncmpResponseStatus == UNKNOWN_ERROR
}
}
with(response.removedCmHandles[0]) {
assert it.status == Status.FAILURE
assert it.cmHandle == 'cmhandle'
- assert it.registrationError == expectedError
+ assert it.ncmpResponseStatus == expectedError
assert it.errorText == expectedErrorText
}
and: 'the cm handle state is not updated to "DELETED"'
0 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_, CmHandleState.DELETED)
where:
- scenario | cmHandleId | deleteListElementException || expectedError | expectedErrorText
- 'cm-handle does not exist' | 'cmhandle' | new DataNodeNotFoundException('', '', '') || CM_HANDLE_DOES_NOT_EXIST | 'cm-handle does not exist'
- 'cm-handle has invalid name' | 'cm handle with space' | new DataValidationException('', '') || CM_HANDLE_INVALID_ID | 'cm-handle has an invalid character(s) in id'
- 'an unexpected exception' | 'cmhandle' | new RuntimeException('Failed') || UNKNOWN_ERROR | 'Failed'
+ scenario | cmHandleId | deleteListElementException || expectedError | expectedErrorText
+ 'cm-handle does not exist' | 'cmhandle' | new DataNodeNotFoundException('', '', '') || CM_HANDLES_NOT_FOUND | 'cm handle id(s) not found'
+ 'cm-handle has invalid name' | 'cm handle with space' | new DataValidationException('', '') || CM_HANDLE_INVALID_ID | 'cm-handle has an invalid character(s) in id'
+ 'an unexpected exception' | 'cmhandle' | new RuntimeException('Failed') || UNKNOWN_ERROR | 'Failed'
}
def getObjectUnderTest() {
return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
- mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmhandleQueries,
+ mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries,
stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService,
- mockModuleSyncStartedOnCmHandles, mockTrustLevelPerDmiPlugin))
+ mockModuleSyncStartedOnCmHandles, trustLevelPerCmHandle))
}
def addPersistedYangModelCmHandles(ids) {