Merge "Update Model to allow Persisting of alternateId"
authorToine Siebelink <toine.siebelink@est.tech>
Mon, 18 Dec 2023 10:56:47 +0000 (10:56 +0000)
committerGerrit Code Review <gerrit@onap.org>
Mon, 18 Dec 2023 10:56:47 +0000 (10:56 +0000)
60 files changed:
cps-ncmp-events/src/main/resources/schemas/cmsubscription/cm-subscription-dmi-in-event-schema-1.0.0.json
cps-ncmp-events/src/main/resources/schemas/cmsubscription/cm-subscription-dmi-out-event-schema-1.0.0.json
cps-ncmp-events/src/main/resources/schemas/cmsubscription/cm-subscription-ncmp-in-event-schema-1.0.0.json
cps-ncmp-events/src/main/resources/schemas/cmsubscription/cm-subscription-ncmp-out-event-schema-1.0.0.json
cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-in-event-schema-1.0.0.json [deleted file]
cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-out-event-schema-1.0.0.json [deleted file]
cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-in-event-schema-1.0.0.json [deleted file]
cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-out-event-schema-1.0.0.json [deleted file]
cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-in-event-schema-1.0.0.json [new file with mode: 0644]
cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-out-event-schema-1.0.0.json [new file with mode: 0644]
cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-in-event-schema-1.0.0.json [new file with mode: 0644]
cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-out-event-schema-1.0.0.json [new file with mode: 0644]
cps-ncmp-rest/docs/openapi/components.yaml
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/deprecated/subscriptions/SubscriptionPersistence.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistence.java with 96% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/deprecated/subscriptions/SubscriptionPersistenceImpl.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java with 99% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/deprecated/subscriptions/SubscriptionStatus.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionStatus.java with 96% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionDmiOutEventConsumer.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventConsumer.java with 97% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapper.java with 91% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapper.java with 97% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventConsumer.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumer.java with 96% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventForwarder.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java with 97% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventMapper.java with 97% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventToCmSubscriptionDmiInEventMapper.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventToCmSubscriptionDmiInEventMapper.java with 95% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java with 93% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/ResponseTimeoutTask.java [moved from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/ResponseTimeoutTask.java with 96% similarity]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtils.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelSubscriptionEvent.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmSubscriptionStatus.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/SubscriptionEventResponse.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/deprecated/subscriptions/SubscriptionPersistenceSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceSpec.groovy with 99% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/ClientCmSubscriptionNcmpInEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/ClientCmSubscriptionNcmpInEventMapperSpec.groovy with 97% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionDmiOutEventConsumerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventConsumerSpec.groovy with 98% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapperSpec.groovy with 95% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionEventToCmSubscriptionNcmpOutEventMapperSpec.groovy with 98% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventConsumerSpec.groovy with 97% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventForwarderSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarderSpec.groovy with 98% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpInEventMapperSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventMapperSpec.groovy with 96% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/deprecated/cmsubscription/CmSubscriptionNcmpOutEventPublisherSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisherSpec.groovy with 98% similarity]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilderSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandleSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy [deleted file]
cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy
cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/java/org/onap/cps/ncmp/dmi/rest/stub/controller/DmiRestStubController.java
dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/src/main/resources/module/moduleResourcesResponse.json
integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy

index 3750bd0..4d4d504 100644 (file)
   "$ref": "#/definitions/CmSubscriptionDmiInEvent",
   "definitions": {
     "CmSubscriptionDmiInEvent": {
-      "description": "The payload for subscription event to be forwarded to dmi plugins.",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_dmi.CmSubscriptionDmiInEvent",
+      "description": "The payload for cm subscription merge event incoming message from NCMP.",
+      "type": "object",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_dmi.CmSubscriptionDmiInEvent",
+      "additionalProperties": false,
       "properties": {
         "data": {
-          "properties": {
-            "dataType": {
-              "description": "The datatype content.",
-              "properties": {
-                "dataCategory": {
-                  "description": "The category type of the data",
-                  "type": "string"
-                },
-                "dataProvider": {
-                  "description": "The provider name of the data",
+          "$ref": "#/definitions/data"
+        }
+      },
+      "required": [
+        "data"
+      ]
+    },
+    "data": {
+      "type": "object",
+      "description": "Information about the targets and subscription",
+      "additionalProperties": false,
+      "properties": {
+        "cmhandles": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "description": "Details for the target cmhandles",
+            "additionalProperties": false,
+            "properties": {
+              "cmhandleId": {
+                "type": "string"
+              },
+              "private-properties": {
+                "type": "object",
+                "existingJavaType": "java.util.Map<String,String>",
+                "items": {
                   "type": "string"
-                },
-                "dataspace": {
-                  "description": "The dataspace name",
+                }
+              }
+            }
+          }
+        },
+        "predicates": {
+          "type": "array",
+          "description": "Additional values to be added into the subscription",
+          "items": {
+            "type": "object",
+            "properties": {
+              "targetFilter": {
+                "description": "CM Handles to be targeted by the subscription",
+                "type": "array",
+                "items": {
                   "type": "string"
                 }
               },
-              "required": [
-                "dataCategory",
-                "dataProvider",
-                "dataspace"
-              ],
-              "type": "object",
-              "additionalProperties": false
-            },
-            "predicates": {
-              "description": "Additional values to be added into the subscription",
-              "properties": {
-                "datastore": {
-                  "description": "datastore which is to be used by the subscription",
-                  "type": "string"
-                },
-                "targets": {
-                  "description": "CM Handles to be targeted by the subscription",
-                  "type": "array",
-                  "items": {
-                    "$ref": "#/definitions/CmHandle"
+              "scopeFilter": {
+                "type": "object",
+                "properties": {
+                  "datastore": {
+                    "description": "Datastore which is to be used by the subscription",
+                    "type": "string",
+                    "enum": ["ncmp-datastore:passthrough-operational", "ncmp-datastore:passthrough-running"]
+                  },
+                  "xpath-filter": {
+                    "description": "Filter to be applied to the CM Handles through this event",
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    }
                   }
                 },
-                "datastore-xpath-filter": {
-                  "description": "filter to be applied to the CM Handles through this event",
-                  "type": "string"
-                }
-              },
-              "required": [
-                "datastore",
-                "targets",
-                "datastore-xpath-filter"
-              ],
-              "type": "object",
-              "additionalProperties": false
+                "additionalProperties": false,
+                "required": [
+                  "xpath-filter"
+                ]
+              }
             },
-            "subscription": {
-              "description": "The subscription details.",
-              "properties": {
-                "clientID": {
-                  "description": "The clientID",
-                  "type": "string"
-                },
-                "name": {
-                  "description": "The name of the subscription",
-                  "type": "string"
-                },
-                "isTagged": {
-                  "description": "optional parameter, default is no",
-                  "type": "boolean",
-                  "default": false
-                }
-              },
-              "required": [
-                "clientID",
-                "name"
-              ],
-              "type": "object",
-              "additionalProperties": false
-            }
+            "additionalProperties": false,
+            "required": [
+              "targetFilter"
+            ]
           },
-          "required": [
-            "dataType",
-            "predicates",
-            "subscription"
-          ],
-          "type": "object",
           "additionalProperties": false
         }
       },
-      "type": "object",
-      "additionalProperties": false,
       "required": [
-        "data"
+        "cmhandles",
+        "predicates"
       ]
-    },
-    "CmHandle": {
-      "description": "The CM handle information",
-      "type": "object",
-      "properties": {
-        "id": {
-          "type": "string"
-        },
-        "additional-properties": {
-          "existingJavaType": "java.util.Map<String,String>"
-        }
-      },
-      "required": [
-        "id",
-        "additional-properties"
-      ],
-      "additionalProperties": false
     }
   }
 }
\ No newline at end of file
index ebbdde9..5ae6225 100644 (file)
@@ -3,67 +3,41 @@
   "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-dmi-out-event-schema:1.0.0",
   "$ref": "#/definitions/CmSubscriptionDmiOutEvent",
   "definitions": {
-    "SubscriptionStatus": {
-      "description": "The subscription status information",
+    "CmSubscriptionDmiOutEvent": {
+      "description": "The payload for cm subscription merge event coming out from DMI Plugin.",
       "type": "object",
+      "additionalProperties": false,
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent",
       "properties": {
-        "id": {
-          "type": "string"
-        },
-        "status" : {
-          "type": "string",
-          "enum": [
-            "ACCEPTED",
-            "REJECTED"
-          ]
-        },
-        "details" : {
-          "type": "string"
+        "data": {
+          "$ref": "#/definitions/Data"
         }
       },
       "required": [
-        "id",
-        "status"
+        "data"
       ],
-      "additionalProperties": false
+      "title": "CmSubscriptionDmiOutEvent"
     },
-    "CmSubscriptionDmiOutEvent" : {
-      "description": "The payload for subscription response event.",
+    "Data": {
       "type": "object",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent",
+      "description": "Information about the targets and subscription",
+      "additionalProperties": false,
       "properties": {
-        "data": {
-          "type": "object",
-          "properties": {
-            "clientId": {
-              "type": "string"
-            },
-            "subscriptionName": {
-              "type": "string"
-            },
-            "dmiName": {
-              "type": "string"
-            },
-            "subscriptionStatus": {
-              "type": "array",
-              "items": {
-                "$ref": "#/definitions/SubscriptionStatus"
-              }
-            }
-          },
-          "required": [
-            "clientId",
-            "subscriptionName",
-            "dmiName",
-            "subscriptionStatus"
-          ],
-          "additionalProperties": false
+        "statusCode": {
+          "type": "string",
+          "format": "integer",
+          "description": "The common status as defined in CPS"
+        },
+        "statusMessage": {
+          "type": "string",
+          "description": "The common status message as defined in CPS"
         }
       },
-      "additionalProperties": false,
       "required": [
-        "data"
-      ]
+        "statusCode",
+        "statusMessage"
+      ],
+      "title": "Data"
     }
   }
 }
\ No newline at end of file
index 818a8e7..ffdc2e3 100644 (file)
@@ -4,86 +4,61 @@
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "definitions": {
     "CmSubscriptionNcmpInEvent": {
-      "description": "The payload for subscription event.",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent",
+      "description": "The payload for subscription merge event.",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent",
       "properties": {
         "data": {
           "properties": {
-            "dataType": {
-              "description": "The datatype content.",
-              "properties": {
-                "dataCategory": {
-                  "description": "The category type of the data",
-                  "type": "string"
-                },
-                "dataProvider": {
-                  "description": "The provider name of the data",
-                  "type": "string"
-                },
-                "dataspace": {
-                  "description": "The dataspace name",
-                  "type": "string"
-                }
-              },
-              "required": [
-                "dataCategory",
-                "dataProvider",
-                "dataspace"
-              ],
-              "type": "object",
-              "additionalProperties": false
+            "subscriptionId": {
+              "description": "The subscription details.",
+              "type": "string"
             },
             "predicates": {
+              "type": "array",
               "description": "Additional values to be added into the subscription",
-              "properties": {
-                "datastore": {
-                  "description": "datastore which is to be used by the subscription",
-                  "type": "string"
-                },
-                "targets": {
-                  "description": "CM Handles to be targeted by the subscription",
-                  "type": "array",
-                  "items": {
-                    "type": "string"
+              "items": {
+                "type": "object",
+                "properties": {
+                  "targetFilter": {
+                    "description": "CM Handles to be targeted by the subscription",
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    }
+                  },
+                  "scopeFilter": {
+                    "type": "object",
+                    "properties": {
+                      "datastore": {
+                        "description": "Datastore which is to be used by the subscription",
+                        "type": "string",
+                        "enum": ["ncmp-datastore:passthrough-operational", "ncmp-datastore:passthrough-running"]
+                      },
+                      "xpath-filter": {
+                        "description": "Filter to be applied to the CM Handles through this event",
+                        "type": "array",
+                        "items": {
+                          "type": "string"
+                        }
+                      }
+                    },
+                    "additionalProperties": false,
+                    "required": [
+                      "xpath-filter"
+                    ]
                   }
                 },
-                "datastore-xpath-filter": {
-                  "description": "filter to be applied to the CM Handles through this event",
-                  "type": "string"
-                }
-              },
-              "required": [
-                "datastore",
-                "targets",
-                "datastore-xpath-filter"
-              ],
-              "type": "object",
-              "additionalProperties": false
-            },
-            "subscription": {
-              "description": "The subscription details.",
-              "properties": {
-                "clientID": {
-                  "description": "The clientID",
-                  "type": "string"
-                },
-                "name": {
-                  "description": "The name of the subscription",
-                  "type": "string"
-                }
+                "additionalProperties": false,
+                "required": [
+                  "targetFilter"
+                ]
               },
-              "required": [
-                "clientID",
-                "name"
-              ],
-              "type": "object",
               "additionalProperties": false
             }
           },
           "required": [
-            "dataType",
-            "predicates",
-            "subscription"
+            "subscriptionId",
+            "predicates"
           ],
           "type": "object",
           "additionalProperties": false
index 9c0c28b..e5659a7 100644 (file)
@@ -4,66 +4,60 @@
   "$ref": "#/definitions/CmSubscriptionNcmpOutEvent",
   "definitions": {
     "CmSubscriptionNcmpOutEvent": {
-      "description": "The payload for avc subscription event outcome message.",
       "type": "object",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent",
+      "description": "The payload applied cm subscription merge event coming out from NCMP.",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent",
       "additionalProperties": false,
       "properties": {
         "data": {
-          "$ref": "#/definitions/data"
+          "$ref": "#/definitions/Data"
         }
       },
       "required": [
         "data"
-      ]
+      ],
+      "title": "CmSubscriptionNcmpOutEvent"
     },
-    "data": {
+    "Data": {
       "type": "object",
-      "description": "The actual data containing information about the pending and rejected targets",
+      "description": "Information about the targets and subscription",
       "additionalProperties": false,
       "properties": {
-        "statusCode": {
-          "type": "integer"
+        "subscriptionId": {
+          "type": "string",
+          "description": "The unique subscription id"
         },
-        "statusMessage": {
-          "type": "string"
+        "accepted-targets": {
+          "type": "array",
+          "description": "List of accepted targets",
+          "items": {
+            "type": "string"
+          }
         },
-        "additionalInfo": {
-          "type": "object",
-          "additionalProperties": false,
-          "properties": {
-            "rejected": {
-              "$ref": "#/definitions/additionalInfoDetails"
-            },
-            "pending": {
-              "$ref": "#/definitions/additionalInfoDetails"
-            }
+        "rejected-targets": {
+          "type": "array",
+          "description": "List of rejected targets",
+          "items": {
+            "type": "string"
           }
-        }
-      },
-      "required": [
-        "statusCode",
-        "statusMessage"
-      ]
-    },
-    "additionalInfoDetails": {
-      "type": "array",
-      "items": {
-        "type": "object",
-        "description": "Details for the target cmhandles",
-        "additionalProperties": false,
-        "properties": {
-          "details": {
+        },
+        "pending-targets": {
+          "type": "array",
+          "description": "List of pending targets",
+          "items": {
             "type": "string"
-          },
-          "targets": {
-            "type": "array",
-            "items": {
-              "type": "string"
-            }
           }
         }
-      }
+      },
+      "required": [
+        "accepted-targets",
+        "pending-targets",
+        "rejected-targets",
+        "subscriptionId"
+      ],
+      "title": "Data"
     }
   }
+
+
 }
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-in-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-in-event-schema-1.0.0.json
deleted file mode 100644 (file)
index 4d4d504..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-{
-  "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-dmi-in-event-schema:1.0.0",
-  "$ref": "#/definitions/CmSubscriptionDmiInEvent",
-  "definitions": {
-    "CmSubscriptionDmiInEvent": {
-      "description": "The payload for cm subscription merge event incoming message from NCMP.",
-      "type": "object",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_dmi.CmSubscriptionDmiInEvent",
-      "additionalProperties": false,
-      "properties": {
-        "data": {
-          "$ref": "#/definitions/data"
-        }
-      },
-      "required": [
-        "data"
-      ]
-    },
-    "data": {
-      "type": "object",
-      "description": "Information about the targets and subscription",
-      "additionalProperties": false,
-      "properties": {
-        "cmhandles": {
-          "type": "array",
-          "items": {
-            "type": "object",
-            "description": "Details for the target cmhandles",
-            "additionalProperties": false,
-            "properties": {
-              "cmhandleId": {
-                "type": "string"
-              },
-              "private-properties": {
-                "type": "object",
-                "existingJavaType": "java.util.Map<String,String>",
-                "items": {
-                  "type": "string"
-                }
-              }
-            }
-          }
-        },
-        "predicates": {
-          "type": "array",
-          "description": "Additional values to be added into the subscription",
-          "items": {
-            "type": "object",
-            "properties": {
-              "targetFilter": {
-                "description": "CM Handles to be targeted by the subscription",
-                "type": "array",
-                "items": {
-                  "type": "string"
-                }
-              },
-              "scopeFilter": {
-                "type": "object",
-                "properties": {
-                  "datastore": {
-                    "description": "Datastore which is to be used by the subscription",
-                    "type": "string",
-                    "enum": ["ncmp-datastore:passthrough-operational", "ncmp-datastore:passthrough-running"]
-                  },
-                  "xpath-filter": {
-                    "description": "Filter to be applied to the CM Handles through this event",
-                    "type": "array",
-                    "items": {
-                      "type": "string"
-                    }
-                  }
-                },
-                "additionalProperties": false,
-                "required": [
-                  "xpath-filter"
-                ]
-              }
-            },
-            "additionalProperties": false,
-            "required": [
-              "targetFilter"
-            ]
-          },
-          "additionalProperties": false
-        }
-      },
-      "required": [
-        "cmhandles",
-        "predicates"
-      ]
-    }
-  }
-}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-out-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-dmi-out-event-schema-1.0.0.json
deleted file mode 100644 (file)
index 5ae6225..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-  "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-dmi-out-event-schema:1.0.0",
-  "$ref": "#/definitions/CmSubscriptionDmiOutEvent",
-  "definitions": {
-    "CmSubscriptionDmiOutEvent": {
-      "description": "The payload for cm subscription merge event coming out from DMI Plugin.",
-      "type": "object",
-      "additionalProperties": false,
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent",
-      "properties": {
-        "data": {
-          "$ref": "#/definitions/Data"
-        }
-      },
-      "required": [
-        "data"
-      ],
-      "title": "CmSubscriptionDmiOutEvent"
-    },
-    "Data": {
-      "type": "object",
-      "description": "Information about the targets and subscription",
-      "additionalProperties": false,
-      "properties": {
-        "statusCode": {
-          "type": "string",
-          "format": "integer",
-          "description": "The common status as defined in CPS"
-        },
-        "statusMessage": {
-          "type": "string",
-          "description": "The common status message as defined in CPS"
-        }
-      },
-      "required": [
-        "statusCode",
-        "statusMessage"
-      ],
-      "title": "Data"
-    }
-  }
-}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-in-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-in-event-schema-1.0.0.json
deleted file mode 100644 (file)
index ffdc2e3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-{
-  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-ncmp-in-event:1.0.0",
-  "$ref": "#/definitions/CmSubscriptionNcmpInEvent",
-  "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "definitions": {
-    "CmSubscriptionNcmpInEvent": {
-      "description": "The payload for subscription merge event.",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent",
-      "properties": {
-        "data": {
-          "properties": {
-            "subscriptionId": {
-              "description": "The subscription details.",
-              "type": "string"
-            },
-            "predicates": {
-              "type": "array",
-              "description": "Additional values to be added into the subscription",
-              "items": {
-                "type": "object",
-                "properties": {
-                  "targetFilter": {
-                    "description": "CM Handles to be targeted by the subscription",
-                    "type": "array",
-                    "items": {
-                      "type": "string"
-                    }
-                  },
-                  "scopeFilter": {
-                    "type": "object",
-                    "properties": {
-                      "datastore": {
-                        "description": "Datastore which is to be used by the subscription",
-                        "type": "string",
-                        "enum": ["ncmp-datastore:passthrough-operational", "ncmp-datastore:passthrough-running"]
-                      },
-                      "xpath-filter": {
-                        "description": "Filter to be applied to the CM Handles through this event",
-                        "type": "array",
-                        "items": {
-                          "type": "string"
-                        }
-                      }
-                    },
-                    "additionalProperties": false,
-                    "required": [
-                      "xpath-filter"
-                    ]
-                  }
-                },
-                "additionalProperties": false,
-                "required": [
-                  "targetFilter"
-                ]
-              },
-              "additionalProperties": false
-            }
-          },
-          "required": [
-            "subscriptionId",
-            "predicates"
-          ],
-          "type": "object",
-          "additionalProperties": false
-        }
-      },
-      "type": "object",
-      "additionalProperties": false,
-      "required": [
-        "data"
-      ]
-    }
-  }
-}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-out-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/cmsubscriptionmerge/cm-subscription-ncmp-out-event-schema-1.0.0.json
deleted file mode 100644 (file)
index e5659a7..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-{
-  "$schema": "https://json-schema.org/draft/2019-09/schema",
-  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-ncmp-out-event-schema:1.0.0",
-  "$ref": "#/definitions/CmSubscriptionNcmpOutEvent",
-  "definitions": {
-    "CmSubscriptionNcmpOutEvent": {
-      "type": "object",
-      "description": "The payload applied cm subscription merge event coming out from NCMP.",
-      "javaType": "org.onap.cps.ncmp.events.cmsubscription_merge1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent",
-      "additionalProperties": false,
-      "properties": {
-        "data": {
-          "$ref": "#/definitions/Data"
-        }
-      },
-      "required": [
-        "data"
-      ],
-      "title": "CmSubscriptionNcmpOutEvent"
-    },
-    "Data": {
-      "type": "object",
-      "description": "Information about the targets and subscription",
-      "additionalProperties": false,
-      "properties": {
-        "subscriptionId": {
-          "type": "string",
-          "description": "The unique subscription id"
-        },
-        "accepted-targets": {
-          "type": "array",
-          "description": "List of accepted targets",
-          "items": {
-            "type": "string"
-          }
-        },
-        "rejected-targets": {
-          "type": "array",
-          "description": "List of rejected targets",
-          "items": {
-            "type": "string"
-          }
-        },
-        "pending-targets": {
-          "type": "array",
-          "description": "List of pending targets",
-          "items": {
-            "type": "string"
-          }
-        }
-      },
-      "required": [
-        "accepted-targets",
-        "pending-targets",
-        "rejected-targets",
-        "subscriptionId"
-      ],
-      "title": "Data"
-    }
-  }
-
-
-}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-in-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-in-event-schema-1.0.0.json
new file mode 100644 (file)
index 0000000..3750bd0
--- /dev/null
@@ -0,0 +1,121 @@
+{
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-dmi-in-event-schema:1.0.0",
+  "$ref": "#/definitions/CmSubscriptionDmiInEvent",
+  "definitions": {
+    "CmSubscriptionDmiInEvent": {
+      "description": "The payload for subscription event to be forwarded to dmi plugins.",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_dmi.CmSubscriptionDmiInEvent",
+      "properties": {
+        "data": {
+          "properties": {
+            "dataType": {
+              "description": "The datatype content.",
+              "properties": {
+                "dataCategory": {
+                  "description": "The category type of the data",
+                  "type": "string"
+                },
+                "dataProvider": {
+                  "description": "The provider name of the data",
+                  "type": "string"
+                },
+                "dataspace": {
+                  "description": "The dataspace name",
+                  "type": "string"
+                }
+              },
+              "required": [
+                "dataCategory",
+                "dataProvider",
+                "dataspace"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            },
+            "predicates": {
+              "description": "Additional values to be added into the subscription",
+              "properties": {
+                "datastore": {
+                  "description": "datastore which is to be used by the subscription",
+                  "type": "string"
+                },
+                "targets": {
+                  "description": "CM Handles to be targeted by the subscription",
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/definitions/CmHandle"
+                  }
+                },
+                "datastore-xpath-filter": {
+                  "description": "filter to be applied to the CM Handles through this event",
+                  "type": "string"
+                }
+              },
+              "required": [
+                "datastore",
+                "targets",
+                "datastore-xpath-filter"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            },
+            "subscription": {
+              "description": "The subscription details.",
+              "properties": {
+                "clientID": {
+                  "description": "The clientID",
+                  "type": "string"
+                },
+                "name": {
+                  "description": "The name of the subscription",
+                  "type": "string"
+                },
+                "isTagged": {
+                  "description": "optional parameter, default is no",
+                  "type": "boolean",
+                  "default": false
+                }
+              },
+              "required": [
+                "clientID",
+                "name"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            }
+          },
+          "required": [
+            "dataType",
+            "predicates",
+            "subscription"
+          ],
+          "type": "object",
+          "additionalProperties": false
+        }
+      },
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "data"
+      ]
+    },
+    "CmHandle": {
+      "description": "The CM handle information",
+      "type": "object",
+      "properties": {
+        "id": {
+          "type": "string"
+        },
+        "additional-properties": {
+          "existingJavaType": "java.util.Map<String,String>"
+        }
+      },
+      "required": [
+        "id",
+        "additional-properties"
+      ],
+      "additionalProperties": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-out-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-dmi-out-event-schema-1.0.0.json
new file mode 100644 (file)
index 0000000..ebbdde9
--- /dev/null
@@ -0,0 +1,69 @@
+{
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-dmi-out-event-schema:1.0.0",
+  "$ref": "#/definitions/CmSubscriptionDmiOutEvent",
+  "definitions": {
+    "SubscriptionStatus": {
+      "description": "The subscription status information",
+      "type": "object",
+      "properties": {
+        "id": {
+          "type": "string"
+        },
+        "status" : {
+          "type": "string",
+          "enum": [
+            "ACCEPTED",
+            "REJECTED"
+          ]
+        },
+        "details" : {
+          "type": "string"
+        }
+      },
+      "required": [
+        "id",
+        "status"
+      ],
+      "additionalProperties": false
+    },
+    "CmSubscriptionDmiOutEvent" : {
+      "description": "The payload for subscription response event.",
+      "type": "object",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent",
+      "properties": {
+        "data": {
+          "type": "object",
+          "properties": {
+            "clientId": {
+              "type": "string"
+            },
+            "subscriptionName": {
+              "type": "string"
+            },
+            "dmiName": {
+              "type": "string"
+            },
+            "subscriptionStatus": {
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/SubscriptionStatus"
+              }
+            }
+          },
+          "required": [
+            "clientId",
+            "subscriptionName",
+            "dmiName",
+            "subscriptionStatus"
+          ],
+          "additionalProperties": false
+        }
+      },
+      "additionalProperties": false,
+      "required": [
+        "data"
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-in-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-in-event-schema-1.0.0.json
new file mode 100644 (file)
index 0000000..818a8e7
--- /dev/null
@@ -0,0 +1,99 @@
+{
+  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-ncmp-in-event:1.0.0",
+  "$ref": "#/definitions/CmSubscriptionNcmpInEvent",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "definitions": {
+    "CmSubscriptionNcmpInEvent": {
+      "description": "The payload for subscription event.",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent",
+      "properties": {
+        "data": {
+          "properties": {
+            "dataType": {
+              "description": "The datatype content.",
+              "properties": {
+                "dataCategory": {
+                  "description": "The category type of the data",
+                  "type": "string"
+                },
+                "dataProvider": {
+                  "description": "The provider name of the data",
+                  "type": "string"
+                },
+                "dataspace": {
+                  "description": "The dataspace name",
+                  "type": "string"
+                }
+              },
+              "required": [
+                "dataCategory",
+                "dataProvider",
+                "dataspace"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            },
+            "predicates": {
+              "description": "Additional values to be added into the subscription",
+              "properties": {
+                "datastore": {
+                  "description": "datastore which is to be used by the subscription",
+                  "type": "string"
+                },
+                "targets": {
+                  "description": "CM Handles to be targeted by the subscription",
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                },
+                "datastore-xpath-filter": {
+                  "description": "filter to be applied to the CM Handles through this event",
+                  "type": "string"
+                }
+              },
+              "required": [
+                "datastore",
+                "targets",
+                "datastore-xpath-filter"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            },
+            "subscription": {
+              "description": "The subscription details.",
+              "properties": {
+                "clientID": {
+                  "description": "The clientID",
+                  "type": "string"
+                },
+                "name": {
+                  "description": "The name of the subscription",
+                  "type": "string"
+                }
+              },
+              "required": [
+                "clientID",
+                "name"
+              ],
+              "type": "object",
+              "additionalProperties": false
+            }
+          },
+          "required": [
+            "dataType",
+            "predicates",
+            "subscription"
+          ],
+          "type": "object",
+          "additionalProperties": false
+        }
+      },
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "data"
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-out-event-schema-1.0.0.json b/cps-ncmp-events/src/main/resources/schemas/deprecated.cmsubscription/cm-subscription-ncmp-out-event-schema-1.0.0.json
new file mode 100644 (file)
index 0000000..9c0c28b
--- /dev/null
@@ -0,0 +1,69 @@
+{
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "$id": "urn:cps:org.onap.cps.ncmp.events:cm-subscription-ncmp-out-event-schema:1.0.0",
+  "$ref": "#/definitions/CmSubscriptionNcmpOutEvent",
+  "definitions": {
+    "CmSubscriptionNcmpOutEvent": {
+      "description": "The payload for avc subscription event outcome message.",
+      "type": "object",
+      "javaType": "org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.CmSubscriptionNcmpOutEvent",
+      "additionalProperties": false,
+      "properties": {
+        "data": {
+          "$ref": "#/definitions/data"
+        }
+      },
+      "required": [
+        "data"
+      ]
+    },
+    "data": {
+      "type": "object",
+      "description": "The actual data containing information about the pending and rejected targets",
+      "additionalProperties": false,
+      "properties": {
+        "statusCode": {
+          "type": "integer"
+        },
+        "statusMessage": {
+          "type": "string"
+        },
+        "additionalInfo": {
+          "type": "object",
+          "additionalProperties": false,
+          "properties": {
+            "rejected": {
+              "$ref": "#/definitions/additionalInfoDetails"
+            },
+            "pending": {
+              "$ref": "#/definitions/additionalInfoDetails"
+            }
+          }
+        }
+      },
+      "required": [
+        "statusCode",
+        "statusMessage"
+      ]
+    },
+    "additionalInfoDetails": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "description": "Details for the target cmhandles",
+        "additionalProperties": false,
+        "properties": {
+          "details": {
+            "type": "string"
+          },
+          "targets": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
index 9b5a1fd..3bee633 100644 (file)
@@ -140,6 +140,9 @@ components:
             type: string
             enum: [COMPLETE, NONE]
             example: "COMPLETE"
+        alternateId:
+          type: string
+          example: "my-alternate-id"
     RestCmHandleProperties:
       type: object
       additionalProperties:
@@ -158,6 +161,7 @@ components:
           example: [ my-cm-handle1, my-cm-handle2, my-cm-handle3 ]
         moduleSetTag:
           type: string
+          default: ""
           example: 'my-module-set-tag'
 
     #Response Schemas
index c4dd91e..0bc0c1e 100644 (file)
@@ -41,7 +41,7 @@ class NcmpRestInputMapperSpec extends Specification {
     def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
         given: 'a rest cm handle input'
             def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: registrationDmiProperties,
-                publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel)
+                publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel, alternateId: 'my-alternate-id', moduleSetTag: 'my-module-set-tag')
             def restDmiPluginRegistration = new RestDmiPluginRegistration(
                 createdCmHandles: [inputRestCmHandle])
         when: 'to plugin dmi registration is called'
@@ -54,6 +54,9 @@ class NcmpRestInputMapperSpec extends Specification {
             result.createdCmHandles[0].dmiProperties == mappedDmiProperties
             result.createdCmHandles[0].publicProperties == mappedPublicProperties
             result.createdCmHandles[0].registrationTrustLevel == mappedTrustLevel
+        and: 'alternate ID and module set tag converted correctly'
+            result.createdCmHandles[0].alternateId == 'my-alternate-id'
+            result.createdCmHandles[0].moduleSetTag == 'my-module-set-tag'
         where: 'the following parameters are used'
             scenario                    | registrationDmiProperties                | registrationPublicProperties                           | registrationTrustLevel || mappedDmiProperties                      | mappedPublicProperties                                 | mappedTrustLevel
             'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | 'COMPLETE'             || ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | TrustLevel.COMPLETE
index 1afe5c7..469d75a 100755 (executable)
@@ -328,7 +328,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
                             dmiPluginRegistration.getDmiDataPlugin(),
                             dmiPluginRegistration.getDmiModelPlugin(),
                             cmHandle,
-                            cmHandle.getModuleSetTag());
+                            cmHandle.getModuleSetTag(),
+                            cmHandle.getAlternateId());
                     yangModelCmHandles.add(yangModelCmHandle);
                     initialTrustLevelPerCmHandleId.put(cmHandle.getCmHandleId(), cmHandle.getRegistrationTrustLevel());
                 });
@@ -420,7 +421,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
                 .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
         return YangModelCmHandle.toYangModelCmHandle(dmiPluginRegistration.getDmiPlugin(),
                 dmiPluginRegistration.getDmiDataPlugin(), dmiPluginRegistration.getDmiModelPlugin(),
-                ncmpServiceCmHandle, moduleSetTag);
+                ncmpServiceCmHandle, moduleSetTag, ncmpServiceCmHandle.getAlternateId());
     }
 
     private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent;
 
@@ -30,7 +30,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
 import org.onap.cps.ncmp.api.impl.config.embeddedcache.ForwardedSubscriptionEventCacheConfig;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent;
 import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent;
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import java.util.List;
 import java.util.stream.Collectors;
@@ -49,7 +49,8 @@ public interface CmSubscriptionDmiOutEventToYangModelSubscriptionEventMapper {
     default List<YangModelSubscriptionEvent.TargetCmHandle> mapSubscriptionStatusToCmHandleTargets(
             List<SubscriptionStatus> subscriptionStatus) {
         return subscriptionStatus.stream().map(status -> new YangModelSubscriptionEvent.TargetCmHandle(status.getId(),
-                org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.fromString(status.getStatus().value()),
+                org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus.fromString(
+                        status.getStatus().value()),
                         status.getDetails())).collect(Collectors.toList());
     }
 }
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import java.util.List;
 import java.util.Map;
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.Named;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
 import org.onap.cps.ncmp.api.models.CmSubscriptionStatus;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_client.AdditionalInfo;
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent;
 import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL;
@@ -28,7 +28,7 @@ import io.cloudevents.CloudEvent;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent;
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent;
 import org.springframework.beans.factory.annotation.Value;
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import com.hazelcast.map.IMap;
 import io.cloudevents.CloudEvent;
@@ -37,10 +37,10 @@ import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.api.impl.config.embeddedcache.ForwardedSubscriptionEventCacheConfig;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.events.EventsPublisher;
 import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.utils.CmSubscriptionEventCloudMapper;
 import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription;
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription;
 
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.PARTIALLY_APPLIED_SUBSCRIPTION;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUBSCRIPTION_NOT_APPLICABLE;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUBSCRIPTION_PENDING;
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUCCESSFULLY_APPLIED_SUBSCRIPTION;
-import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.ACCEPTED;
-import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.PENDING;
-import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.REJECTED;
+import static org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus.ACCEPTED;
+import static org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus.PENDING;
+import static org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus.REJECTED;
 
 import io.cloudevents.CloudEvent;
 import java.util.List;
@@ -34,9 +34,9 @@ import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.api.NcmpResponseStatus;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.events.EventsPublisher;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
 import org.onap.cps.ncmp.api.impl.utils.DataNodeHelper;
 import org.onap.cps.ncmp.api.impl.utils.SubscriptionOutcomeCloudMapper;
 import org.onap.cps.ncmp.api.models.CmSubscriptionEvent;
index 25ea3bc..750be2d 100644 (file)
@@ -38,6 +38,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
 import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
@@ -64,7 +65,7 @@ public class ModuleOperationsUtils {
     public static final String MODULE_SET_TAG_KEY = "moduleSetTag";
     public static final String MODULE_SET_TAG_MESSAGE_FORMAT = "Upgrade to ModuleSetTag: {0}";
     private static final String UPGRADE_FORMAT = "Upgrade to ModuleSetTag: %s";
-    private static final String UPGRADE_FAILED_FORMAT = UPGRADE_FORMAT + " Attempt #%d failed: %s";
+    private static final String LOCK_REASON_DETAILS_MSG_FORMAT = UPGRADE_FORMAT + " Attempt #%d failed: %s";
     private static final Pattern retryAttemptPattern = Pattern.compile("Attempt #(\\d+) failed:.+");
     private static final Pattern moduleSetTagPattern = Pattern.compile("Upgrade to ModuleSetTag: (\\S+)");
 
@@ -127,13 +128,14 @@ public class ModuleOperationsUtils {
         int attempt = 1;
         final Map<String, String> compositeStateDetails
                 = getLockedCompositeStateDetails(compositeState.getLockReason());
-        if (!compositeStateDetails.isEmpty()) {
+        if (!compositeStateDetails.isEmpty() && compositeStateDetails.containsKey(RETRY_ATTEMPT_KEY)) {
             attempt = 1 + Integer.parseInt(compositeStateDetails.get(RETRY_ATTEMPT_KEY));
         }
+        final String moduleSetTag = compositeStateDetails.get(MODULE_SET_TAG_KEY);
         compositeState.setLockReason(CompositeState.LockReason.builder()
-                .details(String.format(UPGRADE_FAILED_FORMAT,
-                        compositeStateDetails.get(MODULE_SET_TAG_KEY), attempt, errorMessage))
-                .lockReasonCategory(lockReasonCategory).build());
+                .details(String.format(LOCK_REASON_DETAILS_MSG_FORMAT, StringUtils.isNotBlank(moduleSetTag)
+                        ? moduleSetTag : "not-specified", attempt, errorMessage)).lockReasonCategory(lockReasonCategory)
+                .build());
     }
 
     /**
@@ -174,13 +176,19 @@ public class ModuleOperationsUtils {
                 DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
         final CompositeState.LockReason lockReason = compositeState.getLockReason();
 
+        final boolean moduleUpgrade = LockReasonCategory.MODULE_UPGRADE == lockReason.getLockReasonCategory();
+        if (moduleUpgrade) {
+            log.info("Locked for module upgrade");
+            return true;
+        }
+
         final boolean failedDuringModuleSync = LockReasonCategory.MODULE_SYNC_FAILED
                 == lockReason.getLockReasonCategory();
         final boolean failedDuringModuleUpgrade = LockReasonCategory.MODULE_UPGRADE_FAILED
                 == lockReason.getLockReasonCategory();
 
         if (failedDuringModuleSync || failedDuringModuleUpgrade) {
-            log.info("Locked for module {}.", failedDuringModuleSync ? "sync" : "upgrade");
+            log.info("Locked for module {} (last attempt failed).", failedDuringModuleSync ? "sync" : "upgrade");
             return isRetryDue(lockReason, time);
         }
         log.info("Locked for other reason");
index 841368c..a6b85a5 100644 (file)
@@ -73,34 +73,36 @@ public class ModuleSyncService {
      */
     public void syncAndCreateOrUpgradeSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
 
-        final String moduleSetTag;
         final String cmHandleId = yangModelCmHandle.getId();
         final CompositeState compositeState = yangModelCmHandle.getCompositeState();
         final boolean inUpgrade = ModuleOperationsUtils.isInUpgradeOrUpgradeFailed(compositeState);
-
-        if (inUpgrade) {
-            moduleSetTag = ModuleOperationsUtils.getLockedCompositeStateDetails(compositeState.getLockReason())
-                    .get(ModuleOperationsUtils.MODULE_SET_TAG_KEY);
-        } else {
-            moduleSetTag = yangModelCmHandle.getModuleSetTag();
-        }
+        final String moduleSetTag = getModuleSetTag(yangModelCmHandle, compositeState, inUpgrade);
 
         final Collection<ModuleReference> moduleReferencesFromCache = moduleSetTagCache.get(moduleSetTag);
 
         if (moduleReferencesFromCache == null) {
-            final Optional<DataNode> optionalExistingCmHandleWithSameModuleSetTag
+            final Optional<DataNode> existingCmHandleWithSameModuleSetTag
                     = getFirstReadyDataNodeWithModuleSetTag(moduleSetTag);
 
-            if (optionalExistingCmHandleWithSameModuleSetTag.isPresent()) {
-                final String existingCmHandleAnchorName
-                        = optionalExistingCmHandleWithSameModuleSetTag.get().getAnchorName();
-                createOrUpgradeSchemaSetUsingModuleSetTag(cmHandleId, moduleSetTag, existingCmHandleAnchorName);
+            if (existingCmHandleWithSameModuleSetTag.isPresent()) {
+                final String existingAnchorName = existingCmHandleWithSameModuleSetTag.get().getAnchorName();
+                final Collection<ModuleReference> moduleReferencesFromExistingCmHandle =
+                        upgradeOrCreateSchemaSetUsingModuleSetTag(yangModelCmHandle.getId(), moduleSetTag,
+                                existingAnchorName, inUpgrade);
+                updateModuleSetTagCache(moduleSetTag, moduleReferencesFromExistingCmHandle);
             } else {
-                syncAndCreateSchemaSet(yangModelCmHandle, moduleSetTag);
+                final Collection<ModuleReference> allModuleReferencesFromCmHandle
+                        = syncAndCreateSchemaSet(yangModelCmHandle);
+                updateModuleSetTagCache(moduleSetTag, allModuleReferencesFromCmHandle);
             }
         } else {
-            cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                    cmHandleId, NO_NEW_MODULES, moduleReferencesFromCache);
+            if (inUpgrade) {
+                cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
+                        NO_NEW_MODULES, moduleReferencesFromCache);
+            } else {
+                cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                        cmHandleId, NO_NEW_MODULES, moduleReferencesFromCache);
+            }
         }
         if (!inUpgrade) {
             cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
@@ -108,25 +110,6 @@ public class ModuleSyncService {
         setCmHandleModuleSetTag(yangModelCmHandle, moduleSetTag);
     }
 
-    private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle, final String moduleSetTag) {
-        final Collection<ModuleReference> allModuleReferencesFromCmHandle =
-                dmiModelOperations.getModuleReferences(yangModelCmHandle);
-        final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
-                .identifyNewModuleReferences(allModuleReferencesFromCmHandle);
-        final Map<String, String> newModuleNameToContentMap;
-        if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
-            newModuleNameToContentMap = NO_NEW_MODULES;
-        } else {
-            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
-                    identifiedNewModuleReferencesFromCmHandle);
-        }
-        cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-            yangModelCmHandle.getId(), newModuleNameToContentMap, allModuleReferencesFromCmHandle);
-        if (StringUtils.isNotBlank(moduleSetTag)) {
-            moduleSetTagCache.put(moduleSetTag, allModuleReferencesFromCmHandle);
-        }
-    }
-
     /**
      * Deletes the SchemaSet for schema set id if the SchemaSet Exists.
      *
@@ -162,16 +145,56 @@ public class ModuleSyncService {
                 jsonObjectMapper.asJsonString(dmiRegistryProperties), OffsetDateTime.now());
     }
 
-    private void createOrUpgradeSchemaSetUsingModuleSetTag(final String schemaSetName,
-                                                           final String moduleSetTag,
-                                                           final String existingCmHandleAnchorName) {
+    private Collection<ModuleReference> syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
+        final Collection<ModuleReference> allModuleReferencesFromCmHandle =
+                dmiModelOperations.getModuleReferences(yangModelCmHandle);
+        final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
+                .identifyNewModuleReferences(allModuleReferencesFromCmHandle);
+        final Map<String, String> newModuleNameToContentMap;
+        if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
+            newModuleNameToContentMap = NO_NEW_MODULES;
+        } else {
+            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
+                    identifiedNewModuleReferencesFromCmHandle);
+        }
+        cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                yangModelCmHandle.getId(), newModuleNameToContentMap, allModuleReferencesFromCmHandle);
+        return allModuleReferencesFromCmHandle;
+    }
+
+    private Collection<ModuleReference> upgradeOrCreateSchemaSetUsingModuleSetTag(final String schemaSetName,
+                                                                                  final String moduleSetTag,
+                                                                                  final String existingAnchorName,
+                                                                                  final boolean inUpgrade) {
         log.info("Found cm handle having module set tag: {}", moduleSetTag);
         final Collection<ModuleReference> moduleReferencesFromExistingCmHandle =
                 cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                        existingCmHandleAnchorName);
-        cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-            schemaSetName, NO_NEW_MODULES, moduleReferencesFromExistingCmHandle);
-        moduleSetTagCache.put(moduleSetTag, moduleReferencesFromExistingCmHandle);
+                        existingAnchorName);
+        if (inUpgrade) {
+            cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
+                    NO_NEW_MODULES, moduleReferencesFromExistingCmHandle);
+        } else {
+            cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                    schemaSetName, NO_NEW_MODULES, moduleReferencesFromExistingCmHandle);
+        }
+        return moduleReferencesFromExistingCmHandle;
+    }
+
+    private String getModuleSetTag(final YangModelCmHandle yangModelCmHandle,
+                                   final CompositeState compositeState,
+                                   final boolean inUpgrade) {
+        if (inUpgrade) {
+            return ModuleOperationsUtils.getLockedCompositeStateDetails(compositeState.getLockReason())
+                    .get(ModuleOperationsUtils.MODULE_SET_TAG_KEY);
+        }
+        return yangModelCmHandle.getModuleSetTag();
+    }
+
+    private void updateModuleSetTagCache(final String moduleSetTag,
+                                         final Collection<ModuleReference> allModuleReferencesFromCmHandle) {
+        if (StringUtils.isNotBlank(moduleSetTag)) {
+            moduleSetTagCache.putIfAbsent(moduleSetTag, allModuleReferencesFromCmHandle);
+        }
     }
 
 }
index 896316a..e214044 100644 (file)
@@ -67,20 +67,20 @@ public class ModuleSyncTasks {
                 final YangModelCmHandle yangModelCmHandle =
                         YangDataConverter.convertCmHandleToYangModel(cmHandleAsDataNode, cmHandleId);
                 final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
+                final boolean inUpgrade = ModuleOperationsUtils.isInUpgradeOrUpgradeFailed(compositeState);
                 try {
-                    moduleSyncService.deleteSchemaSetIfExists(cmHandleId);
+                    if (!inUpgrade) {
+                        moduleSyncService.deleteSchemaSetIfExists(cmHandleId);
+                    }
                     moduleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle);
                     yangModelCmHandle.getCompositeState().setLockReason(null);
                     cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.READY);
                 } catch (final Exception e) {
                     log.warn("Processing of {} module failed due to reason {}.", cmHandleId, e.getMessage());
-                    if (ModuleOperationsUtils.isInUpgradeOrUpgradeFailed(compositeState)) {
-                        moduleOperationsUtils.updateLockReasonDetailsAndAttempts(compositeState,
-                                LockReasonCategory.MODULE_UPGRADE_FAILED, e.getMessage());
-                    } else {
-                        moduleOperationsUtils.updateLockReasonDetailsAndAttempts(compositeState,
-                                LockReasonCategory.MODULE_SYNC_FAILED, e.getMessage());
-                    }
+                    final LockReasonCategory lockReasonCategory = inUpgrade ? LockReasonCategory.MODULE_UPGRADE_FAILED
+                            : LockReasonCategory.MODULE_SYNC_FAILED;
+                    moduleOperationsUtils.updateLockReasonDetailsAndAttempts(compositeState,
+                            lockReasonCategory, e.getMessage());
                     setCmHandleStateLocked(yangModelCmHandle, compositeState.getLockReason());
                     cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED);
                 }
index b6a04d3..b54c154 100644 (file)
@@ -87,7 +87,8 @@ public class YangDataConverter {
                 (String) cmHandleDataNode.getLeaves().get("dmi-data-service-name"),
                 (String) cmHandleDataNode.getLeaves().get("dmi-model-service-name"),
                 ncmpServiceCmHandle,
-                (String) cmHandleDataNode.getLeaves().get("module-set-tag")
+                (String) cmHandleDataNode.getLeaves().get("module-set-tag"),
+                (String) cmHandleDataNode.getLeaves().get("alternate-id")
         );
     }
 
index f930d5b..ba36b1a 100644 (file)
@@ -68,6 +68,9 @@ public class YangModelCmHandle {
     @JsonProperty("module-set-tag")
     private String moduleSetTag;
 
+    @JsonProperty("alternate-id")
+    private String alternateId;
+
     @JsonProperty("additional-properties")
     private List<Property> dmiProperties;
 
@@ -91,6 +94,7 @@ public class YangModelCmHandle {
         copy.dmiProperties = original.getDmiProperties() == null ? null : new ArrayList<>(original.getDmiProperties());
         copy.publicProperties =
                 original.getPublicProperties() == null ? null : new ArrayList<>(original.getPublicProperties());
+        copy.alternateId = original.getAlternateId();
         return copy;
     }
 
@@ -107,13 +111,15 @@ public class YangModelCmHandle {
                                                         final String dmiDataServiceName,
                                                         final String dmiModelServiceName,
                                                         final NcmpServiceCmHandle ncmpServiceCmHandle,
-                                                        final String moduleSetTag) {
+                                                        final String moduleSetTag,
+                                                        final String alternateId) {
         final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle();
         yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleId());
         yangModelCmHandle.setDmiServiceName(dmiServiceName);
         yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
         yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
         yangModelCmHandle.setModuleSetTag(moduleSetTag == null ? StringUtils.EMPTY : moduleSetTag);
+        yangModelCmHandle.setAlternateId(alternateId);
         yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
         yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
                 ncmpServiceCmHandle.getPublicProperties()));
index 866bfd4..a6cfa7b 100644 (file)
@@ -31,7 +31,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 
 /**
  * Subscription event model to persist data into DB.
index 5541a01..c569123 100644 (file)
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import jakarta.validation.constraints.NotNull;
 import lombok.Getter;
 import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Getter
index f323079..4989878 100644 (file)
@@ -23,7 +23,6 @@ package org.onap.cps.ncmp.api.models;
 import com.fasterxml.jackson.annotation.JsonSetter;
 import com.fasterxml.jackson.annotation.Nulls;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
@@ -59,18 +58,6 @@ public class NcmpServiceCmHandle {
     @JsonSetter(nulls = Nulls.AS_EMPTY)
     private TrustLevel registrationTrustLevel;
 
-    /**
-     * NcmpServiceCmHandle copy constructor.
-     *
-     * @param ncmpServiceCmHandle Ncmp Service CmHandle
-     */
-    public NcmpServiceCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
-        this.cmHandleId = ncmpServiceCmHandle.getCmHandleId();
-        this.dmiProperties = new LinkedHashMap<>(ncmpServiceCmHandle.getDmiProperties());
-        this.publicProperties = new LinkedHashMap<>(ncmpServiceCmHandle.getPublicProperties());
-        this.compositeState = ncmpServiceCmHandle.getCompositeState() != null ? new CompositeState(
-                ncmpServiceCmHandle.getCompositeState()) : null;
-        this.moduleSetTag = ncmpServiceCmHandle.getModuleSetTag();
-        this.registrationTrustLevel = ncmpServiceCmHandle.getRegistrationTrustLevel();
-    }
+    @JsonSetter(nulls = Nulls.AS_EMPTY)
+    private String alternateId;
 }
index 05663a5..cabd868 100644 (file)
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.Map;
 import lombok.Getter;
 import lombok.Setter;
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus;
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 @Getter
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.subscriptions
+package org.onap.cps.ncmp.api.impl.deprecated.subscriptions
 
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NO_TIMESTAMP
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
 
@@ -27,7 +27,7 @@ import com.hazelcast.map.IMap
 import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistenceImpl
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistenceImpl
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent
 import org.onap.cps.ncmp.utils.TestUtils
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.dmi_to_ncmp.CmSubscriptionDmiOutEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.apache.kafka.clients.consumer.ConsumerRecord
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent
 import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent
 
@@ -27,8 +27,8 @@ import com.hazelcast.map.IMap
 import io.cloudevents.CloudEvent
 import org.mapstruct.factory.Mappers
 import org.onap.cps.ncmp.api.impl.events.EventsPublisher
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus
 import org.onap.cps.ncmp.api.impl.utils.CmSubscriptionEventCloudMapper
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent.TargetCmHandle
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.mapstruct.factory.Mappers
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionStatus
 import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
@@ -18,7 +18,7 @@
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl.events.cmsubscription
+package org.onap.cps.ncmp.api.impl.events.deprecated.cmsubscription
 
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUCCESSFULLY_APPLIED_SUBSCRIPTION
 import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUBSCRIPTION_PENDING
@@ -30,7 +30,7 @@ import io.cloudevents.CloudEvent
 import io.cloudevents.core.builder.CloudEventBuilder
 import org.mapstruct.factory.Mappers
 import org.onap.cps.ncmp.api.impl.events.EventsPublisher
-import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence
+import org.onap.cps.ncmp.api.impl.deprecated.subscriptions.SubscriptionPersistence
 import org.onap.cps.ncmp.api.impl.utils.DataNodeBaseSpec
 import org.onap.cps.ncmp.api.impl.utils.SubscriptionOutcomeCloudMapper
 import org.onap.cps.ncmp.api.models.CmSubscriptionEvent
index 099fc5a..8f3d8d9 100644 (file)
@@ -108,9 +108,24 @@ class ModuleOperationsUtilsSpec extends Specification{
             assert compositeState.lockReason.lockReasonCategory == MODULE_SYNC_FAILED
             assert compositeState.lockReason.details.contains(expectedDetails)
         where:
-            scenario         | lockReason                                                                                   || expectedDetails
-            'does not exist' | null                                                                                         || 'Attempt #1 failed: new error message'
-            'exists'         | CompositeState.LockReason.builder().details("Attempt #2 failed: some error message").build() || 'Attempt #3 failed: new error message'
+            scenario                           | lockReason                                                                                       || expectedDetails
+            'does not exist'                   | null                                                                                             || 'Attempt #1 failed: new error message'
+            'exists'                           | CompositeState.LockReason.builder().details("Attempt #2 failed: some error message").build()     || 'Attempt #3 failed: new error message'
+    }
+
+    def 'Update lock reason details that contains #scenario'() {
+        given: 'A locked state'
+            def compositeState = new CompositeStateBuilder().withCmHandleState(CmHandleState.LOCKED)
+                .withLockReason(MODULE_UPGRADE, "Upgrade to ModuleSetTag: " + moduleSetTag).build()
+        when: 'update cm handle details'
+            objectUnderTest.updateLockReasonDetailsAndAttempts(compositeState, MODULE_UPGRADE_FAILED, 'new error message')
+        then: 'the composite state lock reason and details are updated'
+            assert compositeState.lockReason.lockReasonCategory == MODULE_UPGRADE_FAILED
+            assert compositeState.lockReason.details.contains("Upgrade to ModuleSetTag: " + expectedDetails)
+        where:
+            scenario               | moduleSetTag       || expectedDetails
+            'a module set tag'     | 'someModuleSetTag' || 'someModuleSetTag'
+            'empty module set tag' | ''                 || 'not-specified'
     }
 
     def 'Get all locked Cm-Handle where Lock Reason is MODULE_SYNC_FAILED cm handle #scenario'() {
index 5384f31..2ded84f 100644 (file)
@@ -62,7 +62,7 @@ class ModuleSyncServiceSpec extends Specification {
             def ncmpServiceCmHandle = new NcmpServiceCmHandle()
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.ADVISED).build())
             ncmpServiceCmHandle.cmHandleId = 'ch-1'
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag)
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag, '')
         and: 'DMI operations returns some module references'
             def moduleReferences =  [ new ModuleReference('module1','1'), new ModuleReference('module2','2') ]
             mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
@@ -76,7 +76,7 @@ class ModuleSyncServiceSpec extends Specification {
         when: 'module sync is triggered'
             objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
         then: 'create schema set from module is invoked with correct parameters'
-            1 * mockCpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', newModuleNameContentToMap, moduleReferences)
+            1 * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', newModuleNameContentToMap, moduleReferences)
         and: 'anchor is created with the correct parameters'
             1 * mockCpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', 'ch-1')
         where: 'the following parameters are used'
@@ -91,7 +91,7 @@ class ModuleSyncServiceSpec extends Specification {
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withLockReason(MODULE_UPGRADE, 'Upgrade to ModuleSetTag: tag-1').build())
             def dmiServiceName = 'some service name'
             ncmpServiceCmHandle.cmHandleId = 'upgraded-ch'
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle,'tag-1')
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '', '', ncmpServiceCmHandle,'tag-1', '')
         and: 'some module references'
             def moduleReferences =  [ new ModuleReference('module1','1') ]
         and: 'cache or DMI operations returns some module references for upgraded cm handle'
@@ -110,15 +110,17 @@ class ModuleSyncServiceSpec extends Specification {
             mockCmHandleQueries.cmHandleHasState('otherId', CmHandleState.READY) >> true
         when: 'module sync is triggered'
             objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
-        then: 'create schema set from module is invoked for the upgraded cm handle'
-            1 * mockCpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
+        then: 'update schema set from module is invoked for the upgraded cm handle'
+            expectedCallsToUpgradeSchemaSet * mockCpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
+        and: 'create schema set from module is invoked for the upgraded cm handle'
+            expectedCallsToCeateSchemaSet * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
         and: 'No anchor is created for the upgraded cm handle'
             0 * mockCpsAdminService.createAnchor(*_)
         where: 'the following parameters are used'
-            scenario      | populateCache | existingCmHandlesWithSameTag
-            'new'         | false         | []
-            'in cache'    | true          | []
-            'in database' | false         | [cmHandleWithModuleSetTag]
+            scenario      | populateCache | existingCmHandlesWithSameTag || expectedCallsToUpgradeSchemaSet | expectedCallsToCeateSchemaSet
+            'new'         | false         | []                           || 0                               | 1
+            'in cache'    | true          | []                           || 1                               | 0
+            'in database' | false         | [cmHandleWithModuleSetTag]   || 1                               | 0
     }
 
     def 'upgrade model for a existing cm handle'() {
@@ -127,7 +129,7 @@ class ModuleSyncServiceSpec extends Specification {
             ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder()
                 .withLockReason(MODULE_UPGRADE, 'Upgrade to ModuleSetTag: targetModuleSetTag').build())
             ncmpServiceCmHandle.setCmHandleId('cmHandleId-1')
-            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, 'targetModuleSetTag')
+            def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, 'targetModuleSetTag', '')
             mockCmHandleQueries.cmHandleHasState('cmHandleId-1', CmHandleState.READY) >> true
         and: 'the module service returns some module references'
             def moduleReferences = [new ModuleReference('module1', '1'), new ModuleReference('module2', '2')]
@@ -138,7 +140,7 @@ class ModuleSyncServiceSpec extends Specification {
         when: 'module upgrade is triggered'
             objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
         then: 'the upgrade is delegated to the module service (with the correct parameters)'
-            1 * mockCpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'cmHandleId-1', Collections.emptyMap(), moduleReferences)
+            1 * mockCpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'cmHandleId-1', Collections.emptyMap(), moduleReferences)
     }
 
     def 'Delete Schema Set for CmHandle'() {
index 2b17e5d..c83a540 100644 (file)
@@ -32,7 +32,7 @@ import spock.lang.Specification
 class DmiServiceUrlBuilderSpec extends Specification {
 
     static YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('dmiServiceName',
-        'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'),'')
+        'dmiDataServiceName', 'dmiModuleServiceName', new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id'),'my-module-set-tag', 'my-alternate-id')
 
     NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties()
 
index ca0015e..493db8c 100644 (file)
@@ -47,9 +47,12 @@ class YangModelCmHandleSpec extends Specification {
                 .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, 'some-sync-time').build()
             ncmpServiceCmHandle.setCompositeState(compositeState)
         when: 'it is converted to a yang model cm handle'
-            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle,'')
+            def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle,'my-module-set-tag', 'my-alternate-id')
         then: 'the result has the right size'
             assert objectUnderTest.dmiProperties.size() == 1
+        and: 'the result has the correct values for module set tag and alternate ID'
+            assert objectUnderTest.moduleSetTag == 'my-module-set-tag'
+            assert objectUnderTest.alternateId == 'my-alternate-id'
         and: 'the DMI property in the result has the correct name and value'
             assert objectUnderTest.dmiProperties[0].name == 'myDmiProperty'
             assert objectUnderTest.dmiProperties[0].value == 'value1'
@@ -64,7 +67,7 @@ class YangModelCmHandleSpec extends Specification {
     def 'Resolve DMI service name: #scenario and #requiredService service require.'() {
         given: 'a yang model cm handle'
             def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName,
-                    dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'),'')
+                    dmiModelServiceName, new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1'),'', '')
         expect:
             assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService
         where:
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/NcmpServiceCmHandleSpec.groovy
deleted file mode 100644 (file)
index e42b914..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2023 Nordix Foundation
- *  ================================================================================
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *  SPDX-License-Identifier: Apache-2.0
- *  ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.models
-
-import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState
-import spock.lang.Specification
-
-class NcmpServiceCmHandleSpec extends Specification {
-
-
-    def 'NCMP Service CmHandle check for deep copy operation'() {
-        given: 'ncmp service cm handle'
-            def originalNcmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'cmhandleid',
-                dmiProperties: ['property1': 'value1', 'property2': 'value2'],
-                publicProperties: ['pubproperty1': 'value1', 'pubproperty2': 'value2'],
-                compositeState: new CompositeState(cmHandleState: CmHandleState.ADVISED, dataSyncEnabled: Boolean.FALSE))
-        when: 'we create a deep copy'
-            def deepCopiedNcmpServiceCmHandle = new NcmpServiceCmHandle(originalNcmpServiceCmHandle)
-        and: 'we change the original ncmp service cmhandle'
-            originalNcmpServiceCmHandle.dmiProperties = ['newProperty1': 'newValue1']
-            originalNcmpServiceCmHandle.publicProperties = ['newPublicProperty1': 'newPubValue1']
-            originalNcmpServiceCmHandle.compositeState = new CompositeState(cmHandleState: CmHandleState.DELETED, dataSyncEnabled: Boolean.TRUE)
-        then: 'no change in the copied dmi and public properties of ncmp service cmhandle'
-            deepCopiedNcmpServiceCmHandle.dmiProperties == ['property1': 'value1', 'property2': 'value2']
-            deepCopiedNcmpServiceCmHandle.publicProperties == ['pubproperty1': 'value1', 'pubproperty2': 'value2']
-        and: 'no change in the composite state'
-            deepCopiedNcmpServiceCmHandle.compositeState.cmHandleState == CmHandleState.ADVISED
-            deepCopiedNcmpServiceCmHandle.compositeState.dataSyncEnabled == Boolean.FALSE
-    }
-
-}
index 0d77530..b115f9a 100755 (executable)
@@ -34,6 +34,7 @@ import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -190,6 +191,21 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
         schemaSetRepository.deleteByDataspaceAndNameIn(dataspaceEntity, schemaSetNames);
     }
 
+
+    @Override
+    @Transactional
+    public void updateSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
+                                           final Map<String, String> newModuleNameToContentMap,
+                                           final Collection<ModuleReference> allModuleReferences) {
+        final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+        final SchemaSetEntity schemaSetEntity =
+            schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName);
+        storeAndLinkNewModules(newModuleNameToContentMap, schemaSetEntity);
+        updateAllModuleReferences(allModuleReferences, schemaSetEntity.getId());
+    }
+
+
+
     @Override
     @Transactional
     public void deleteUnusedYangResourceModules() {
@@ -364,4 +380,21 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
         return SchemaSet.builder().name(schemaSetEntity.getName())
                 .dataspaceName(schemaSetEntity.getDataspace().getName()).build();
     }
+
+    private void storeAndLinkNewModules(final Map<String, String> newModuleNameToContentMap,
+                                        final SchemaSetEntity schemaSetEntity) {
+        final Set<YangResourceEntity> yangResourceEntities
+            = new HashSet<>(synchronizeYangResources(newModuleNameToContentMap));
+        schemaSetEntity.setYangResources(yangResourceEntities);
+        schemaSetRepository.save(schemaSetEntity);
+    }
+
+    private void updateAllModuleReferences(final Collection<ModuleReference> allModuleReferences,
+                                           final Integer schemaSetEntityId) {
+        yangResourceRepository.deleteSchemaSetYangResourceForSchemaSetId(schemaSetEntityId);
+        final List<Integer> allYangResourceIds =
+            yangResourceRepository.getResourceIdsByModuleReferences(allModuleReferences);
+        yangResourceRepository.insertSchemaSetIdYangResourceId(schemaSetEntityId, allYangResourceIds);
+    }
+
 }
index e833796..3fec462 100644 (file)
@@ -108,6 +108,10 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
         return findAllModuleReferencesByDataspaceAndModuleNames(dataspaceName, moduleNames.toArray(new String[0]));
     }
 
+    @Modifying
+    @Query(value = "DELETE FROM schema_set_yang_resources WHERE schema_set_id = :schemaSetId", nativeQuery = true)
+    void deleteSchemaSetYangResourceForSchemaSetId(@Param("schemaSetId") int schemaSetId);
+
     @Modifying
     @Query(value = "DELETE FROM yang_resource yr WHERE NOT EXISTS "
         + "(SELECT 1 FROM schema_set_yang_resources ssyr WHERE ssyr.yang_resource_id = yr.id)", nativeQuery = true)
index 9696b28..3447a1c 100644 (file)
 package org.onap.cps.spi.impl
 
 import org.hibernate.exception.ConstraintViolationException
-import org.onap.cps.spi.CpsAdminPersistenceService
 import org.onap.cps.spi.CpsModulePersistenceService
+import org.onap.cps.spi.entities.SchemaSetEntity
 import org.onap.cps.spi.exceptions.DuplicatedYangResourceException
+import org.onap.cps.spi.model.ModuleReference
 import org.onap.cps.spi.repository.DataspaceRepository
 import org.onap.cps.spi.repository.ModuleReferenceRepository
 import org.onap.cps.spi.repository.SchemaSetRepository
 import org.onap.cps.spi.repository.YangResourceRepository
 import org.springframework.dao.DataIntegrityViolationException
 import spock.lang.Specification
-
 import java.sql.SQLException
 
 /**
@@ -39,11 +39,10 @@ class CpsModulePersistenceServiceSpec extends Specification {
 
     CpsModulePersistenceService objectUnderTest
 
-    def dataspaceRepositoryMock = Mock(DataspaceRepository)
-    def yangResourceRepositoryMock = Mock(YangResourceRepository)
-    def schemaSetRepositoryMock = Mock(SchemaSetRepository)
-    def cpsAdminPersistenceServiceMock = Mock(CpsAdminPersistenceService)
-    def moduleReferenceRepositoryMock = Mock(ModuleReferenceRepository)
+    def mockDataspaceRepository = Mock(DataspaceRepository)
+    def mockYangResourceRepository = Mock(YangResourceRepository)
+    def mockSchemaSetRepository = Mock(SchemaSetRepository)
+    def mockModuleReferenceRepository = Mock(ModuleReferenceRepository)
 
     def yangResourceName = 'my-yang-resource-name'
     def yangResourceContent = 'module stores {\n' +
@@ -68,15 +67,15 @@ class CpsModulePersistenceServiceSpec extends Specification {
     static otherIntegrityException = new DataIntegrityViolationException('another integrity exception')
 
     def setup() {
-        objectUnderTest = new CpsModulePersistenceServiceImpl(yangResourceRepositoryMock, schemaSetRepositoryMock,
-            dataspaceRepositoryMock, moduleReferenceRepositoryMock)
+        objectUnderTest = new CpsModulePersistenceServiceImpl(mockYangResourceRepository, mockSchemaSetRepository,
+            mockDataspaceRepository, mockModuleReferenceRepository)
     }
 
     def 'Store schema set error scenario: #scenario.'() {
         given: 'no yang resource are currently saved'
-            yangResourceRepositoryMock.findAllByChecksumIn(_ as Collection<String>) >> Collections.emptyList()
+            mockYangResourceRepository.findAllByChecksumIn(_ as Collection<String>) >> Collections.emptyList()
         and: 'persisting yang resource raises db constraint exception (in case of concurrent requests for example)'
-            yangResourceRepositoryMock.saveAll(_) >> { throw dbException }
+            mockYangResourceRepository.saveAll(_) >> { throw dbException }
         when: 'attempt to store schema set '
             def newYangResourcesNameToContentMap = [(yangResourceName):yangResourceContent]
             objectUnderTest.storeSchemaSet('my-dataspace', 'my-schema-set', newYangResourcesNameToContentMap)
@@ -90,4 +89,15 @@ class CpsModulePersistenceServiceSpec extends Specification {
             'other data failure'                | otherIntegrityException                   || DataIntegrityViolationException | 'another integrity exception'
     }
 
+    def 'Upgrade existing schema set'() {
+        given: 'old schema has empty yang resource'
+            mockYangResourceRepository.findAllByChecksumIn(_ as Collection<String>) >> Collections.emptyList()
+        def schemaSetEntity = new SchemaSetEntity(id: 1)
+            mockSchemaSetRepository.getByDataspaceAndName(_, _) >> schemaSetEntity
+        when: 'schema set update is requested'
+            objectUnderTest.updateSchemaSetFromModules('my-dataspace', 'my-schemaset', [:], [new ModuleReference('some module name', 'some revision name')])
+        then: 'no exception is thrown '
+            noExceptionThrown()
+    }
+
 }
index e8c3e77..2928464 100644 (file)
@@ -53,7 +53,7 @@ public interface CpsModuleService {
      * @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
      * @param allModuleReferences       All YANG resource module references
      */
-    void createOrUpgradeSchemaSetFromModules(String dataspaceName, String schemaSetName,
+    void createSchemaSetFromModules(String dataspaceName, String schemaSetName,
                                     Map<String, String> newModuleNameToContentMap,
                                     Collection<ModuleReference> allModuleReferences);
 
@@ -94,6 +94,19 @@ public interface CpsModuleService {
      */
     void deleteSchemaSetsWithCascade(String dataspaceName, Collection<String> schemaSetNames);
 
+
+    /**
+     * upgrade schema sets with existing or new modules.
+     *
+     * @param dataspaceName             dataspace name
+     * @param schemaSetName             schema set name
+     * @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
+     * @param allModuleReferences       All YANG resource module references
+     */
+    void upgradeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
+                                     final Map<String, String> newModuleNameToContentMap,
+                                     final Collection<ModuleReference> allModuleReferences);
+
     /**
      * Retrieve module references for the given dataspace name.
      *
index d274b51..5337237 100644 (file)
@@ -66,9 +66,9 @@ public class CpsModuleServiceImpl implements CpsModuleService {
     }
 
     @Override
-    public void createOrUpgradeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
-        final Map<String, String> newModuleNameToContentMap,
-        final Collection<ModuleReference> allModuleReferences) {
+    public void createSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
+                                           final Map<String, String> newModuleNameToContentMap,
+                                           final Collection<ModuleReference> allModuleReferences) {
         cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
         cpsModulePersistenceService.storeSchemaSetFromModules(dataspaceName, schemaSetName,
             newModuleNameToContentMap, allModuleReferences);
@@ -124,6 +124,17 @@ public class CpsModuleServiceImpl implements CpsModuleService {
         }
     }
 
+    @Override
+    public void upgradeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
+                                            final Map<String, String> newModuleNameToContentMap,
+                                            final Collection<ModuleReference> allModuleReferences) {
+        cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
+        cpsModulePersistenceService.updateSchemaSetFromModules(dataspaceName, schemaSetName,
+                newModuleNameToContentMap, allModuleReferences);
+        yangTextSchemaSourceSetCache.removeFromCache(dataspaceName, schemaSetName);
+    }
+
+
     @Override
     public Collection<ModuleReference> getYangResourceModuleReferences(final String dataspaceName) {
         cpsValidator.validateNameCharacters(dataspaceName);
index beb3d4f..aaca2ee 100755 (executable)
@@ -43,7 +43,7 @@ public interface CpsModulePersistenceService {
     void storeSchemaSet(String dataspaceName, String schemaSetName, Map<String, String> yangResourcesNameToContentMap);
 
     /**
-     * Stores a schema set from new modules and existing modules.
+     * Stores a new schema set from new modules and existing modules.
      *
      * @param dataspaceName             Dataspace name
      * @param schemaSetName             Schema set name
@@ -53,6 +53,19 @@ public interface CpsModulePersistenceService {
     void storeSchemaSetFromModules(String dataspaceName, String schemaSetName,
         Map<String, String> newModuleNameToContentMap, Collection<ModuleReference> allModuleReferences);
 
+    /**
+     * Update an existing schema set from new modules and existing modules.
+     *
+     * @param dataspaceName             Dataspace name
+     * @param schemaSetName             Schema set name
+     * @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
+     * @param allModuleReferences       All YANG resources module references
+     */
+    void updateSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
+                                    final Map<String, String> newModuleNameToContentMap,
+                                    final Collection<ModuleReference> allModuleReferences);
+
+
     /**
      * Get all schema sets for a given dataspace.
      *
index 61f6741..d8edb02 100644 (file)
@@ -23,6 +23,9 @@
 
 package org.onap.cps.api.impl
 
+import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
+import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
+
 import org.onap.cps.TestUtils
 import org.onap.cps.api.CpsAdminService
 import org.onap.cps.spi.CpsModulePersistenceService
@@ -38,8 +41,6 @@ import org.onap.cps.yang.TimedYangTextSchemaSourceSetBuilder
 import org.onap.cps.yang.YangTextSchemaSourceSet
 import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
 import spock.lang.Specification
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
 
 class CpsModuleServiceImplSpec extends Specification {
 
@@ -65,7 +66,7 @@ class CpsModuleServiceImplSpec extends Specification {
             def moduleReferenceForExistingModule = new ModuleReference('test',  '2021-10-12','test.org')
             def listOfExistingModulesModuleReference = [moduleReferenceForExistingModule]
         when: 'create schema set from modules method is invoked'
-            objectUnderTest.createOrUpgradeSchemaSetFromModules('someDataspaceName', 'someSchemaSetName', [newModule: 'newContent'], listOfExistingModulesModuleReference)
+            objectUnderTest.createSchemaSetFromModules('someDataspaceName', 'someSchemaSetName', [newModule: 'newContent'], listOfExistingModulesModuleReference)
         then: 'processing is delegated to persistence service'
             1 * mockCpsModulePersistenceService.storeSchemaSetFromModules('someDataspaceName', 'someSchemaSetName', [newModule: 'newContent'], listOfExistingModulesModuleReference)
         and: 'the CpsValidator is called on the dataspaceName and schemaSetName'
@@ -175,12 +176,6 @@ class CpsModuleServiceImplSpec extends Specification {
             thrown(SchemaSetInUseException)
     }
 
-    def createAnchors(int anchorCount) {
-        def anchors = []
-        (0..<anchorCount).each { anchors.add(new Anchor("my-anchor-$it", 'my-dataspace', 'my-schemaset')) }
-        return anchors
-    }
-
     def 'Delete multiple schema-sets when cascade is allowed.'() {
         given: '#numberOfAnchors anchors are associated with each schemaset'
             mockCpsAdminService.getAnchors('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2)
@@ -202,9 +197,16 @@ class CpsModuleServiceImplSpec extends Specification {
             numberOfAnchors << [0, 3]
     }
 
+    def 'Upgrade existing schema set'() {
+        when: 'schema set update is requested'
+        objectUnderTest.upgradeSchemaSetFromModules('my-dataspace', 'my-schemaset', [:], moduleReferences)
+        then: 'no exception is thrown '
+        noExceptionThrown()
+    }
+
     def 'Get all yang resources module references.'() {
         given: 'an already present module reference'
-            def moduleReferences = [new ModuleReference('some module name','some revision name')]
+            def moduleReferences = getModuleReferences()
             mockCpsModulePersistenceService.getYangResourceModuleReferences('someDataspaceName') >> moduleReferences
         when: 'get yang resource module references is called'
             def result = objectUnderTest.getYangResourceModuleReferences('someDataspaceName')
@@ -228,7 +230,7 @@ class CpsModuleServiceImplSpec extends Specification {
 
     def 'Identifying new module references.'(){
         given: 'module references from cm handle'
-            def moduleReferencesToCheck = [new ModuleReference('some-module', 'some-revision')]
+            def moduleReferencesToCheck = getModuleReferences()
         when: 'identifyNewModuleReferences is called'
             objectUnderTest.identifyNewModuleReferences(moduleReferencesToCheck)
         then: 'cps module persistence service is called with module references to check'
@@ -246,4 +248,14 @@ class CpsModuleServiceImplSpec extends Specification {
         and: 'the CpsValidator is called on the dataspaceName and schemaSetName'
             1 * mockCpsValidator.validateNameCharacters('some-dataspace-name', 'some-anchor-name')
     }
+
+    def getModuleReferences() {
+        return [new ModuleReference('some module name','some revision name')]
+    }
+
+    def createAnchors(int anchorCount) {
+        def anchors = []
+        (0..<anchorCount).each { anchors.add(new Anchor("my-anchor-$it", 'my-dataspace', 'my-schemaset')) }
+        return anchors
+    }
 }
index 3f9731d..5c72429 100644 (file)
@@ -84,6 +84,7 @@ public class DmiRestStubController {
         final String moduleResponseContent = ResourceFileReaderUtil
                 .getResourceFileContent(applicationContext.getResource(
                         ResourceLoader.CLASSPATH_URL_PREFIX + "module/moduleResponse.json"));
+        log.info("cm handle: {} requested for modules", cmHandle);
         return ResponseEntity.ok(moduleResponseContent);
     }
 
@@ -102,6 +103,7 @@ public class DmiRestStubController {
         final String moduleResourcesResponseContent = ResourceFileReaderUtil
                 .getResourceFileContent(applicationContext.getResource(
                         ResourceLoader.CLASSPATH_URL_PREFIX + "module/moduleResourcesResponse.json"));
+        log.info("cm handle: {} requested for module resources", cmHandle);
         return ResponseEntity.ok(moduleResourcesResponseContent);
     }
 
index 69eb9da..571c2ef 100644 (file)
@@ -7,47 +7,47 @@
        {
                "moduleName": "ietf-yang-types-2",
                "revision": "2013-07-16",
-               "yangSource": "module ietf-yang-types-2 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-2\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-2 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-2\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-16 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-3",
                "revision": "2013-07-17",
-               "yangSource": "module ietf-yang-types-3 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-3\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-3 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-3\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-17 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-4",
                "revision": "2013-07-18",
-               "yangSource": "module ietf-yang-types-4 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-4\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-4 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-4\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-18 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-5",
                "revision": "2013-07-19",
-               "yangSource": "module ietf-yang-types-5 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-5\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-5 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-5\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-19 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-6",
                "revision": "2013-07-20",
-               "yangSource": "module ietf-yang-types-6 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-6\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-6 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-6\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-20 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-7",
                "revision": "2013-07-21",
-               "yangSource": "module ietf-yang-types-7 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-7\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-7 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-7\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-21 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-8",
                "revision": "2013-07-22",
-               "yangSource": "module ietf-yang-types-8 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-8\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-8 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-8\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-22 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-9",
                "revision": "2013-07-23",
-               "yangSource": "module ietf-yang-types-9 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-9\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-9 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-9\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-23 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        },
        {
                "moduleName": "ietf-yang-types-10",
                "revision": "2013-07-24",
-               "yangSource": "module ietf-yang-types-10 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-10\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-15 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
+               "yangSource": "module ietf-yang-types-10 {\n\n  namespace \"urn:ietf:params:xml:ns:yang:ietf-yang-types-10\";\n  prefix \"yang\";\n\n  organization\n   \"IETF NETMOD (NETCONF Data Modeling Language) Working Group\";\n\n  contact\n   \"WG Web:   <http://tools.ietf.org/wg/netmod/>\n    WG List:  <mailto:netmod@ietf.org>\n\n    WG Chair: David Kessens\n              <mailto:david.kessens@nsn.com>\n\n    WG Chair: Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\n\n    Editor:   Juergen Schoenwaelder\n              <mailto:j.schoenwaelder@jacobs-university.de>\";\n\n  description\n   \"This module contains a collection of generally useful derived\n    YANG data types.\n\n    Copyright (c) 2013 IETF Trust and the persons identified as\n    authors of the code.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or\n    without modification, is permitted pursuant to, and subject\n    to the license terms contained in, the Simplified BSD License\n    set forth in Section 4.c of the IETF Trust's Legal Provisions\n    Relating to IETF Documents\n    (http://trustee.ietf.org/license-info).\n\n    This version of this YANG module is part of RFC 6991; see\n    the RFC itself for full legal notices.\";\n\n  revision 2013-07-24 {\n    description\n     \"This revision adds the following new data types:\n      - yang-identifier\n      - hex-string\n      - uuid\n      - dotted-quad\";\n    reference\n     \"RFC 6991: Common YANG Data Types\";\n  }\n\n  revision 2010-09-24 {\n    description\n     \"Initial revision.\";\n    reference\n     \"RFC 6021: Common YANG Data Types\";\n  }\n\n  /*** collection of counter and gauge types ***/\n\n  typedef counter32 {\n    type uint32;\n    description\n     \"The counter32 type represents a non-negative integer\n      that monotonically increases until it reaches a\n      maximum value of 2^32-1 (4294967295 decimal), when it\n      wraps around and starts increasing again from zero.\n\n      Counters have no defined 'initial' value, and thus, a\n      single value of a counter has (in general) no information\n      content.  Discontinuities in the monotonically increasing\n      value normally occur at re-initialization of the\n      management system, and at other times as specified in the\n      description of a schema node using this type.  If such\n      other times can occur, for example, the creation of\n      a schema node of type counter32 at times other than\n      re-initialization, then a corresponding schema node\n      should be defined, with an appropriate type, to indicate\n      the last discontinuity.\n\n      The counter32 type should not be used for configuration\n      schema nodes.  A default statement SHOULD NOT be used in\n      combination with the type counter32.\n\n      In the value set and its semantics, this type is equivalent\n      to the Counter32 type of the SMIv2.\";\n    reference\n     \"RFC 2578: Structure of Management Information Version 2\n                (SMIv2)\";\n  }\n}\n"
        }
 ]
 
index d33a774..2e1b082 100644 (file)
@@ -52,6 +52,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
 
     def newYangResourcesNameToContentMap = [:]
     def moduleReferences = []
+    def noNewModules = [:]
 
     def setup() {
         objectUnderTest = cpsModuleService
@@ -94,7 +95,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
             moduleReferences.addAll(existingModuleReferences)
         when: 'the new schema set is created'
             def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules"
-            objectUnderTest.createOrUpgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
+            objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
         and: 'associated with a new anchor'
             cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor')
         then: 'the new anchor has the correct number of modules'
@@ -261,16 +262,75 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
             'schema set does not exists' | FUNCTIONAL_TEST_DATASPACE_1 | 'unknown'       || SchemaSetNotFoundException
     }
 
+    /*
+        U P G R A D E
+     */
+
+    def 'Upgrade schema set (with existing and new modules, no matching module set tag in NCMP)'() {
+        given: 'an anchor and schema set with 2 modules (to be upgraded)'
+            populateNewYangResourcesNameToContentMapAndAllModuleReferences('original', 2)
+            objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
+            cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+            def yangResourceModuleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+            assert yangResourceModuleReferencesBeforeUpgrade.size() == 2
+            assert yangResourceModuleReferencesBeforeUpgrade.containsAll([new ModuleReference('original_0','2000-01-01'),new ModuleReference('original_1','2001-01-01')])
+        and: 'two new 2 modules (from node)'
+            populateNewYangResourcesNameToContentMapAndAllModuleReferences('new', 2)
+            def newModuleReferences = [new ModuleReference('new_0','2000-01-01'),new ModuleReference('new_1','2001-01-01')]
+        and: 'a list of all module references (normally retrieved from node)'
+            def allModuleReferences = []
+            allModuleReferences.add(existingModuleReference)
+            allModuleReferences.addAll(newModuleReferences)
+        when: 'the schema set is upgraded'
+            objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, allModuleReferences)
+        then: 'the new anchor has the correct new and existing modules'
+            def yangResourceModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+            assert yangResourceModuleReferencesAfterUpgrade.size() == 3
+            assert yangResourceModuleReferencesAfterUpgrade.contains(existingModuleReference)
+            assert yangResourceModuleReferencesAfterUpgrade.containsAll(newModuleReferences);
+        cleanup:
+            objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
+    }
+    
+    def 'Upgrade existing schema set from another anchor (used in NCMP for matching module set tag)'() {
+        given: 'an anchor and schema set with 1 module (target)'
+            populateNewYangResourcesNameToContentMapAndAllModuleReferences('target', 1)
+            objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
+            cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+            def moduleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+            assert moduleReferencesBeforeUpgrade.size() == 1
+        and: 'another anchor and schema set with 2 other modules (source for upgrade)'
+            populateNewYangResourcesNameToContentMapAndAllModuleReferences('source', 2)
+            objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', newYangResourcesNameToContentMap, [])
+            cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
+            assert objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor').size() == 2
+        when: 'the target schema is upgraded using the module references from the source anchor'
+            def moduleReferencesFromSourceAnchor = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor')
+            objectUnderTest.upgradeSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', noNewModules, moduleReferencesFromSourceAnchor)
+        then: 'the target schema now refers to the source modules (with namespace) modules'
+            def schemaSetModuleReferencesAfterUpgrade = getObjectUnderTest().getSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema').moduleReferences
+            assert schemaSetModuleReferencesAfterUpgrade.containsAll([new ModuleReference('source_0','2000-01-01','org:onap:ccsdk:sample'),new ModuleReference('source_1','2001-01-01','org:onap:ccsdk:sample')]);
+        and: 'the associated target anchor has the same module references (without namespace but that is a legacy issue)'
+            def anchorModuleReferencesAfterUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
+            assert anchorModuleReferencesAfterUpgrade.containsAll([new ModuleReference('source_0','2000-01-01'),new ModuleReference('source_1','2001-01-01')]);
+        cleanup:
+            objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['sourceSchema', 'targetSchema'])
+    }
+
     /*
         H E L P E R   M E T H O D S
      */
 
     def populateNewYangResourcesNameToContentMapAndAllModuleReferences(numberOfModules) {
+        populateNewYangResourcesNameToContentMapAndAllModuleReferences('name', numberOfModules)
+    }
+
+    def populateNewYangResourcesNameToContentMapAndAllModuleReferences(namePrefix, numberOfModules) {
         numberOfModules.times {
-            def uniqueName = 'name_' + it
+            def uniqueName = namePrefix + '_' + it
             def uniqueRevision = String.valueOf(2000 + it) + '-01-01'
             moduleReferences.add(new ModuleReference(uniqueName, uniqueRevision))
-            def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision)
+            def uniqueContent = NEW_RESOURCE_CONTENT.replace(NEW_RESOURCE_REVISION, uniqueRevision).replace('module test_module', 'module '+uniqueName)
             newYangResourcesNameToContentMap.put(uniqueRevision, uniqueContent)
         }
     }