Merge "Enable/Disable Data Sync for Cm Handle"
authorJoseph Keenan <joseph.keenan@est.tech>
Tue, 2 Aug 2022 12:59:07 +0000 (12:59 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 2 Aug 2022 12:59:07 +0000 (12:59 +0000)
1  2 
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/docs/openapi/ncmp.yml
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java

@@@ -185,7 -185,18 +185,7 @@@ components
              type: object
              $ref: '#/components/schemas/OldConditionProperties'
            description: not necessary, it is just for backward compatibility
 -      example:
 -        cmHandleQueryParameters:
 -          - conditionName: hasAllModules
 -            conditionParameters:
 -              - { "moduleName": "my-module-1" }
 -              - { "moduleName": "my-module-2" }
 -              - { "moduleName": "my-module-3" }
 -          - conditionName: hasAllProperties
 -            conditionParameters:
 -              - { "Color": "yellow" }
 -              - { "Shape": "circle" }
 -              - { "Size": "small" }
 +
      ConditionProperties:
        properties:
          conditionName:
      sync-state:
        type: object
        properties:
 -        state:
 +        syncState:
            type: string
            example: NONE_REQUESTED
          lastSyncTime:
                        - Philip Pullman
                  name: kids
  
 +    allCmHandleQueryParameters:
 +      value:
 +        cmHandleQueryParameters:
 +          - conditionName: hasAllModules
 +            conditionParameters:
 +              - { "moduleName": "my-module-1" }
 +              - { "moduleName": "my-module-2" }
 +              - { "moduleName": "my-module-3" }
 +          - conditionName: hasAllProperties
 +            conditionParameters:
 +              - { "Color": "yellow" }
 +              - { "Shape": "circle" }
 +              - { "Size": "small" }
 +          - conditionName: cmHandleWithCpsPath
 +            conditionParameters:
 +              - { "cpsPath": "//state[@cm-handle-state='ADVISED']" }
 +    pubPropCmHandleQueryParameters:
 +      value:
 +        cmHandleQueryParameters:
 +          - conditionName: hasAllProperties
 +            conditionParameters:
 +              - { "Color": "yellow" }
 +              - { "Shape": "circle" }
 +              - { "Size": "small" }
 +    modulesCmHandleQueryParameters:
 +      value:
 +        cmHandleQueryParameters:
 +          - conditionName: hasAllModules
 +            conditionParameters:
 +              - { "moduleName": "my-module-1" }
 +              - { "moduleName": "my-module-2" }
 +              - { "moduleName": "my-module-3" }
 +    cpsPathCmHandleStateQueryParameters:
 +      value:
 +        cmHandleQueryParameters:
 +          - conditionName: cmHandleWithCpsPath
 +            conditionParameters:
 +              - { "cpsPath": "//state[@cm-handle-state='LOCKED']" }
 +    cpsPathCmHandleDataSyncQueryParameters:
 +      value:
 +        cmHandleQueryParameters:
 +          - conditionName: cmHandleWithCpsPath
 +            conditionParameters:
 +              - { "cpsPath": "//state[@data-sync-enabled='true']" }
 +
    parameters:
      cmHandleInPath:
        name: cm-handle
        schema:
          type: string
          example: my-cm-handle
+     dataSyncEnabled:
+       name: dataSyncEnabled
+       in: query
+       description: Is used to enable or disable the data synchronization flag
+       required: true
+       schema:
+         type: boolean
+         example: true
      xpathInQuery:
        name: xpath
        in: query
@@@ -273,7 -273,7 +273,7 @@@ fetchModuleDefinitionsByCmHandle
  
  searchCmHandles:
    post:
 -    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here, if one of the given module names does not exists, return with an empty collection.
 +    description: Execute cm handle query search and return a list of cm handle details. Any number of conditions can be applied. To be included in the result a cm-handle must fulfill ALL the conditions. An empty collection will be returned in the case that the cm handle does not match a condition. For more on cm handle query search please refer to <a href="RTD page to be created in separate task">cm handle query search Read the Docs</a>.<br/>By supplying a CPS Path it is possible to query on any data related to the cm handle. For more on CPS Path please refer to <a href="https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html">CPS Path Read the Docs</a>. The cm handle ancestor is automatically returned for this query.
      tags:
        - network-cm-proxy
      summary: Execute cm handle search using the available conditions
          application/json:
            schema:
              $ref: 'components.yaml#/components/schemas/CmHandleQueryParameters'
 +          examples:
 +            Cm handle properties query:
 +              $ref: 'components.yaml#/components/examples/pubPropCmHandleQueryParameters'
 +            Cm handle modules query:
 +              $ref: 'components.yaml#/components/examples/modulesCmHandleQueryParameters'
 +            All cm handle query parameters:
 +              $ref: 'components.yaml#/components/examples/allCmHandleQueryParameters'
 +            Cm handle with CPS path state query:
 +              $ref: 'components.yaml#/components/examples/cpsPathCmHandleStateQueryParameters'
 +            Cm handle with data sync flag query:
 +              $ref: 'components.yaml#/components/examples/cpsPathCmHandleDataSyncQueryParameters'
      responses:
        200:
          description: OK
@@@ -390,7 -379,7 +390,7 @@@ getCmHandleStateById
  
  searchCmHandleIds:
    post:
 -    description: Execute cm handle query search, to be included in the result a cm-handle must fulfill ALL the conditions listed here, if one of the given module names does not exists, return with an empty collection.
 +    description: Execute cm handle query search and return a list of cm handle ids. Any number of conditions can be applied. To be included in the result a cm-handle must fulfill ALL the conditions. An empty collection will be returned in the case that the cm handle does not match a condition. For more on cm handle query search please refer to <a href="RTD page to be created in separate task">cm handle query search Read the Docs</a>.<br/>By supplying a CPS Path it is possible to query on any data related to the cm handle. For more on CPS Path please refer to <a href="https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html">CPS Path Read the Docs</a>. The cm handle ancestor is automatically returned for this query.
      tags:
        - network-cm-proxy
      summary: Execute cm handle query upon a given set of query parameters
          application/json:
            schema:
              $ref: 'components.yaml#/components/schemas/CmHandleQueryParameters'
 +          examples:
 +            Cm handle properties query:
 +              $ref: 'components.yaml#/components/examples/pubPropCmHandleQueryParameters'
 +            Cm handle modules query:
 +              $ref: 'components.yaml#/components/examples/modulesCmHandleQueryParameters'
 +            All cm handle query parameters:
 +              $ref: 'components.yaml#/components/examples/allCmHandleQueryParameters'
 +            Cm handle with CPS path state query:
 +              $ref: 'components.yaml#/components/examples/cpsPathCmHandleStateQueryParameters'
 +            Cm handle with data sync flag query:
 +              $ref: 'components.yaml#/components/examples/cpsPathCmHandleDataSyncQueryParameters'
      responses:
        200:
          description: OK
        404:
          $ref: 'components.yaml#/components/responses/NotFound'
        500:
-         $ref: 'components.yaml#/components/responses/InternalServerError'
+         $ref: 'components.yaml#/components/responses/InternalServerError'
+ setDataSyncEnabledFlag:
+   put:
+     tags:
+       - network-cm-proxy
+     summary: Set the Data Sync Enabled Flag
+     description: Set the data sync enabled flag to true or false for a specified Cm-Handle. This will in turn set the data sync state to UNSYNCHRONIZED and NONE_REQUESTED respectfully.
+     operationId: setDataSyncEnabledFlagForCmHandle
+     parameters:
+       - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+       - $ref: 'components.yaml#/components/parameters/dataSyncEnabled'
+     responses:
+       200:
+         $ref: 'components.yaml#/components/responses/Ok'
+       400:
+         $ref: 'components.yaml#/components/responses/BadRequest'
+       401:
+         $ref: 'components.yaml#/components/responses/Unauthorized'
+       403:
+         $ref: 'components.yaml#/components/responses/Forbidden'
+       500:
+         $ref: 'components.yaml#/components/responses/InternalServerError'
+       502:
+         $ref: 'components.yaml#/components/responses/BadGateway'
@@@ -423,6 -423,20 +423,20 @@@ class NetworkCmProxyControllerSpec exte
              response.status == HttpStatus.OK.value()
      }
  
+     def 'Set the data sync enabled based on the cm handle id and the data sync flag is #scenario' () {
+         when: 'the set data sync enabled request is invoked'
+             def response = mvc.perform(put("$ncmpBasePathV1/ch/some-cm-handle-id/data-sync?dataSyncEnabled=" + dataSyncEnabledFlag))
+                     .andReturn().response
+         then: 'method to set data sync enabled is called'
+             1 * mockNetworkCmProxyDataService.setDataSyncEnabled('some-cm-handle-id', dataSyncEnabledFlag)
+         and: 'the response returns an OK http code'
+             response.status == HttpStatus.OK.value()
+         where: 'the following parameters are used'
+         scenario     |  dataSyncEnabledFlag
+         'enabled'    |  true
+         'disabled'   |  false
+     }
      def dataStores() {
          DataStores.builder()
              .operationalDataStore(Operational.builder()
              '"dataSyncEnabled":false',
              '"dataSyncState":',
              '"operational":',
 -            '"state":"NONE_REQUESTED"',
 +            '"syncState":"NONE_REQUESTED"',
              '"lastSyncTime":"2022-12-31T20:30:40.000+0000"',
              '"running":null'
          ]
@@@ -26,6 -26,7 +26,7 @@@ package org.onap.cps.ncmp.api.impl
  import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
  import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters;
  
+ import java.time.OffsetDateTime;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.HashMap;
@@@ -35,6 -36,7 +36,7 @@@ import java.util.Set
  import java.util.stream.Collectors;
  import lombok.RequiredArgsConstructor;
  import lombok.extern.slf4j.Slf4j;
+ import org.onap.cps.api.CpsDataService;
  import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
  import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
  import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler;
@@@ -44,6 -46,8 +46,8 @@@ import org.onap.cps.ncmp.api.impl.utils
  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.CompositeStateUtils;
+ import org.onap.cps.ncmp.api.inventory.DataStoreSyncState;
  import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
  import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
  import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
@@@ -52,6 -56,7 +56,7 @@@ import org.onap.cps.ncmp.api.models.Dmi
  import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
  import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
  import org.onap.cps.spi.exceptions.AlreadyDefinedException;
+ import org.onap.cps.spi.exceptions.CpsException;
  import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
  import org.onap.cps.spi.exceptions.DataValidationException;
  import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
@@@ -79,6 -84,8 +84,8 @@@ public class NetworkCmProxyDataServiceI
  
      private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
  
+     private final CpsDataService cpsDataService;
      @Override
      public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
              final DmiPluginRegistration dmiPluginRegistration) {
          return networkCmProxyCmHandlerQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
      }
  
+     /**
+      * Set the data sync enabled flag, along with the data sync state
+      * based on the data sync enabled boolean for the cm handle id provided.
+      *
+      * @param cmHandleId cm handle id
+      * @param dataSyncEnabled data sync enabled flag
+      */
+     @Override
+     public void setDataSyncEnabled(final String cmHandleId, final boolean dataSyncEnabled) {
+         CpsValidator.validateNameCharacters(cmHandleId);
+         final CompositeState compositeState = inventoryPersistence
+             .getCmHandleState(cmHandleId);
+         if (compositeState.getDataSyncEnabled().equals(dataSyncEnabled)) {
+             log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabled);
+         } else if (compositeState.getCmHandleState() != CmHandleState.READY) {
+             throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: "
+                 + compositeState.getCmHandleState());
+         } else {
+             final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores()
+                 .getOperationalDataStore().getDataStoreSyncState();
+             if (!dataSyncEnabled && dataStoreSyncState == DataStoreSyncState.SYNCHRONIZED) {
+                 cpsDataService.deleteDataNode("NFP-Operational", cmHandleId,
+                     "/netconf-state", OffsetDateTime.now());
+             }
+             CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabled, compositeState);
+             inventoryPersistence.saveCmHandleState(cmHandleId,
+                 compositeState);
+         }
+     }
      /**
       * Retrieve cm handle details for a given cm handle.
       *
                  final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
                  lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle,
                          CmHandleState.DELETING);
 -                deleteSchemaSetAndListElementByCmHandleId(cmHandleId);
 +                deleteCmHandleByCmHandleId(cmHandleId);
                  cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId));
                  lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle,
                          CmHandleState.DELETED);
          return cmHandleRegistrationResponses;
      }
  
 -    private void deleteSchemaSetAndListElementByCmHandleId(final String cmHandleId) {
 +    private void deleteCmHandleByCmHandleId(final String cmHandleId) {
          inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
          inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandleId + "']");
      }