Merge "Update documentation related to hazelcast"
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
index ee555f7..ecbe447 100644
--- a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
@@ -228,6 +228,9 @@
 
         final Collection<String> xpaths = xpathToUpdatedDataNode.keySet();
         Collection<FragmentEntity> existingFragmentEntities = getFragmentEntities(anchorEntity, xpaths);
+
+        logMissingXPaths(xpaths, existingFragmentEntities);
+
         existingFragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(
             FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS, existingFragmentEntities);
 
@@ -243,6 +246,19 @@
         }
     }
 
+    private void logMissingXPaths(final Collection<String> xpaths, final Collection<FragmentEntity>
+            existingFragmentEntities) {
+        final Set<String> existingXPaths = existingFragmentEntities.stream().map(FragmentEntity::getXpath)
+                .collect(Collectors.toSet());
+
+        final Set<String> missingXPaths = xpaths.stream().filter(xpath -> !existingXPaths.contains(xpath))
+                .collect(Collectors.toSet());
+
+        if (!missingXPaths.isEmpty()) {
+            log.warn("Cannot update data nodes: Target XPaths {} not found in DB.", missingXPaths);
+        }
+    }
+
     private void retryUpdateDataNodesIndividually(final AnchorEntity anchorEntity,
                                                   final Collection<FragmentEntity> fragmentEntities) {
         final Collection<String> failedXpaths = new HashSet<>();
diff --git a/docs/api/swagger/cps/openapi.yaml b/docs/api/swagger/cps/openapi.yaml
index d22b288..87c6378 100644
--- a/docs/api/swagger/cps/openapi.yaml
+++ b/docs/api/swagger/cps/openapi.yaml
@@ -1451,6 +1451,15 @@
         schema:
           default: /
           type: string
+      - description: "Boolean flag to validate data, without persisting it. Default\
+          \ value is set to false."
+        in: query
+        name: dry-run
+        required: false
+        schema:
+          default: false
+          example: false
+          type: boolean
       - description: observed-timestamp
         in: query
         name: observed-timestamp
@@ -2550,6 +2559,16 @@
       schema:
         example: application/json
         type: string
+    dryRunInQuery:
+      description: "Boolean flag to validate data, without persisting it. Default\
+        \ value is set to false."
+      in: query
+      name: dry-run
+      required: false
+      schema:
+        default: false
+        example: false
+        type: boolean
     requiredXpathInQuery:
       description: "For more details on xpath, please refer https://docs.onap.org/projects/onap-cps/en/latest/xpath.html"
       examples:
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
index 5f4ba34..9e51d80 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/cps/ModuleServiceIntegrationSpec.groovy
@@ -134,7 +134,7 @@
             objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, [ 'newSchema1', 'newSchema2'])
     }
 
-    def 'Create schema set error scenario: #scenario.'() {
+    def 'Attempt to create schema set, error scenario: #scenario.'() {
         when: 'attempt to store schema set #schemaSetName in dataspace #dataspaceName'
             populateNewYangResourcesNameToContentMapAndAllModuleReferences(0)
             objectUnderTest.createSchemaSet(dataspaceName, schemaSetName, newYangResourcesNameToContentMap)
@@ -146,6 +146,14 @@
             'schema set already exists' | FUNCTIONAL_TEST_DATASPACE_1 | BOOKSTORE_SCHEMA_SET || AlreadyDefinedException
     }
 
+    def 'Attempt to create duplicate schema set from modules.'() {
+        when: 'attempt to store duplicate schema set from modules'
+            objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, newYangResourcesNameToContentMap, [])
+        then: 'an Already Defined Exception is thrown'
+            thrown(AlreadyDefinedException)
+    }
+
+
     /*
         R E A D   S C H E M A   S E T   I N F O   U S E - C A S E S
      */