From 673c6d94830a1677e685cab82a76747a0808d347 Mon Sep 17 00:00:00 2001 From: aditya puthuparambil Date: Tue, 24 Aug 2021 17:44:34 +0100 Subject: Add optional observed timestamp in the cps data api - Added optional query parameter in cps data endpoints - Updated service layer and notification to use observedTimestamp Note: - NCMP REST endpoints are not updated as a part of this patch - NCMP does not sent observed timestamp when using cps data services Issue-ID: CPS-477 Signed-off-by: puthuparambil.aditya Change-Id: I1f92da3da7b3a13c45405fdf44e5fef861991d9a Signed-off-by: Renu Kumari --- .../api/impl/NetworkCmProxyDataServiceImpl.java | 20 +++++++++------- .../impl/NetworkCmProxyDataServiceImplSpec.groovy | 28 ++++++++++++++-------- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'cps-ncmp-service/src') 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 235030a84..b5a591401 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 @@ -3,6 +3,7 @@ * Copyright (C) 2021 highstreet technologies GmbH * Modifications Copyright (C) 2021 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2021 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,6 +25,7 @@ package org.onap.cps.ncmp.api.impl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.OffsetDateTime; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; @@ -62,6 +64,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry"; + private static final OffsetDateTime NO_TIMESTAMP = null; + private CpsDataService cpsDataService; private ObjectMapper objectMapper; @@ -105,25 +109,25 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService @Override public void createDataNode(final String cmHandle, final String parentNodeXpath, final String jsonData) { if (!StringUtils.hasText(parentNodeXpath) || "/".equals(parentNodeXpath)) { - cpsDataService.saveData(getDataspaceName(), cmHandle, jsonData); + cpsDataService.saveData(getDataspaceName(), cmHandle, jsonData, NO_TIMESTAMP); } else { - cpsDataService.saveData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + cpsDataService.saveData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData, NO_TIMESTAMP); } } @Override public void addListNodeElements(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.saveListNodeData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + cpsDataService.saveListNodeData(getDataspaceName(), cmHandle, parentNodeXpath, jsonData, NO_TIMESTAMP); } @Override public void updateNodeLeaves(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.updateNodeLeaves(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + cpsDataService.updateNodeLeaves(getDataspaceName(), cmHandle, parentNodeXpath, jsonData, NO_TIMESTAMP); } @Override public void replaceNodeTree(final String cmHandle, final String parentNodeXpath, final String jsonData) { - cpsDataService.replaceNodeTree(getDataspaceName(), cmHandle, parentNodeXpath, jsonData); + cpsDataService.replaceNodeTree(getDataspaceName(), cmHandle, parentNodeXpath, jsonData, NO_TIMESTAMP); } @Override @@ -150,7 +154,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService persistenceCmHandlesList.setCmHandles(createdPersistenceCmHandles); final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry", - cmHandleJsonData); + cmHandleJsonData, NO_TIMESTAMP); } catch (final JsonProcessingException e) { log.error("Parsing error occurred while converting Object to JSON for Dmi Registry."); throw new DataValidationException( @@ -170,7 +174,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService persistenceCmHandlesList.setCmHandles(updatedPersistenceCmHandles); final String cmHandlesJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "/dmi-registry", cmHandlesJsonData); + "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP); } catch (final JsonProcessingException e) { log.error("Parsing error occurred while converting Object to JSON Dmi Registry."); throw new DataValidationException( @@ -183,7 +187,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService for (final String cmHandle: dmiPluginRegistration.getRemovedCmHandles()) { try { cpsDataService.deleteListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "/dmi-registry/cm-handles[@id='" + cmHandle + "']"); + "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP); } catch (final DataNodeNotFoundException e) { log.warn("Datanode {} not deleted message {}", cmHandle, e.getMessage()); } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 076016718..45fa0af45 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2021 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2021 Bell Canada * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +50,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsDataService, mockCpsQueryService, new ObjectMapper()) def cmHandle = 'some handle' + def noTimestamp = null def expectedDataspaceName = 'NFP-Operational' def 'Query data nodes by cps path with #fetchDescendantsOption.'() { @@ -67,7 +69,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'createDataNode is invoked' objectUnderTest.createDataNode(cmHandle, xpath, jsonData) then: 'the CPS service method is invoked once with the expected parameters' - 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, jsonData) + 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, jsonData, noTimestamp) where: 'following parameters were used' scenario | xpath 'no xpath' | '' @@ -80,7 +82,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'createDataNode is invoked' objectUnderTest.createDataNode(cmHandle, xpath, jsonData) then: 'the CPS service method is invoked once with the expected parameters' - 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, xpath, jsonData) + 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp) } def 'Add list-node elements.'() { given: 'a cm handle and parent node xpath' @@ -89,7 +91,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'addListNodeElements is invoked' objectUnderTest.addListNodeElements(cmHandle, xpath, jsonData) then: 'the CPS service method is invoked once with the expected parameters' - 1 * mockCpsDataService.saveListNodeData(expectedDataspaceName, cmHandle, xpath, jsonData) + 1 * mockCpsDataService.saveListNodeData(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp) } def 'Update data node leaves.'() { given: 'a cm Handle and a cps path' @@ -98,7 +100,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'updateNodeLeaves is invoked' objectUnderTest.updateNodeLeaves(cmHandle, xpath, jsonData) then: 'the persistence service is called once with the correct parameters' - 1 * mockCpsDataService.updateNodeLeaves(expectedDataspaceName, cmHandle, xpath, jsonData) + 1 * mockCpsDataService.updateNodeLeaves(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp) } def 'Replace data node tree.'() { given: 'a cm Handle and a cps path' @@ -107,7 +109,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'replaceNodeTree is invoked' objectUnderTest.replaceNodeTree(cmHandle, xpath, jsonData) then: 'the persistence service is called once with the correct parameters' - 1 * mockCpsDataService.replaceNodeTree(expectedDataspaceName, cmHandle, xpath, jsonData) + 1 * mockCpsDataService.replaceNodeTree(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp) } def 'Register or re-register a DMI Plugin with #scenario cm handles.'() { @@ -123,11 +125,15 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'registration is updated' objectUnderTest.updateDmiPluginRegistration(dmiPluginRegistration) then: 'the CPS save list node data is invoked with the expected parameters' - expectedCallsToSaveNode * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData) + expectedCallsToSaveNode * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry', + '/dmi-registry', expectedJsonData, noTimestamp) and: 'update Node and Child Data Nodes is invoked with correct parameters' - expectedCallsToUpdateNode * mockCpsDataService.updateNodeLeavesAndExistingDescendantLeaves('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData) + expectedCallsToUpdateNode * mockCpsDataService.updateNodeLeavesAndExistingDescendantLeaves('NCMP-Admin', + 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData, noTimestamp) and : 'delete list data node is invoked with the correct parameters' - expectedCallsToDeleteListDataNode * mockCpsDataService.deleteListNodeData('NCMP-Admin', 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']") + expectedCallsToDeleteListDataNode * mockCpsDataService.deleteListNodeData('NCMP-Admin', + 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp) + where: scenario | createdCmHandles | updatedCmHandles | removedCmHandles || expectedCallsToSaveNode | expectedCallsToUpdateNode | expectedCallsToDeleteListDataNode 'create' | [persistenceCmHandle ] | [] | [] || 1 | 0 | 0 @@ -148,7 +154,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { when: 'registration is updated' objectUnderTest.updateDmiPluginRegistration(dmiPluginRegistration) then: 'the CPS save list node data is invoked with the expected parameters' - 1 * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData) + 1 * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry', + '/dmi-registry', expectedJsonData, noTimestamp) } def 'Get resource data for pass-through operational from dmi.'() { @@ -176,7 +183,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'testFieldQuery', 5, 'testAcceptParam', - '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('result-json', HttpStatus.OK) + '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> + new ResponseEntity<>('result-json', HttpStatus.OK) and: 'dmi returns ok response' response == 'result-json' } -- cgit 1.2.3-korg