TEIV: yang-parser updates 17/14117/1
authorJvD_Ericsson <jeff.van.dam@est.tech>
Mon, 27 Jan 2025 13:56:39 +0000 (13:56 +0000)
committerJvD_Ericsson <jeff.van.dam@est.tech>
Mon, 27 Jan 2025 13:56:43 +0000 (13:56 +0000)
Issue-ID: SMO-177
Change-Id: Id24d75f4f80e666e95b450910e9125ae9984286b
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
13 files changed:
teiv/src/test/resources/contracts/exposure/schemas/02_postSchemas.groovy
teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy [deleted file]
teiv/src/test/resources/contracts/schemas/01_getSchemaContent.groovy [deleted file]
teiv/src/test/resources/contracts/schemas/02_postSchemas.groovy [deleted file]
teiv/src/test/resources/contracts/schemas/03_deleteSchemas.groovy [deleted file]
yang-parser/src/main/java/org/oran/smo/yangtools/parser/findings/ParserFindingType.java
yang-parser/src/main/java/org/oran/smo/yangtools/parser/model/YangModel.java
yang-parser/src/main/java/org/oran/smo/yangtools/parser/model/schema/Schema.java
yang-parser/src/test/java/org/oran/smo/yangtools/parser/model/statements/yang/test/NamespaceTest.java [new file with mode: 0644]
yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsA.yang [new file with mode: 0644]
yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsB.yang [new file with mode: 0644]
yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsA.yang [new file with mode: 0644]
yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsB.yang [new file with mode: 0644]

index 1823d82..949cc6b 100644 (file)
@@ -642,7 +642,7 @@ import org.springframework.cloud.contract.spec.Contract
                     p('module o-ran-smo-teiv-ran { ' +
                     '  ' +
                     '  yang-version 1.1; ' +
-                    '  namespace "urn:o-ran-smo-teiv-ran"; ' +
+                    '  namespace "urn:o-ran:smo-teiv-ran"; ' +
                     '  prefix module; ' +
                     '   ' +
                     '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
diff --git a/teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy b/teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy
deleted file mode 100644 (file)
index 729b26b..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 Ericsson
- *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
- *  ================================================================================
- *  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 contracts.schemas
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [
-                    {
-                        "name": "_3gpp-common-yang-extensions",
-                        "domain": "",
-                        "revision": "2019-06-23",
-                        "content": {
-                            "href": "/schemas/_3gpp-common-yang-extensions/content"
-                        }
-                    },
-                    {
-                        "name": "_3gpp-common-yang-types",
-                        "domain": "",
-                        "revision": "2022-07-26",
-                        "content": {
-                            "href": "/schemas/_3gpp-common-yang-types/content"
-                        }
-                    },
-                    {
-                        "name": "ietf-geo-location",
-                        "domain": "",
-                        "revision": "2022-02-11",
-                        "content": {
-                            "href": "/schemas/ietf-geo-location/content"
-                        }
-                    },
-                    {
-                        "name": "ietf-inet-types",
-                        "domain": "",
-                        "revision": "2013-07-15",
-                        "content": {
-                            "href": "/schemas/ietf-inet-types/content"
-                        }
-                    },
-                    {
-                        "name": "ietf-yang-types",
-                        "domain": "",
-                        "revision": "2013-07-15",
-                        "content": {
-                            "href": "/schemas/ietf-yang-types/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-cloud",
-                        "domain": "CLOUD",
-                        "revision": "2024-10-04",
-                        "content": {
-                        "href": "/schemas/o-ran-smo-teiv-cloud/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-common-yang-extensions",
-                        "domain": "",
-                        "revision": "2024-05-24",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-common-yang-extensions/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-common-yang-types",
-                        "domain": "",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-common-yang-types/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-equipment",
-                        "domain": "EQUIPMENT",
-                        "revision": "2024-10-21",
-                        "content": {
-                        "href": "/schemas/o-ran-smo-teiv-equipment/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-oam",
-                        "domain": "OAM",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-oam/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-ran",
-                        "domain": "RAN",
-                        "revision": "2024-10-08",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-cloud-ran",
-                        "domain": "REL_CLOUD_RAN",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-cloud-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-equipment-ran",
-                        "domain": "REL_EQUIPMENT_RAN",
-                        "revision": "2024-10-08",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-equipment-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-oam-cloud",
-                        "domain": "REL_OAM_CLOUD",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-oam-cloud/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-oam-ran",
-                        "domain": "REL_OAM_RAN",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-oam-ran/content"
-                        }
-                    },
-                    {
-                        "name": "test-existing-rapp-module",
-                        "domain": "",
-                        "revision": "2024-05-02",
-                        "content": {
-                            "href": "/schemas/test-existing-rapp-module/content"
-                        }
-                    },
-                    {
-                        "name": "test-module-for-deletion",
-                        "domain": "",
-                        "revision": "2024-05-02",
-                        "content": {
-                            "href": "/schemas/test-module-for-deletion/content"
-                        }
-                    },
-                    {
-                        "name":"test-module-in-deleting-state",
-                        "domain":"",
-                        "revision":"2024-05-02",
-                        "content":{
-                          "href":"/schemas/test-module-in-deleting-state/content"
-                        }
-                    },
-                    {
-                        "name":"module-rapp-module",
-                        "domain":"",
-                        "revision":"2024-05-01",
-                        "content":{
-                          "href":"/schemas/module-rapp-module/content"
-                        }
-                    },
-                    {
-                        "name": "test-built-in-module",
-                        "domain": "TEST",
-                        "revision": "2024-05-24",
-                        "content": {
-                            "href": "/schemas/test-built-in-module/content"
-                        }
-                    },
-                    {
-                        "name": "test-app-module",
-                        "domain": "",
-                        "revision": "2024-05-24",
-                        "content": {
-                            "href": "/schemas/test-app-module/content"
-                        }
-                    },
-                    {
-                        "name": "test-app-for-deletion-module",
-                        "domain": "",
-                        "revision": "2024-05-24",
-                        "content": {
-                            "href": "/schemas/test-app-for-deletion-module/content"
-                        }
-                    }
-                ],
-                "self": {
-                    "href": "/schemas?offset=0&limit=500"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=500"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=500"
-                },
-                "next": {
-                    "href": "/schemas?offset=0&limit=500"
-                },
-                "last": {
-                    "href": "/schemas?offset=0&limit=500"
-                },
-                "totalCount": 22
-            }''')
-            bodyMatchers {
-                jsonPath('$.items', byType {
-                    occurrence(22)
-                })
-                jsonPath('$.items[0].name', byEquality())
-                jsonPath('$.items[0].domain', byEquality())
-                jsonPath('$.items[0].revision', byEquality())
-                jsonPath('$.items[0].content.href', byEquality())
-                jsonPath('$.items[1].name', byEquality())
-                jsonPath('$.items[1].domain', byEquality())
-                jsonPath('$.items[1].revision', byEquality())
-                jsonPath('$.items[1].content.href', byEquality())
-                jsonPath('$.items[2].name', byEquality())
-                jsonPath('$.items[2].domain', byEquality())
-                jsonPath('$.items[2].revision', byEquality())
-                jsonPath('$.items[2].content.href', byEquality())
-                jsonPath('$.items[3].name', byEquality())
-                jsonPath('$.items[3].domain', byEquality())
-                jsonPath('$.items[3].revision', byEquality())
-                jsonPath('$.items[3].content.href', byEquality())
-                jsonPath('$.items[4].name', byEquality())
-                jsonPath('$.items[4].domain', byEquality())
-                jsonPath('$.items[4].revision', byEquality())
-                jsonPath('$.items[4].content.href', byEquality())
-                jsonPath('$.items[5].name', byEquality())
-                jsonPath('$.items[5].domain', byEquality())
-                jsonPath('$.items[5].revision', byEquality())
-                jsonPath('$.items[5].content.href', byEquality())
-                jsonPath('$.items[6].name', byEquality())
-                jsonPath('$.items[6].domain', byEquality())
-                jsonPath('$.items[6].revision', byEquality())
-                jsonPath('$.items[6].content.href', byEquality())
-                jsonPath('$.items[7].name', byEquality())
-                jsonPath('$.items[7].domain', byEquality())
-                jsonPath('$.items[7].revision', byEquality())
-                jsonPath('$.items[7].content.href', byEquality())
-                jsonPath('$.items[8].name', byEquality())
-                jsonPath('$.items[8].domain', byEquality())
-                jsonPath('$.items[8].revision', byEquality())
-                jsonPath('$.items[8].content.href', byEquality())
-                jsonPath('$.items[9].name', byEquality())
-                jsonPath('$.items[9].domain', byEquality())
-                jsonPath('$.items[9].revision', byEquality())
-                jsonPath('$.items[9].content.href', byEquality())
-                jsonPath('$.items[10].name', byEquality())
-                jsonPath('$.items[10].domain', byEquality())
-                jsonPath('$.items[10].revision', byEquality())
-                jsonPath('$.items[10].content.href', byEquality())
-                jsonPath('$.items[11].name', byEquality())
-                jsonPath('$.items[11].domain', byEquality())
-                jsonPath('$.items[11].revision', byEquality())
-                jsonPath('$.items[11].content.href', byEquality())
-                jsonPath('$.items[12].name', byEquality())
-                jsonPath('$.items[12].domain', byEquality())
-                jsonPath('$.items[12].revision', byEquality())
-                jsonPath('$.items[12].content.href', byEquality())
-                jsonPath('$.items[13].name', byEquality())
-                jsonPath('$.items[13].domain', byEquality())
-                jsonPath('$.items[13].revision', byEquality())
-                jsonPath('$.items[13].content.href', byEquality())
-                jsonPath('$.items[14].name', byEquality())
-                jsonPath('$.items[14].domain', byEquality())
-                jsonPath('$.items[14].revision', byEquality())
-                jsonPath('$.items[14].content.href', byEquality())
-                jsonPath('$.items[16].name', byEquality())
-                jsonPath('$.items[16].domain', byEquality())
-                jsonPath('$.items[16].revision', byEquality())
-                jsonPath('$.items[16].content.href', byEquality())
-                jsonPath('$.items[17].name', byEquality())
-                jsonPath('$.items[17].domain', byEquality())
-                jsonPath('$.items[17].revision', byEquality())
-                jsonPath('$.items[17].content.href', byEquality())
-                jsonPath('$.items[18].name', byEquality())
-                jsonPath('$.items[18].domain', byEquality())
-                jsonPath('$.items[18].revision', byEquality())
-                jsonPath('$.items[18].content.href', byEquality())
-                jsonPath('$.items[19].name', byEquality())
-                jsonPath('$.items[19].domain', byEquality())
-                jsonPath('$.items[19].revision', byEquality())
-                jsonPath('$.items[19].content.href', byEquality())
-                jsonPath('$.items[20].name', byEquality())
-                jsonPath('$.items[20].domain', byEquality())
-                jsonPath('$.items[20].revision', byEquality())
-                jsonPath('$.items[20].content.href', byEquality())
-                jsonPath('$.items[21].name', byEquality())
-                jsonPath('$.items[21].domain', byEquality())
-                jsonPath('$.items[21].revision', byEquality())
-                jsonPath('$.items[21].content.href', byEquality())
-            }
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas with offset as 0 and limit as 1."
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?offset=0&limit=1")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [
-                    {
-                        "name": "_3gpp-common-yang-extensions",
-                        "domain": "",
-                        "revision": "2019-06-23",
-                        "content": {
-                            "href": "/schemas/_3gpp-common-yang-extensions/content"
-                        }
-                    }
-                ],
-                "self": {
-                    "href": "/schemas?offset=0&limit=1"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=1"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=1"
-                },
-                "next": {
-                    "href": "/schemas?offset=1&limit=1"
-                },
-                "last": {
-                    "href": "/schemas?offset=21&limit=1"
-                },
-                "totalCount": 22
-            }''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas with offset as 3 and limit as 3."
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?offset=3&limit=3")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [
-                    {
-                        "name": "ietf-inet-types",
-                        "domain": "",
-                        "revision": "2013-07-15",
-                        "content": {
-                            "href": "/schemas/ietf-inet-types/content"
-                        }
-                    },
-                    {
-                        "name": "ietf-yang-types",
-                        "domain": "",
-                        "revision": "2013-07-15",
-                        "content": {
-                            "href": "/schemas/ietf-yang-types/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-cloud",
-                        "domain": "CLOUD",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-cloud/content"
-                        }
-                    }
-                ],
-                "self": {
-                    "href": "/schemas?offset=3&limit=3"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=3"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=3"
-                },
-                "next": {
-                    "href": "/schemas?offset=6&limit=3"
-                },
-                "last": {
-                    "href": "/schemas?offset=21&limit=3"
-                },
-                "totalCount": 22
-            }''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas with RAN domain"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=RAN&offset=0&limit=100")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [
-                    {
-                        "name": "o-ran-smo-teiv-ran",
-                        "domain": "RAN",
-                        "revision": "2024-10-08",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-ran/content"
-                        }
-                    }
-                ],
-                "self": {
-                    "href": "/schemas?offset=0&limit=100&domain=RAN"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=100&domain=RAN"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=100&domain=RAN"
-                },
-                "next": {
-                    "href": "/schemas?offset=0&limit=100&domain=RAN"
-                },
-                "last": {
-                    "href": "/schemas?offset=0&limit=100&domain=RAN"
-                },
-                "totalCount": 1
-            }''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas with domain name containing RAN"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=.*RAN.*")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [
-                    {
-                        "name": "o-ran-smo-teiv-rel-oam-ran",
-                        "domain": "REL_OAM_RAN",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-oam-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-cloud-ran",
-                        "domain": "REL_CLOUD_RAN",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-cloud-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-ran",
-                        "domain": "RAN",
-                        "revision": "2024-10-08",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-ran/content"
-                        }
-                    },
-                    {
-                        "name": "o-ran-smo-teiv-rel-equipment-ran",
-                        "domain": "REL_EQUIPMENT_RAN",
-                        "revision": "2024-10-04",
-                        "content": {
-                            "href": "/schemas/o-ran-smo-teiv-rel-equipment-ran/content"
-                        }
-                    }
-                ],
-                "self": {
-                    "href": "/schemas?offset=0&limit=500&domain=.*RAN.*"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=500&domain=.*RAN.*"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=500&domain=.*RAN.*"
-                },
-                "next": {
-                    "href": "/schemas?offset=0&limit=500&domain=.*RAN.*"
-                },
-                "last": {
-                    "href": "/schemas?offset=0&limit=500&domain=.*RAN.*"
-                },
-                "totalCount": 4
-            }''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas with invalid domain"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=INVALID")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "items": [],
-                "self": {
-                    "href": "/schemas?offset=0&limit=500&domain=INVALID"
-                },
-                "first": {
-                    "href": "/schemas?offset=0&limit=500&domain=INVALID"
-                },
-                "prev": {
-                    "href": "/schemas?offset=0&limit=500&domain=INVALID"
-                },
-                "next": {
-                    "href": "/schemas?offset=0&limit=500&domain=INVALID"
-                },
-                "last": {
-                    "href": "/schemas?offset=0&limit=500&domain=INVALID"
-                },
-                "totalCount": 0
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Get a list of all schemas with offset greater than totalCount"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=RAN.*&offset=100")
-        }
-        response {
-            status BAD_REQUEST()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid Value",
-                "details": "Offset cannot be larger than 0"
-            }''')
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/schemas/01_getSchemaContent.groovy b/teiv/src/test/resources/contracts/schemas/01_getSchemaContent.groovy
deleted file mode 100644 (file)
index 2a6ba12..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 Ericsson
- *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
- *  ================================================================================
- *  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 contracts.schemas
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get schema with name o-ran-smo-teiv-rel-oam-ran"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas/o-ran-smo-teiv-rel-oam-ran/content")
-        }
-        response {
-            status OK()
-            body("module o-ran-smo-teiv-rel-oam-ran {\n" +
-                    "    yang-version 1.1;\n" +
-                    "    namespace \"urn:o-ran:smo-teiv-rel-oam-ran\";\n" +
-                    "    prefix or-teiv-rel-oamran;\n" +
-                    "\n" +
-                    "    import o-ran-smo-teiv-common-yang-types { prefix or-teiv-types; }\n" +
-                    "\n" +
-                    "    import o-ran-smo-teiv-common-yang-extensions { prefix or-teiv-yext; }\n" +
-                    "\n" +
-                    "    import o-ran-smo-teiv-oam { prefix or-teiv-oam; }\n" +
-                    "\n" +
-                    "    import o-ran-smo-teiv-ran { prefix or-teiv-ran; }\n" +
-                    "\n" +
-                    "    organization \"ORAN\";\n" +
-                    "    contact \"The Authors\";\n" +
-                    "    description\n" +
-                    "        \"RAN O&M to Logical topology model.\n" +
-                    "\n" +
-                    "        This model contains the RAN O&M to Logical topology relations\n" +
-                    "\n" +
-                    "        Copyright (C) 2024 Ericsson\n" +
-                    "        Modifications Copyright (C) 2024 OpenInfra Foundation Europe\n" +
-                    "\n" +
-                    "        Licensed under the Apache License, Version 2.0 (the \\\"License\\\");\n" +
-                    "        you may not use this file except in compliance with the License.\n" +
-                    "        You may obtain a copy of the License at\n" +
-                    "\n" +
-                    "        http://www.apache.org/licenses/LICENSE-2.0\n" +
-                    "\n" +
-                    "        Unless required by applicable law or agreed to in writing, software\n" +
-                    "        distributed under the License is distributed on an \\\"AS IS\\\" BASIS,\n" +
-                    "        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
-                    "        See the License for the specific language governing permissions and\n" +
-                    "        limitations under the License.\n" +
-                    "\n" +
-                    "        SPDX-License-Identifier: Apache-2.0\";\n" +
-                    "\n" +
-                    "    revision \"2024-10-04\" {\n" +
-                    "        description \"Added grouping, Origin_Relationship_Mapping_Grp to the topology object.\";\n" +
-                    "        or-teiv-yext:label 0.5.0;\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    revision \"2024-07-15\" {\n" +
-                    "        description \"This revision aligns O-RAN Work Group 10 Stage 2 Specification (O-RAN.WG10.TE&IV-CIMI.0-R004.v02.00)\";\n" +
-                    "        or-teiv-yext:label 0.4.0;\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    revision \"2024-05-24\" {\n" +
-                    "        description \"Initial revision.\";\n" +
-                    "        or-teiv-yext:label 0.3.0;\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    or-teiv-yext:domain REL_OAM_RAN;\n" +
-                    "\n" +
-                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_ODUFUNCTION {    // 1 to 0..n\n" +
-                    "\n" +
-                    "        description\n" +
-                    "            \"The aSide of this relationship is an instance of the ManagedElement type.\n" +
-                    "            The bSide of this relationship is an instance of the ODUFunction type.\n" +
-                    "            The ManagedElement represents the node that manages the ODUFunction.\n" +
-                    "            A ManagedElement instance can manage many ODUFunctions.\n" +
-                    "            An ODUFunction instance must be managed by one ManagedElement.\n" +
-                    "            \";\n" +
-                    "\n" +
-                    "        uses or-teiv-types:Top_Grp_Type;\n" +
-                    "        uses or-teiv-types:Origin_Relationship_Mapping_Grp;\n" +
-                    "        key id;\n" +
-                    "\n" +
-                    "        leaf-list managed-oduFunction {\n" +
-                    "            description \"Managed Element manages O-DU Function.\";\n" +
-                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
-                    "            type instance-identifier;\n" +
-                    "        }\n" +
-                    "\n" +
-                    "        leaf managed-by-managedElement {\n" +
-                    "            description \"O-DU Function managed by Managed Element.\";\n" +
-                    "            or-teiv-yext:bSide or-teiv-ran:ODUFunction;\n" +
-                    "            type instance-identifier;\n" +
-                    "            mandatory true;\n" +
-                    "        }\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_OCUCPFUNCTION {    // 1 to 0..n\n" +
-                    "\n" +
-                    "        description\n" +
-                    "            \"The aSide of this relationship is an instance of the ManagedElement type.\n" +
-                    "            The bSide of this relationship is an instance of the OCUCPFunction type.\n" +
-                    "            The ManagedElement represents the node that manages the OCUCPFunction.\n" +
-                    "            A ManagedElement instance can manage many OCUCPFunctions.\n" +
-                    "            An OCUCPFunction instance must be managed by one ManagedElement.\n" +
-                    "            \";\n" +
-                    "\n" +
-                    "        uses or-teiv-types:Top_Grp_Type;\n" +
-                    "        uses or-teiv-types:Origin_Relationship_Mapping_Grp;\n" +
-                    "        key id;\n" +
-                    "\n" +
-                    "        leaf-list managed-ocucpFunction {\n" +
-                    "            description \"Managed Element manages O-CU-CP Function.\";\n" +
-                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
-                    "            type instance-identifier;\n" +
-                    "        }\n" +
-                    "\n" +
-                    "        leaf managed-by-managedElement {\n" +
-                    "            description \"O-CU-CP Function managed by Managed Element.\";\n" +
-                    "            or-teiv-yext:bSide or-teiv-ran:OCUCPFunction;\n" +
-                    "            type instance-identifier;\n" +
-                    "            mandatory true;\n" +
-                    "        }\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_OCUUPFUNCTION {    // 1 to 0..n\n" +
-                    "\n" +
-                    "        description\n" +
-                    "            \"The aSide of this relationship is an instance of the ManagedElement type.\n" +
-                    "            The bSide of this relationship is an instance of the OCUUPFunction type.\n" +
-                    "            The ManagedElement represents the node that manages the OCUUPFunction.\n" +
-                    "            A ManagedElement instance can manage many OCUUPFunctions.\n" +
-                    "            An OCUUPFunction instance must be managed by one ManagedElement.\n" +
-                    "            \";\n" +
-                    "\n" +
-                    "        uses or-teiv-types:Top_Grp_Type;\n" +
-                    "        uses or-teiv-types:Origin_Relationship_Mapping_Grp;\n" +
-                    "        key id;\n" +
-                    "\n" +
-                    "        leaf-list managed-ocuupFunction {\n" +
-                    "            description \"Managed Element manages O-CU-UP Function.\";\n" +
-                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
-                    "            type instance-identifier;\n" +
-                    "        }\n" +
-                    "\n" +
-                    "        leaf managed-by-managedElement {\n" +
-                    "            description \"O-CU-UP Function managed by Managed Element.\";\n" +
-                    "            or-teiv-yext:bSide or-teiv-ran:OCUUPFunction;\n" +
-                    "            type instance-identifier;\n" +
-                    "            mandatory true;\n" +
-                    "        }\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_ORUFUNCTION {    // 1 to 0..n\n" +
-                    "\n" +
-                    "        description\n" +
-                    "            \"The aSide of this relationship is an instance of the ManagedElement type.\n" +
-                    "            The bSide of this relationship is an instance of the ORUFunction type.\n" +
-                    "            The ManagedElement represents the node that manages the ORUFunction.\n" +
-                    "            A ManagedElement instance can manage many ORUFunction.\n" +
-                    "            An ORUFunction instance must be managed by one ManagedElement.\n" +
-                    "            \";\n" +
-                    "\n" +
-                    "        uses or-teiv-types:Top_Grp_Type;\n" +
-                    "        uses or-teiv-types:Origin_Relationship_Mapping_Grp;\n" +
-                    "        key id;\n" +
-                    "\n" +
-                    "        leaf-list managed-oruFunction {\n" +
-                    "            description \"Managed Element manages O-RU Function.\";\n" +
-                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
-                    "            type instance-identifier;\n" +
-                    "        }\n" +
-                    "\n" +
-                    "        leaf managed-by-managedElement {\n" +
-                    "            description \"O-RU Function managed by Managed Element.\";\n" +
-                    "            or-teiv-yext:bSide or-teiv-ran:ORUFunction;\n" +
-                    "            type instance-identifier;\n" +
-                    "            mandatory true;\n" +
-                    "        }\n" +
-                    "    }\n" +
-                    "\n" +
-                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_NEARRTRICFUNCTION {    // 1 to 0..n\n" +
-                    "\n" +
-                    "        description\n" +
-                    "            \"The aSide of this relationship is an instance of the ManagedElement type.\n" +
-                    "            The bSide of this relationship is an instance of the NearRTRICFunction type.\n" +
-                    "            The ManagedElement represents the node that manages the NearRTRICFunction.\n" +
-                    "            A ManagedElement instance can manage many NearRTRICFunction.\n" +
-                    "            An NearRTRICFunction instance must be managed by one ManagedElement.\n" +
-                    "            \";\n" +
-                    "\n" +
-                    "        uses or-teiv-types:Top_Grp_Type;\n" +
-                    "        uses or-teiv-types:Origin_Relationship_Mapping_Grp;\n" +
-                    "        key id;\n" +
-                    "\n" +
-                    "        leaf-list managed-nearRTRICFunction {\n" +
-                    "            description \"Managed Element manages Near RT RIC Function.\";\n" +
-                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
-                    "            type instance-identifier;\n" +
-                    "        }\n" +
-                    "\n" +
-                    "        leaf managed-by-managedElement {\n" +
-                    "            description \"Near RT RIC Function managed by Managed Element.\";\n" +
-                    "            or-teiv-yext:bSide or-teiv-ran:NearRTRICFunction;\n" +
-                    "            type instance-identifier;\n" +
-                    "            mandatory true;\n" +
-                    "        }\n" +
-                    "    }\n" +
-                    "}")
-            headers {
-                contentType('text/plain')
-            }
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Get schema content with invalid name invalid"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas/invalid/content")
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid schema name",
-                    "details": "Invalid schema name: invalid"
-                }''')
-            headers {
-                contentType('application/json')
-            }
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/schemas/02_postSchemas.groovy b/teiv/src/test/resources/contracts/schemas/02_postSchemas.groovy
deleted file mode 100644 (file)
index b2506ec..0000000
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 Ericsson
- *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
- *  ================================================================================
- *  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 contracts.schemas
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 201: Create a new classifiers + decorators schema with name module-rapp-model1"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model1 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model1"; ' +
-                    '  prefix model1; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status CREATED()
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 201: Create a new decorators without classifier schema with name module-rapp-model2"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model2 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model2"; ' +
-                    '  prefix model2; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    ' ' +
-                    '}'))))
-        }
-        response {
-            status CREATED()
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 201: Create a new classifiers without decorator schema with name module-rapp-model3"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model3 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model3"; ' +
-                    '  prefix model3; ' +
-                    '   ' +
-                    '  import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '    identity classifierTest1 { ' +
-                    '        base model:classifiers; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base model:classifiers; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status CREATED()
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifiers and decorators schema, exception thrown due to wrong inheritance for the classifiers"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model4 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model4"; ' +
-                    '  prefix model4; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest1 { ' +
-                    '        base model-test; ' +
-                    '    } ' +
-                    ' ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid schema name",
-                "details": "Invalid schema name: Invalid classifier classifierTest1"
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifiers and decorators schema, exception thrown due to wrong inheritance for the classifiers"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model5 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model5"; ' +
-                    '  prefix model5; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf test1 { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf test2 { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf test3 { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base wrong-classifier; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity urban { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity rural { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    ' ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid schema name",
-                "details": "Invalid schema name: Invalid classifier geo-classifier"
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifiers and decorators schema, exception thrown due to wrong inheritance for the classifier"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model6 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model6"; ' +
-                    '  prefix model6; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest1 { ' +
-                    '        base model-test; ' +
-                    '    } ' +
-                    ' ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-            "status": "BAD_REQUEST",
-            "message": "Invalid schema name",
-            "details": "Invalid schema name: Invalid classifier classifierTest1"
-        }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with already existing schema name"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module test-app-module { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:test-app-module"; ' +
-                    '  prefix module; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid file input",
-                "details": "Invalid file input: Schema already exists"
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Invalid file type"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.json')),
-                    contentType: p('application/json'),
-                    content: $(c(regex(nonEmpty())),
-                    p('{"sample1":"test", "sample2":99}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Invalid file"
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Empty file"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-            "status": "BAD_REQUEST",
-            "message": "Invalid file input",
-            "details": "Invalid file input: Missing content at the beginning of the document."
-        }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Invalid leaf 1"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-x { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-module-x"; ' +
-                    '  prefix module-x; ' +
-                    '   ' +
-                    '  import o-ran-smo-teiv-common-yang-types { prefix test; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-06-10" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /test:decorators { ' +
-                    '        leaf select*fromocucpfunction { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf vendor { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity Outdoor { ' +
-                    '    base test:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity Rural { ' +
-                    '        base test:classifiers; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity Weekend { ' +
-                    '        base test:classifiers; ' +
-                    '    } ' +
-                    ' ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: 'select*fromocucpfunction' is not a valid YANG identifier."
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Invalid leaf 2"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-x2 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-module-x2"; ' +
-                    '  prefix module-x2; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix test; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-06-10" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /test:decorators { ' +
-                    '        leaf location { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf vendor { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity UPDATEties_model.module_referenceSETstatusDELETINGWHEREnameodu-function-model { ' +
-                    '    base test:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity Rural { ' +
-                    '        base test:classifiers; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity Weekend { ' +
-                    '        base test:classifiers; ' +
-                    '    } ' +
-                    ' ' +
-                    '}}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Unexpected content at end of document. Check curly braces balance throughout document."
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema without any given decorator or classifier"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model7 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model7"; ' +
-                    '  prefix model7; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    ' ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest1 { ' +
-                    '        base test-classifier; ' +
-                    '    } ' +
-                    ' ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Encountered '{}', which does nothing. Replace with ';' or un-comment the contents."
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema without any given decorator or classifier 2"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-module8 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-module8"; ' +
-                    '  prefix module8; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Invalid schema"
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema missing leaf type for the decorators"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model9 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model9"; ' +
-                    '  prefix model9; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '     ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid file input",
-                "details": "Invalid file input: Encountered '{}', which does nothing. Replace with ';' or un-comment the contents."
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with wrong decorator type"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model10 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model10"; ' +
-                    '  prefix model10; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type wrong; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Cannot resolve typedef 'wrong'."
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with wrong syntax (missing imports)"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model11 { ' +
-                    '   ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model11"; ' +
-                    '  prefix model11; ' +
-                    ' ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '  } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                    "status": "BAD_REQUEST",
-                    "message": "Invalid file input",
-                    "details": "Invalid file input: Invalid schema"
-                }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with wrong syntax (missing revision)"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model12 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model12"; ' +
-                    '  prefix model12; ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid file input",
-                "details": "Invalid file input: (Sub-)Module does not have a 'revision' statement."
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with wrong syntax (missing yang version, namespace, prefix)"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-model13 { ' +
-                    '   ' +
-                    '    import o-ran-smo-teiv-common-yang-types { prefix model; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf urban { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf rural { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf weekend { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base model:classifiers; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity classifierTest1 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest2 { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity classifierTest3 { ' +
-                    '        base model:classifiers; ' +
-                    '  } ' +
-                    '   ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-            "status": "BAD_REQUEST",
-            "message": "Invalid file input",
-            "details": "Invalid file input: Invalid schema"
-        }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Create a new classifier and decorator schema with wrong syntax (prefix is different then the inheritances)"
-        request {
-            method POST()
-            url("/topology-inventory/v1alpha11/schemas")
-            headers {
-                contentType(multipartFormData())
-            }
-            multipart(
-                    file: named(
-                    name: $(c(regex(nonEmpty())), p('file.yang')),
-                    contentType: p('application/yang'),
-                    content: $(c(regex(nonEmpty())),
-                    p('module module-rapp-module14 { ' +
-                    '  ' +
-                    '  yang-version 1.1; ' +
-                    '  namespace "urn:module-rapp-model14"; ' +
-                    '  prefix module14; ' +
-                    '   ' +
-                    '  import o-ran-smo-teiv-common-yang-types { prefix testModel; } ' +
-                    '  import o-ran-smo-teiv-common-yang-extensions {prefix or-teiv-yext; } ' +
-                    '   ' +
-                    '  revision "2024-05-08" { ' +
-                    '    description ' +
-                    '    "Initial revision."; ' +
-                    '    or-teiv-yext:label 0.3.0; ' +
-                    '  } ' +
-                    '   ' +
-                    '  augment /model:decorators { ' +
-                    '        leaf test1 { ' +
-                    '            type string; ' +
-                    '        } ' +
-                    '    leaf test2 { ' +
-                    '            type boolean; ' +
-                    '        } ' +
-                    '    leaf test3 { ' +
-                    '            type uint32; ' +
-                    '        } ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity geo-classifier { ' +
-                    '    base geo-classifier; ' +
-                    '  } ' +
-                    '  ' +
-                    '    identity urban { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    '   ' +
-                    '  identity rural { ' +
-                    '        base geo-classifier; ' +
-                    '    } ' +
-                    ' ' +
-                    '}'))))
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid file input",
-                "details": "Invalid file input: Path to schema node '/model:decorators', part of 'augment' statement, cannot be resolved."
-            }''')
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/schemas/03_deleteSchemas.groovy b/teiv/src/test/resources/contracts/schemas/03_deleteSchemas.groovy
deleted file mode 100644 (file)
index 5c486fa..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  ============LICENSE_START=======================================================
- *  Copyright (C) 2024 Ericsson
- *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
- *  ================================================================================
- *  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 contracts.schemas
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 204: Delete an existing classifier schema - test-app-for-deletion-module"
-        request {
-            method DELETE()
-            url("/topology-inventory/v1alpha11/schemas/test-app-for-deletion-module")
-        }
-        response {
-            status NO_CONTENT()
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Delete a schema that does not exists"
-        request {
-            method DELETE()
-            url("/topology-inventory/v1alpha11/schemas/does-not-exist-rapp-module")
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid schema name",
-                "details": "Invalid schema name: does-not-exist-rapp-module"
-            }''')
-        }
-    },
-    Contract.make {
-        description "ERROR - 400: Delete a schema that is in deleting status"
-        request {
-            method DELETE()
-            url("/topology-inventory/v1alpha11/schemas/test-module-in-deleting-state")
-        }
-        response {
-            status BAD_REQUEST()
-            body('''{
-                "status": "BAD_REQUEST",
-                "message": "Invalid schema name",
-                "details": "Invalid schema name: test-module-in-deleting-state"
-            }''')
-        }
-    }
-]
index 907f3cd..50b01ec 100644 (file)
@@ -64,6 +64,11 @@ public enum ParserFindingType {
      * There is a mismatch in conformance type between a module and its submodules.
      */
     P006_IMPLEMENT_IMPORT_MISMATCH,
+    /**
+     * Two or more modules are in the input with the same module name but different namespace;
+     * or the other way around. This is a serious issue.
+     */
+    P007_MODULE_NAMESPACE_MISMATCH,
 
     /**
      * Fail-fast. Denotes that during parsing some issues were found that are so severe that it
@@ -142,7 +147,7 @@ public enum ParserFindingType {
      */
     P037_UNRESOLVABLE_INCLUDE,
     /**
-     * Multiple revisions of a subnmodule are in the input. Not allowed.
+     * Multiple revisions of a submodule are in the input. Not allowed.
      */
     P038_AMBIGUOUS_INCLUDE,
     /**
index b4b14e2..d6336d4 100644 (file)
@@ -184,7 +184,7 @@ public class YangModel {
              */
             extractModuleIdentity(context, yangDomDocumentRoot);
             extractPrefixes(yangDomDocumentRoot);
-            extractNamespace(yangDomDocumentRoot, namespaceResolver);
+            extractNamespace(context, yangDomDocumentRoot, namespaceResolver);
 
             if (createTypeSafeStatementTree) {
                 /*
@@ -320,8 +320,8 @@ public class YangModel {
         }
     }
 
-    private void extractNamespace(final YangDomDocumentRoot docRoot, final ModuleAndNamespaceResolver namespaceResolver) {
-
+    private void extractNamespace(final ParserExecutionContext context, final YangDomDocumentRoot docRoot,
+            final ModuleAndNamespaceResolver namespaceResolver) {
         if (docRoot.getChildren().isEmpty()) {
             return;
         }
@@ -335,10 +335,31 @@ public class YangModel {
             if (namespaceChildren.size() == 1) {
                 final YangDomElement namespaceDomElement = namespaceChildren.get(0);
                 if (namespaceDomElement.getValue() != null) {
-                    namespaceResolver.recordModuleMapping(this.moduleIdentity.getModuleName(), namespaceDomElement
-                            .getValue());
-                    namespaceResolver.recordNamespaceMapping(namespaceDomElement.getValue(), this.moduleIdentity
-                            .getModuleName());
+                    final String moduleName = this.moduleIdentity.getModuleName();
+                    final String namespace = namespaceDomElement.getValue();
+
+                    /*
+                    * If the module already exists in the resolver (this is the case when multiple revisions of the
+                    * same module are in the input, with only one of these being conformance IMPLEMENT), then the
+                    * namespaces must match, so we check for that - same the other way around. If they don't match
+                    * we will issue a finding here - this is a serious issue.
+                    */
+                    final String alreadyMappedModuleName = namespaceResolver.getModuleForNamespace(namespace);
+                    final String alreadyMappedNamespace = namespaceResolver.getNamespaceForModule(moduleName);
+
+                    if (alreadyMappedModuleName != null && !alreadyMappedModuleName.equals(moduleName)) {
+                        context.addFinding(new Finding(this, ParserFindingType.P007_MODULE_NAMESPACE_MISMATCH,
+                                "Same namespace '" + namespace + "' is used by multiple different modules."));
+                    } else if (alreadyMappedNamespace != null && !alreadyMappedNamespace.equals(namespace)) {
+                        context.addFinding(new Finding(this, ParserFindingType.P007_MODULE_NAMESPACE_MISMATCH,
+                                "Module '" + moduleName + "' is multiple times in the input, with different namespaces."));
+                    } else {
+                        /*
+                        * All good.
+                        */
+                        namespaceResolver.recordModuleMapping(moduleName, namespace);
+                        namespaceResolver.recordNamespaceMapping(namespace, moduleName);
+                    }
                 }
             }
         }
index d5ba911..aad192b 100644 (file)
@@ -209,6 +209,7 @@ public class Schema {
             .toString(), ParserFindingType.P001_BASIC_FILE_READ_ERROR.toString(), ParserFindingType.P003_DUPLICATE_INPUT
                     .toString(), ParserFindingType.P004_SAME_MODULE_DUPLICATE_IMPLEMENTS.toString(),
             ParserFindingType.P005_NO_IMPLEMENTS.toString(), ParserFindingType.P006_IMPLEMENT_IMPORT_MISMATCH.toString(),
+            ParserFindingType.P007_MODULE_NAMESPACE_MISMATCH.toString(),
             ParserFindingType.P013_INVALID_SYNTAX_AT_DOCUMENT_ROOT.toString(),
             ParserFindingType.P014_INVALID_SYNTAX_AT_DOCUMENT_END.toString(), ParserFindingType.P031_PREFIX_NOT_UNIQUE
                     .toString(), ParserFindingType.P032_MISSING_REVISION.toString(), ParserFindingType.P035_AMBIGUOUS_IMPORT
diff --git a/yang-parser/src/test/java/org/oran/smo/yangtools/parser/model/statements/yang/test/NamespaceTest.java b/yang-parser/src/test/java/org/oran/smo/yangtools/parser/model/statements/yang/test/NamespaceTest.java
new file mode 100644 (file)
index 0000000..b2921a1
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 Ericsson
+ *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.yangtools.parser.model.statements.yang.test;
+
+import org.junit.Test;
+import org.oran.smo.yangtools.parser.findings.ParserFindingType;
+import org.oran.smo.yangtools.parser.testutils.YangTestCommon;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class NamespaceTest extends YangTestCommon {
+
+    private static final String TEST_DIR = "src/test/resources/model-statements-yang/namespace-test/";
+
+    @Test
+    public void test___modA_nsA___modB_nsB__ok() {
+
+        parseAbsoluteImplementsYangModels(Arrays.asList(TEST_DIR + "modA_nsA.yang", TEST_DIR + "modB_nsB.yang"));
+
+        assertNoFindings();
+    }
+
+    @Test
+    public void test___modA_nsA___modA_nsB___namespace_different() {
+
+        parseYangModels(Collections.emptyList(), Arrays.asList(TEST_DIR + "modA_nsA.yang"), Collections.emptyList(), Arrays
+                .asList(TEST_DIR + "modA_nsB.yang"));
+
+        assertHasFindingOfType(ParserFindingType.P007_MODULE_NAMESPACE_MISMATCH.toString());
+    }
+
+    @Test
+    public void test___modA_nsA___modB_nsA___module_different() {
+
+        parseYangModels(Collections.emptyList(), Arrays.asList(TEST_DIR + "modA_nsA.yang"), Collections.emptyList(), Arrays
+                .asList(TEST_DIR + "modB_nsA.yang"));
+
+        assertHasFindingOfType(ParserFindingType.P007_MODULE_NAMESPACE_MISMATCH.toString());
+    }
+}
diff --git a/yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsA.yang b/yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsA.yang
new file mode 100644 (file)
index 0000000..5bcf81f
--- /dev/null
@@ -0,0 +1,7 @@
+module modA {
+
+    namespace "nsA";
+
+    prefix "this";
+    revision "2024-09-26";
+}
\ No newline at end of file
diff --git a/yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsB.yang b/yang-parser/src/test/resources/model-statements-yang/namespace-test/modA_nsB.yang
new file mode 100644 (file)
index 0000000..522791b
--- /dev/null
@@ -0,0 +1,7 @@
+module modA {
+
+    namespace "nsB";
+
+    prefix "this";
+    revision "2024-09-30";
+}
\ No newline at end of file
diff --git a/yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsA.yang b/yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsA.yang
new file mode 100644 (file)
index 0000000..23df3f1
--- /dev/null
@@ -0,0 +1,7 @@
+module modB {
+
+    namespace "nsA";
+
+    prefix "this";
+    revision "2024-09-30";
+}
\ No newline at end of file
diff --git a/yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsB.yang b/yang-parser/src/test/resources/model-statements-yang/namespace-test/modB_nsB.yang
new file mode 100644 (file)
index 0000000..cc75642
--- /dev/null
@@ -0,0 +1,7 @@
+module modB {
+
+    namespace "nsB";
+
+    prefix "this";
+    revision "2024-09-26";
+}
\ No newline at end of file