Add classifiers and decorators 55/13255/1
authorJvD_Ericsson <jeff.van.dam@est.tech>
Fri, 9 Aug 2024 09:38:46 +0000 (10:38 +0100)
committerJeff van Dam <jeff.van.dam@est.tech>
Fri, 9 Aug 2024 11:09:02 +0000 (11:09 +0000)
Added classifiers and decorators
Refactored code

Issue-ID: SMO-162
Change-Id: I1cd982505abc7b47b58dbb3bf5472e99b053985b
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
324 files changed:
charts/smo/topology-exposure-inventory/charts/topology-exposure-inventory/values.yaml
charts/smo/topology-exposure-inventory/values.yaml
teiv/src/main/antlr4/org/oran/smo/teiv/antlr4/tiesPath.g4
teiv/src/main/java/org/oran/smo/teiv/CustomMetrics.java
teiv/src/main/java/org/oran/smo/teiv/availability/DependentServiceAvailability.java
teiv/src/main/java/org/oran/smo/teiv/availability/DependentServiceAvailabilityKafka.java
teiv/src/main/java/org/oran/smo/teiv/config/DataSourceConfig.java
teiv/src/main/java/org/oran/smo/teiv/config/KafkaAdminConfig.java
teiv/src/main/java/org/oran/smo/teiv/config/KafkaConfig.java
teiv/src/main/java/org/oran/smo/teiv/controller/health/TiesExposureHealthIndicator.java
teiv/src/main/java/org/oran/smo/teiv/controller/health/TiesHealthIndicator.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/controller/health/TiesIngestionHealthIndicator.java
teiv/src/main/java/org/oran/smo/teiv/exception/InvalidRelationshipException.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exception/TiesException.java
teiv/src/main/java/org/oran/smo/teiv/exposure/audit/AuditInfo.java [moved from teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/TiesPathQueryRefinementTest.java with 54% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/audit/AuditMapper.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/audit/LoggerHandler.java [moved from teiv/src/test/resources/contracts/ran/schemas/getSchemaByName.groovy with 62% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/ClassifiersService.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/impl/ClassifiersServiceImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/rest/controller/ClassifiersRestController.java
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataOperationRegistry.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataRepository.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/TiesPathQueryRefinement.java with 57% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataRepositoryImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataValidator.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/Classifiers.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/StoredSchema.java with 74% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/ConsumerData.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/Decorators.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/PersistableIdMap.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ClassifiersOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ConsumerDataOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DecoratorsOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteClassifiersOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteDecoratorsOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeClassifiersOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeDecoratorsOperation.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/data/api/DataService.java
teiv/src/main/java/org/oran/smo/teiv/exposure/data/api/impl/DataServiceImpl.java
teiv/src/main/java/org/oran/smo/teiv/exposure/data/rest/controller/DataController.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/data/rest/controller/DataRestController.java with 79% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/DecoratorsService.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/impl/DecoratorsServiceImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/rest/controller/DecoratorsRestController.java
teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/ModelService.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/ModelSchemaService.java with 65% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelSchemaServiceImpl.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelServiceImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/model/rest/controller/ModelController.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/model/rest/controller/ModelSchemaRestController.java with 54% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataPersistanceService.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataRepository.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModelRepository.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/Module.java [moved from teiv/src/main/java/org/oran/smo/teiv/schema/Module.java with 81% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModuleStatus.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistanceServiceImpl.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/ModelRepositoryImpl.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapper.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/EntityMapper.java
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtility.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PageMetaData.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaData.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/QueryMetaData.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipMapper.java
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapper.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/ResponseMapper.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/AndOrLogicalBlock.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ConditionFactory.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ContainerType.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/EmptyLogicalBlock.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/FilterCriteria.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/InnerFilterCriteria.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/LogicalBlock.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/QueryFunction.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ScopeLogicalBlock.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ScopeObject.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/TargetObject.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapper.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/BasePathRefinement.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/PathToJooqRefinement.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/PathResolver.java
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ResolverDataType.java [moved from teiv/src/main/java/org/oran/smo/teiv/utils/query/TokenType.java with 88% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ResolverUtil.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeFilterListener.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolver.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/TargetFilterListener.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/TargetResolver.java
teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationDTO.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationUtil.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/exposure/utils/RequestDetails.java [moved from teiv/src/main/java/org/oran/smo/teiv/exposure/collection/rest/controller/TopologyGroupsRestController.java with 69% similarity]
teiv/src/main/java/org/oran/smo/teiv/exposure/utils/RequestValidator.java
teiv/src/main/java/org/oran/smo/teiv/listener/CreateTopologyProcessor.java
teiv/src/main/java/org/oran/smo/teiv/listener/DeleteTopologyProcessor.java
teiv/src/main/java/org/oran/smo/teiv/listener/MergeTopologyProcessor.java
teiv/src/main/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessor.java
teiv/src/main/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/listener/TopologyListener.java
teiv/src/main/java/org/oran/smo/teiv/listener/TopologyProcessorRegistry.java
teiv/src/main/java/org/oran/smo/teiv/schema/BidiDbNameMapper.java
teiv/src/main/java/org/oran/smo/teiv/schema/ConsumerDataCache.java
teiv/src/main/java/org/oran/smo/teiv/schema/DataType.java
teiv/src/main/java/org/oran/smo/teiv/schema/EntityType.java
teiv/src/main/java/org/oran/smo/teiv/schema/Persistable.java
teiv/src/main/java/org/oran/smo/teiv/schema/PostgresSchemaLoader.java
teiv/src/main/java/org/oran/smo/teiv/schema/RelationType.java
teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistry.java
teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryErrorCode.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryException.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/schema/YangDataTypes.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/service/SchemaCleanUpService.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/service/TiesDbOperations.java
teiv/src/main/java/org/oran/smo/teiv/service/TiesDbService.java
teiv/src/main/java/org/oran/smo/teiv/service/cloudevent/CloudEventParser.java
teiv/src/main/java/org/oran/smo/teiv/service/cloudevent/data/Entity.java
teiv/src/main/java/org/oran/smo/teiv/service/cloudevent/data/ModuleObject.java
teiv/src/main/java/org/oran/smo/teiv/service/cloudevent/data/ParsedCloudEventData.java
teiv/src/main/java/org/oran/smo/teiv/service/cloudevent/data/Relationship.java
teiv/src/main/java/org/oran/smo/teiv/service/kafka/KafkaAddressSupplierConfig.java
teiv/src/main/java/org/oran/smo/teiv/service/kafka/KafkaFactory.java
teiv/src/main/java/org/oran/smo/teiv/service/models/OperationResult.java
teiv/src/main/java/org/oran/smo/teiv/startup/SchemaHandler.java
teiv/src/main/java/org/oran/smo/teiv/utils/CloudEventUtil.java
teiv/src/main/java/org/oran/smo/teiv/utils/JooqTypeConverter.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/utils/PersistableUtil.java [new file with mode: 0644]
teiv/src/main/java/org/oran/smo/teiv/utils/TiesConstants.java
teiv/src/main/java/org/oran/smo/teiv/utils/YangParser.java
teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryElement.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryMonad.java [deleted file]
teiv/src/main/java/org/oran/smo/teiv/utils/query/exception/TiesPathException.java
teiv/src/main/resources/application.yaml
teiv/src/main/resources/logback-json.xml
teiv/src/test/java/org/oran/smo/teiv/CoreApplicationTest.java
teiv/src/test/java/org/oran/smo/teiv/controller/health/TiesExposureHealthIndicatorTest.java
teiv/src/test/java/org/oran/smo/teiv/controller/health/TiesIngestionHealthIndicatorTest.java
teiv/src/test/java/org/oran/smo/teiv/db/TestPostgresqlContainer.java
teiv/src/test/java/org/oran/smo/teiv/db/TestPostgresqlContainerV1.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedNonXPathTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/TopologyExposureApiBase.java
teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/RelationshipTestUtility.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/TopologyObjectTestUtility.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/data/api/impl/DataServiceImplTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/data/api/impl/ExposureMetricsTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/data/rest/controller/DataRestControllerTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistenceServiceImplGETRequestsContainerizedTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImplGETRequestsContainerizedTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapperTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/EntityMapperTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtilityTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaDataTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipMapperTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapperTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/DtoToJooqTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/FilterCriteriaTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ScopeLogicalBlockTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/SelectBlockTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapperTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/BasePathRefinementTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/PathToJooqRefinementTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolverTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/resolver/TargetResolverTest.java
teiv/src/test/java/org/oran/smo/teiv/exposure/utils/PaginationUtilTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/exposure/utils/RequestValidatorTest.java
teiv/src/test/java/org/oran/smo/teiv/ingestion/validation/IngestionOperationValidatorTest.java
teiv/src/test/java/org/oran/smo/teiv/listener/CreateTopologyProcessorTest.java
teiv/src/test/java/org/oran/smo/teiv/listener/DeleteTopologyProcessorTest.java
teiv/src/test/java/org/oran/smo/teiv/listener/MergeTopologyProcessorTest.java
teiv/src/test/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorTest.java
teiv/src/test/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1Test.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/schema/ConsumerDataCacheTest.java
teiv/src/test/java/org/oran/smo/teiv/schema/MockSchemaLoader.java
teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryContainerizedTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/service/EndToEndApiTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/service/EndToEndDbTest.java
teiv/src/test/java/org/oran/smo/teiv/service/ModelSchemaServiceTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/service/SchemaCleanUpServiceTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/service/TiesDbOperationResultsTest.java
teiv/src/test/java/org/oran/smo/teiv/service/TiesDbServiceContainerizedTest.java
teiv/src/test/java/org/oran/smo/teiv/service/cloudevent/CloudEventParserTest.java
teiv/src/test/java/org/oran/smo/teiv/service/cloudevent/data/ParsedCloudEventDataTest.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/utils/ConvertToJooqTypeUtilTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/utils/EndToEndExpectedResults.java
teiv/src/test/java/org/oran/smo/teiv/utils/TiesTestConstants.java [new file with mode: 0644]
teiv/src/test/java/org/oran/smo/teiv/utils/exposure/PaginationVerifierTestUtil.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTest.java [deleted file]
teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTestUtil.java [deleted file]
teiv/src/test/resources/application.yaml
teiv/src/test/resources/cloudeventdata/common/ce-arrays.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-data-only.json [deleted file]
teiv/src/test/resources/cloudeventdata/common/ce-invalid-entity-attribute.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module-type-pair.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-type.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-a-side.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-b-side.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-both-sides.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-id.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-with-data.json
teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids2.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids3.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-geo-location.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-many-to-many.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-many-to-one.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-one-to-many.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-one-to-one.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-relationship-connecting-same-entity.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-create-second-case.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-managed-element.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-many-to-many.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-many-to-one.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-one-to-many.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-one-to-one.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-relationship-connecting-same-entity.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-merge-long-names.json
teiv/src/test/resources/cloudeventdata/end-to-end/ce-merge-one-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/ce-merge-one-to-many2.json
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-one.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-one-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-relationship-connecting-same-entity.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-second-case.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-one.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-one-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-relationship-connecting-same-entity.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-merge-one-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-source-entity-delete-cm-handle.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one2.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one3.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one5.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-one-to-one.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-second-case.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-delete-one-to-one.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-merge-one-to-many.json [deleted file]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-many-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-one-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-second-case.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-delete-one-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-merge-one-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-many-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-one-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-source-entity-delete-cm-handle.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-geo-location.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-relationship-connecting-same-entity.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-second-case.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-managed-element.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-many.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-one.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-relationship-connecting-same-entity.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-long-names.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many-deprecated-structure.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many2.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle2.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation2.json [new file with mode: 0644]
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one2.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one3.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one4.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one5.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one6.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one7.json
teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one8.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many2.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many3.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many4.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many5.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many6.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many7.json
teiv/src/test/resources/cloudeventdata/validation/one-to-many/ce-create-one-to-many8.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one2.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one3.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one4.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one5.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one6.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one7.json
teiv/src/test/resources/cloudeventdata/validation/one-to-one/ce-create-one-to-one8.json
teiv/src/test/resources/contracts/classifiers/00_getClassifiers_getTopologyByEntityTypeName.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/classifiers/01_getClassifiers_getRelationshipsByType.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/classifiers/02_getClassifiers_getEntitiesByDomain.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/classifiers/03_postClassifiers_merge.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/classifiers/04_postClassifiers_delete.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/00_getAllDomains.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/01_getTopologyEntityTypes.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/02_getTopologyByEntityTypeName.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/03_getTopologyById.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/04_getAllRelationshipsForEntityId.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/05_getRelationshipTypes.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/06_getRelationshipsByType.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/07_getRelationshipById.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/data/08_getEntitiesByDomain.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/decorators/00_getDecorators_getTopologyByEntityTypeName.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/decorators/01_getDecorators_getRelationshipsByType.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/decorators/02_getDecorators_getEntitiesByDomain.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/decorators/03_postDecoratorsMerge.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/decorators/04_postDecoratorsDelete.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/ran/GNBDUFunction/getAllRelationships.groovy [deleted file]
teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyById.groovy [deleted file]
teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyByType.groovy [deleted file]
teiv/src/test/resources/contracts/ran/NRCellDU/getTopologyById.groovy [deleted file]
teiv/src/test/resources/contracts/ran/schemas/getAllSchemas.groovy [deleted file]
teiv/src/test/resources/contracts/ran/schemas/getSchemasInDomain.groovy [deleted file]
teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/schemas/01_getSchemaContent.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/schemas/02_postSchemas.groovy [new file with mode: 0644]
teiv/src/test/resources/contracts/schemas/03_deleteSchemas.groovy [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/00_init-oran-smo-teiv-data.sql
teiv/src/test/resources/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/01_init-oran-smo-teiv-model.sql
teiv/src/test/resources/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/consumer-data-v1.sql [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/data-deprecated.sql [moved from teiv/src/test/resources/data/data-deprecated.sql with 100% similarity]
teiv/src/test/resources/pgsqlschema/data-v1.sql [new file with mode: 0644]
teiv/src/test/resources/pgsqlschema/data.sql [moved from teiv/src/test/resources/data/data.sql with 62% similarity]
teiv/src/test/resources/pgsqlschema/model.sql [new file with mode: 0644]

index fea5882..84d50af 100644 (file)
@@ -156,7 +156,4 @@ application:
     retry-policies:
       deadlock:
         retry-attempts: 10
-        retry-backoff-ms: 200
-
-  feature_flags:
-    use_alternate_delete_logic: false
\ No newline at end of file
+        retry-backoff-ms: 200
\ No newline at end of file
index 506c1de..e262d97 100644 (file)
@@ -174,9 +174,6 @@ application: &applicationConfig
         retry-attempts: 10
         retry-backoff-ms: 200
 
-  feature_flags:
-    use_alternate_delete_logic: false
-
 topology-exposure:
   name: topology-exposure
   namespace: default
index 8a4046c..456a1fa 100644 (file)
 
 grammar tiesPath ;
 
-tiesPath : ( prefix | incorrectPrefix ) multipleLeafConditions? textFunctionCondition? containsFunctionCondition? ancestorAxis? invalidPostFix? containerName? fieldLeaf?;
+tiesPath : ( prefix | incorrectPrefix ) multipleLeafConditions? containsTextFunctionCondition? textFunctionCondition? containsFunctionCondition? ancestorAxis? invalidPostFix? containerName? fieldLeaf?;
 
 ancestorAxis : SLASH KW_ANCESTOR COLONCOLON ancestorPath ;
 
 ancestorPath : yangElement ( SLASH yangElement)* ;
 
-textFunctionCondition : SLASH leafName OB KW_TEXT_FUNCTION EQ StringLiteral CB ;
+textFunctionCondition : OB KW_TEXT_FUNCTION EQ StringLiteral CB ;
+
+containsTextFunctionCondition : OB KW_CONTAINS_FUNCTION OP KW_TEXT_FUNCTION COMMA StringLiteral CP CB ;
 
 containsFunctionCondition : OB KW_CONTAINS_FUNCTION OP AT leafName COMMA StringLiteral CP CB ;
 
@@ -79,7 +81,8 @@ leafName : QName ;
 
 booleanOperators : ( KW_AND | KW_OR ) ;
 
-comparativeOperators : ( EQ | GT | LT | GE | LE ) ;
+// Onnly EQ supported for now
+comparativeOperators : ( EQ /*| GT | LT | GE | LE */ ) ;
 
 invalidPostFix : (AT | CB | COLONCOLON | comparativeOperators ).+ ;
 
@@ -165,4 +168,4 @@ fragment FragChar : '\u0009' | '\u000a' | '\u000d'
 Whitespace : ('\u000d' | '\u000a' | '\u0020' | '\u0009')+ -> skip ;
 
 // handle characters which failed to match any other token (otherwise Antlr will ignore them)
-ErrorCharacter : . ;
+ErrorCharacter : . ;
\ No newline at end of file
index 859dfe5..315247c 100644 (file)
@@ -24,19 +24,13 @@ import io.micrometer.core.instrument.Counter;
 import io.micrometer.core.instrument.MeterRegistry;
 import io.micrometer.core.instrument.Timer;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import lombok.AccessLevel;
 import lombok.Data;
-import lombok.Getter;
 import org.springframework.stereotype.Component;
 
 @Data
 @Component
 public class CustomMetrics {
 
-    @Getter(AccessLevel.PRIVATE)
-    private final AtomicLong tiesSubscriptionGaugeCounter = new AtomicLong(0L);
-
     private final MeterRegistry meterRegistry;
 
     private final Counter numReceivedCloudEventCreate;
@@ -115,6 +109,10 @@ public class CustomMetrics {
 
     private final Counter numUnsuccessfullyExposedDomainTypes;
 
+    private final Counter numUnsuccessfullyUpdatedClassifiers;
+
+    private final Counter numUnsuccessfullyUpdatedDecorators;
+
     private final Counter numIgnoredAttributes;
 
     public CustomMetrics(MeterRegistry meterRegistry) {
@@ -208,6 +206,12 @@ public class CustomMetrics {
         numUnsuccessfullyExposedDomainTypes = Counter.builder("ties_exposure_http_get_domain_types_fail_total").register(
                 meterRegistry);
 
+        numUnsuccessfullyUpdatedClassifiers = Counter.builder("ties_exposure_http_update_classifiers_fail_total").register(
+                meterRegistry);
+
+        numUnsuccessfullyUpdatedDecorators = Counter.builder("ties_exposure_http_update_decorators_fail_total").register(
+                meterRegistry);
+
         cloudEventMergePersistTime = Timer.builder("ties_ingestion_event_topology_merge_persist_seconds").register(
                 meterRegistry);
 
@@ -525,16 +529,12 @@ public class CustomMetrics {
         numUnsuccessfullyExposedDomainTypes.increment();
     }
 
-    public void incrementNumReceivedTiesSubscriptions(int amountToAdd) {
-        tiesSubscriptionGaugeCounter.addAndGet(amountToAdd);
-    }
-
-    public void resetNumReceivedTiesSubscriptions() {
-        tiesSubscriptionGaugeCounter.set(0);
+    public void incrementNumUnsuccessfullyUpdatedClassifiers() {
+        numUnsuccessfullyUpdatedClassifiers.increment();
     }
 
-    public void setNumReceivedTiesSubscriptions(int amount) {
-        tiesSubscriptionGaugeCounter.set(amount);
+    public void incrementNumUnsuccessfullyUpdatedDecorators() {
+        numUnsuccessfullyUpdatedDecorators.increment();
     }
 
     public void incrementNumIgnoredAttributes() {
index 46291ff..837a06e 100644 (file)
@@ -29,8 +29,6 @@ import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
 public abstract class DependentServiceAvailability {
-    protected String serviceName;
-
     protected int retryIntervalMs;
 
     protected int retryAttempts;
@@ -41,7 +39,7 @@ public abstract class DependentServiceAvailability {
      * @return true once service is reached, false if max retries exhausted
      */
     public boolean checkService() {
-        RetryTemplate retryTemplate = RetryOperationUtils.getRetryTemplate(serviceName,
+        RetryTemplate retryTemplate = RetryOperationUtils.getRetryTemplate(getServiceName(),
                 UnsatisfiedExternalDependencyException.class, retryAttempts, retryIntervalMs);
         try {
             return retryTemplate.execute(retryContext -> isServiceAvailable());
@@ -51,5 +49,10 @@ public abstract class DependentServiceAvailability {
         return false; // exhausted retries
     }
 
+    /**
+     * @return Name of the service, e.g.: Kafka.
+     */
+    protected abstract String getServiceName();
+
     abstract boolean isServiceAvailable() throws UnsatisfiedExternalDependencyException;
 }
index 2af2d33..0e0748e 100644 (file)
  */
 package org.oran.smo.teiv.availability;
 
+import lombok.RequiredArgsConstructor;
 import org.apache.kafka.clients.admin.AdminClient;
 import org.apache.kafka.clients.admin.ListTopicsOptions;
 import org.apache.kafka.clients.admin.ListTopicsResult;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Profile;
 import org.springframework.kafka.core.KafkaAdmin;
 import org.springframework.stereotype.Component;
 
@@ -37,7 +37,7 @@ import lombok.extern.slf4j.Slf4j;
 
 @Component
 @Slf4j
-@Profile("ingestion")
+@RequiredArgsConstructor
 public class DependentServiceAvailabilityKafka extends DependentServiceAvailability {
 
     @Getter
@@ -49,10 +49,9 @@ public class DependentServiceAvailabilityKafka extends DependentServiceAvailabil
     @Setter
     private Integer listTopicTimeout = null;
 
-    public DependentServiceAvailabilityKafka(KafkaAdminConfig kafkaAdminConfig, KafkaAdmin kafkaAdmin) {
-        this.kafkaAdminConfig = kafkaAdminConfig;
-        this.kafkaAdmin = kafkaAdmin;
-        serviceName = "Kafka";
+    @Override
+    protected String getServiceName() {
+        return "Kafka";
     }
 
     @Value("${kafka.availability.retry-interval-ms}")
index a926a0f..f9d2b8f 100644 (file)
@@ -56,4 +56,9 @@ public class DataSourceConfig {
     public DSLContext dslContextRead() {
         return DSL.using(dataSourceRead(), SQLDialect.POSTGRES);
     }
+
+    @Bean(name = "readWriteDataDslContext")
+    public DSLContext dslContextReadWrite() {
+        return DSL.using(dataSourceWrite(), SQLDialect.POSTGRES);
+    }
 }
index 66beb64..747c52e 100644 (file)
@@ -23,7 +23,6 @@ package org.oran.smo.teiv.config;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
 
 import lombok.Data;
 
@@ -31,7 +30,6 @@ import org.oran.smo.teiv.service.kafka.KafkaAddressSupplier;
 
 @Configuration
 @Data
-@Profile("ingestion")
 @Slf4j
 public class KafkaAdminConfig {
 
index b43f4b6..a263de6 100644 (file)
@@ -23,11 +23,9 @@ package org.oran.smo.teiv.config;
 import lombok.Data;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
 
 @Configuration
 @Data
-@Profile("ingestion")
 public class KafkaConfig {
 
     private final TopologyIngestion topologyIngestion;
@@ -35,18 +33,21 @@ public class KafkaConfig {
     @Data
     @Configuration
     public static class TopologyIngestion {
-        @Value("${kafka.topology-ingestion.consumer.topic.name}")
+        @Value("${kafka.topology-ingestion.topic.name}")
         private String topicName;
 
-        @Value("${kafka.topology-ingestion.consumer.topic.partitions}")
+        @Value("${kafka.topology-ingestion.topic.partitions}")
         private int partitions;
 
-        @Value("${kafka.topology-ingestion.consumer.topic.replicas}")
+        @Value("${kafka.topology-ingestion.topic.replicas}")
         private int replicas;
 
-        @Value("${kafka.topology-ingestion.consumer.topic.retention-ms}")
+        @Value("${kafka.topology-ingestion.topic.retention-ms}")
         private String retention;
 
+        @Value("${kafka.topology-ingestion.topic.retention-bytes}")
+        private String retentionBytes;
+
         @Value("${kafka.topology-ingestion.consumer.group-id}")
         private String groupId;
 
index 1863ff7..cdcf000 100644 (file)
  */
 package org.oran.smo.teiv.controller.health;
 
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
+import org.oran.smo.teiv.availability.DependentServiceAvailabilityKafka;
 import org.springframework.boot.actuate.health.Health;
-import org.springframework.boot.actuate.health.HealthIndicator;
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
 
@@ -32,26 +29,25 @@ import org.springframework.stereotype.Component;
  * Health Check component for TIES exposure.
  */
 
-@RequiredArgsConstructor
 @Component
-@Slf4j
 @Profile("!ingestion")
-public class TiesExposureHealthIndicator implements HealthIndicator {
+public class TiesExposureHealthIndicator extends TiesHealthIndicator {
 
-    private final HealthStatus healthStatus;
+    public TiesExposureHealthIndicator(HealthStatus healthStatus,
+            DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka) {
+        super(healthStatus, dependentServiceAvailabilityKafka);
+    }
 
-    private static final String SERVICE_NAME = "topology-exposure-inventory";
+    @Override
+    protected String getServiceName() {
+        return "topology-exposure-inventory";
+    }
 
     @Override
     public Health health() {
         if (!healthStatus.isSchemaInitialized()) {
-            String errorMessage = SERVICE_NAME + " is DOWN because: Schema is yet to be initialized.";
-            log.error(errorMessage);
-            return Health.down().withDetail("Error", errorMessage).build();
-        } else {
-            String message = SERVICE_NAME + " is UP and Healthy.";
-            log.debug(message);
-            return Health.up().withDetail("UP", message).build();
+            return healthDown("Schema is yet to be initialized.");
         }
+        return healthUp();
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/controller/health/TiesHealthIndicator.java b/teiv/src/main/java/org/oran/smo/teiv/controller/health/TiesHealthIndicator.java
new file mode 100644 (file)
index 0000000..0beb247
--- /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.teiv.controller.health;
+
+import org.oran.smo.teiv.availability.DependentServiceAvailabilityKafka;
+
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public abstract class TiesHealthIndicator implements HealthIndicator {
+
+    protected final HealthStatus healthStatus;
+    protected final DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka;
+
+    protected abstract String getServiceName();
+
+    protected TiesHealthIndicator(HealthStatus healthStatus,
+            DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka) {
+        this.healthStatus = healthStatus;
+        this.dependentServiceAvailabilityKafka = dependentServiceAvailabilityKafka;
+    }
+
+    protected Health healthUp() {
+        String message = getServiceName() + " is UP and Healthy.";
+        log.debug(message);
+        return Health.up().withDetail("UP", message).build();
+    }
+
+    protected Health healthDown(String reason) {
+        String errorMessage = getServiceName() + " is DOWN because: " + reason;
+        log.error(errorMessage);
+        return Health.down().withDetail("Error", errorMessage).build();
+    }
+
+    protected boolean isKafkaReachable() {
+        return dependentServiceAvailabilityKafka.checkService();
+    }
+}
index fbedaa0..4b891d2 100644 (file)
  */
 package org.oran.smo.teiv.controller.health;
 
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
 import org.springframework.boot.actuate.health.Health;
-import org.springframework.boot.actuate.health.HealthIndicator;
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
 
@@ -34,43 +30,28 @@ import org.oran.smo.teiv.availability.DependentServiceAvailabilityKafka;
  * Health Check component for TIES ingestion.
  */
 
-@RequiredArgsConstructor
 @Component
-@Slf4j
 @Profile("ingestion")
-public class TiesIngestionHealthIndicator implements HealthIndicator {
-
-    private final HealthStatus healthStatus;
+public class TiesIngestionHealthIndicator extends TiesHealthIndicator {
 
-    private final DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka;
+    @Override
+    protected String getServiceName() {
+        return "top-exp-inv-ingestion";
+    }
 
-    private static final String SERVICE_NAME = "top-exp-inv-ingestion";
+    public TiesIngestionHealthIndicator(HealthStatus healthStatus,
+            DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka) {
+        super(healthStatus, dependentServiceAvailabilityKafka);
+    }
 
     @Override
     public Health health() {
-        String errorMessage = SERVICE_NAME + " is DOWN because:";
-        boolean isHealthy = true;
-
         if (!healthStatus.isSchemaInitialized()) {
-            errorMessage += " Schema is yet to be initialized.";
-            isHealthy = false;
+            return healthDown("Schema is yet to be initialized.");
         }
-
-        if (!checkKafkaHealth()) {
-            errorMessage += " Kafka is unavailable.";
-            isHealthy = false;
-        }
-
-        if (!isHealthy) {
-            log.error(errorMessage);
-            return Health.down().withDetail("Error", errorMessage).build();
-        } else {
-            log.debug(SERVICE_NAME + " is UP and Healthy.");
-            return Health.up().withDetail("UP", SERVICE_NAME + " is UP and Healthy.").build();
+        if (!isKafkaReachable()) {
+            return healthDown("Kafka is unavailable.");
         }
-    }
-
-    private boolean checkKafkaHealth() {
-        return dependentServiceAvailabilityKafka.checkService();
+        return healthUp();
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exception/InvalidRelationshipException.java b/teiv/src/main/java/org/oran/smo/teiv/exception/InvalidRelationshipException.java
new file mode 100644 (file)
index 0000000..2943f44
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  ============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.teiv.exception;
+
+public class InvalidRelationshipException extends Exception {
+    public InvalidRelationshipException(final String message) {
+        super(message);
+    }
+}
index 481a2b6..36d4bdb 100644 (file)
@@ -21,6 +21,9 @@
 package org.oran.smo.teiv.exception;
 
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.springframework.http.HttpStatus;
 
@@ -38,6 +41,11 @@ public class TiesException extends RuntimeException {
         return clientException("Unknown module", String.format("Unknown module: %s", module));
     }
 
+    public static TiesException unknownTopologyObjectType(final String topologyObject) {
+        return serverException("Unknown topology object type", String.format("Unknown topology object type: %s",
+                topologyObject), null);
+    }
+
     //  Request validation
     public static TiesException unknownDomain(final String domain, final Collection<String> domains) {
         return clientException("Unknown domain", String.format("Unknown domain: %s, known domains: %s", domain, domains));
@@ -74,6 +82,10 @@ public class TiesException extends RuntimeException {
         return clientException("Invalid schema name", String.format("Invalid schema name: %s", name));
     }
 
+    public static TiesException invalidFileInput(final String error) {
+        return clientException("Invalid file input", String.format("Invalid file input: %s", error));
+    }
+
     public static TiesException schemaNotOwned(final String name) {
         return new TiesException("Forbidden", String.format("Schema %s is not owned by user", name), HttpStatus.FORBIDDEN,
                 null);
@@ -83,16 +95,51 @@ public class TiesException extends RuntimeException {
         return serverException("Sql exception during query execution", "Please check the logs for more details", null);
     }
 
+    public static TiesException unParsedTopologyObjectType(String topologyObjectName) {
+        return serverException(String.format("Un parsed topology object type: %s", topologyObjectName),
+                "Please check the logs for more details", null);
+    }
+
+    public static TiesException invalidContainerType(String containerType) {
+        return serverException(String.format("Invalid container type: %s", containerType),
+                "Please check the logs for more details", null);
+    }
+
+    public static TiesException invalidAssociationType(final String association) {
+        return serverException(String.format("Invalid association type: %s", association),
+                "Please check the logs for more details", null);
+    }
+
     public static TiesException resourceNotFoundException() {
         return new TiesException("Resource Not Found", "The requested resource is not found", HttpStatus.NOT_FOUND, null);
     }
 
+    public static TiesException resourceNotFoundException(Set<String> entityIds, Set<String> relationshipIds) {
+        return new TiesException("Resource Not Found", String.format(
+                "The requested resource with the following ids cannot be found. Entities: %s Relationships: %s", entityIds,
+                relationshipIds), HttpStatus.NOT_FOUND, null);
+    }
+
+    public static TiesException invalidClassifiersException(List<String> classifiers) {
+        return new TiesException("Invalid classifiers", String.format("The provided classifiers are invalid %s",
+                classifiers), HttpStatus.NOT_FOUND, null);
+    }
+
+    public static TiesException invalidDecoratorsException(Map<String, String> problems) {
+        return new TiesException("Invalid decorators", String.format("The provided decorators are invalid %s", problems),
+                HttpStatus.NOT_FOUND, null);
+    }
+
     public static TiesException invalidValueException(String valueName, Integer valueLimit, Boolean isLowerLimit) {
         return clientException("Invalid Value", String.format("%s cannot be %s than %d", valueName, isLowerLimit ?
                 "larger" :
                 "lower", valueLimit));
     }
 
+    public static TiesException invalidJsonFormat(Exception exception) {
+        return serverException("Invalid json format", "Please check the logs for more details", exception);
+    }
+
     public static TiesException serverException(String message, String details, Exception exception) {
         return new TiesException(message, details, HttpStatus.INTERNAL_SERVER_ERROR, exception);
     }
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.exposure.tiespath.refiner;
+package org.oran.smo.teiv.exposure.audit;
 
-import org.oran.smo.teiv.utils.path.TiesPathQuery;
-import org.apache.commons.lang3.NotImplementedException;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
+import java.util.List;
 
-public class TiesPathQueryRefinementTest {
-    @Test
-    void parseTiesPathQueryTest() {
-        Assertions.assertThrows(NotImplementedException.class, () -> TiesPathQueryRefinement.parseTiesPathQuery(
-                new TiesPathQuery()));
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpStatus;
+
+@AllArgsConstructor
+public class AuditInfo<T> {
+    private final String operation;
+    private final T consumerData;
+    private final List<String> entityIds;
+    private final List<String> relationshipIds;
+    private final HttpStatus status;
+
+    @Override
+    public String toString() {
+        return String.format("%s %s=%s for entities=%s and relationships=%s (%s)", StringUtils.capitalize(operation),
+                consumerData instanceof List<?> ? "classifiers" : "decorators", consumerData, entityIds, relationshipIds,
+                status.equals(HttpStatus.NO_CONTENT) ? "successful" : "failed");
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/audit/AuditMapper.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/audit/AuditMapper.java
new file mode 100644 (file)
index 0000000..f581ccc
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  ============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.teiv.exposure.audit;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.experimental.UtilityClass;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.springframework.http.HttpStatus;
+
+@UtilityClass
+public class AuditMapper {
+    public AuditInfo<List<String>> fromClassifiersRequest(final OranTeivClassifier request, final HttpStatus status) {
+        return new AuditInfo<>(request.getOperation().toString(), request.getClassifiers(), request.getEntityIds(), request
+                .getRelationshipIds(), status);
+    }
+
+    public AuditInfo<Map<String, Object>> fromDecoratorsRequest(final OranTeivDecorator request, final HttpStatus status) {
+        return new AuditInfo<>(request.getOperation().toString(), request.getDecorators(), request.getEntityIds(), request
+                .getRelationshipIds(), status);
+    }
+}
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package contracts.ran.schemas
+package org.oran.smo.teiv.exposure.audit;
 
-import org.springframework.cloud.contract.spec.Contract
+import org.slf4j.Logger;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.stereotype.Component;
 
-[
-    Contract.make {
-        description "SUCCESS - 200: Get schema with name o-ran-smo-teiv-cloud-to-ran"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas/o-ran-smo-teiv-cloud-to-ran/content")
-        }
-        response {
-            body("module o-ran-smo-teiv-cloud-to-ran { yang-version 1.1; }")
-            status OK()
-            headers {
-                contentType('text/plain')
-            }
-        }
+@Component
+public class LoggerHandler {
+
+    public void logAudit(Logger log, String message, HttpServletRequest context) {
+        String requestInfo = getRequestInfo(context);
+        log.info("Audit Log: {} - Request Info: {}", message, requestInfo);
+    }
+
+    private String getRequestInfo(HttpServletRequest context) {
+        String method = context.getMethod();
+        String requestURI = context.getRequestURI();
+
+        return String.format("Method: %s, URI: %s", method, requestURI);
     }
-]
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/ClassifiersService.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/ClassifiersService.java
new file mode 100644 (file)
index 0000000..2f016ed
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  ============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.teiv.exposure.classifiers.api;
+
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+
+public interface ClassifiersService {
+    /**
+     * Updates the classifiers of the specified entities and/or relationships
+     *
+     * @param oranTeivClassifier
+     *     holds information for updating classifiers
+     */
+    void update(OranTeivClassifier oranTeivClassifier);
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/impl/ClassifiersServiceImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/classifiers/api/impl/ClassifiersServiceImpl.java
new file mode 100644 (file)
index 0000000..a346280
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  ============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.teiv.exposure.classifiers.api.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.classifiers.api.ClassifiersService;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataOperationRegistry;
+import org.oran.smo.teiv.exposure.consumerdata.model.Classifiers;
+import org.oran.smo.teiv.exposure.consumerdata.operation.ClassifiersOperation;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.schema.ConsumerDataCache;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Service;
+
+import lombok.RequiredArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import java.util.function.Consumer;
+
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ClassifiersServiceImpl implements ClassifiersService {
+
+    private final ModelRepository modelRepository;
+    private final ConsumerDataCache consumerDataCache;
+    private final ConsumerDataOperationRegistry consumerDataOperationRegistry;
+
+    @Override
+    public void update(final OranTeivClassifier oranTeivClassifier) {
+
+        log.debug(String.format("Executing %s on classifiers", oranTeivClassifier.getOperation()));
+
+        List<String> entityIds = oranTeivClassifier.getEntityIds();
+        if (entityIds == null) {
+            entityIds = Collections.emptyList();
+        }
+
+        List<String> relationshipIds = oranTeivClassifier.getRelationshipIds();
+        if (relationshipIds == null) {
+            relationshipIds = Collections.emptyList();
+        }
+
+        final List<String> classifierNames = oranTeivClassifier.getClassifiers();
+
+        final Classifiers classifierRecords = Classifiers.builder().data(classifierNames).entityIds(entityIds)
+                .relationshipIds(relationshipIds).build();
+
+        if (oranTeivClassifier.getOperation().equals(OranTeivClassifier.OperationEnum.MERGE)) {
+            runMethodSafe(this::validateMerge, classifierRecords);
+        } else {
+            runMethodSafe(this::validateDelete, classifierRecords);
+        }
+
+        final ClassifiersOperation operation = consumerDataOperationRegistry.getClassifiersOperation(oranTeivClassifier
+                .getOperation());
+
+        List<OperationResult> results = operation.execute(classifierRecords);
+    }
+
+    private void validateMerge(final Classifiers classifiers) {
+        log.debug(String.format("Validating merging %s", classifiers));
+
+        final List<String> problems = checkAvailability(classifiers);
+
+        if (!problems.isEmpty()) {
+            throw TiesException.invalidClassifiersException(problems);
+        }
+    }
+
+    private void validateDelete(final Classifiers classifiers) {
+        log.debug(String.format("Validating deleting %s", classifiers));
+
+        for (String classifier : classifiers.data()) {
+            final String schemaName = classifier.split(":")[0];
+            if (!modelRepository.doesModuleExists(TIES_CONSUMER_DATA, schemaName)) {
+                throw TiesException.invalidSchema(schemaName);
+            }
+        }
+    }
+
+    private List<String> checkAvailability(final Classifiers classifiers) {
+        final List<String> invalidClassifiers = new ArrayList<>(classifiers.data());
+
+        classifiers.data().stream().filter(classifier -> consumerDataCache.getClassifiers().contains(classifier)).forEach(
+                invalidClassifiers::remove);
+
+        return invalidClassifiers;
+    }
+
+    private void runMethodSafe(Consumer<Classifiers> consumer, Classifiers classifiers) {
+        try {
+            consumer.accept(classifiers);
+        } catch (TiesException ex) {
+            log.error("Exception during validation", ex);
+            throw ex;
+        }
+    }
+}
index 8d4f66f..22e6acf 100644 (file)
  */
 package org.oran.smo.teiv.exposure.classifiers.rest.controller;
 
+import java.util.Collections;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import io.micrometer.core.annotation.Timed;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import jakarta.servlet.http.HttpServletRequest;
+
+import org.oran.smo.teiv.CustomMetrics;
 import org.oran.smo.teiv.api.ClassifiersApi;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.audit.AuditMapper;
+import org.oran.smo.teiv.exposure.audit.LoggerHandler;
+import org.oran.smo.teiv.exposure.classifiers.api.ClassifiersService;
 import org.oran.smo.teiv.utils.TiesConstants;
-
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+@Slf4j
 @RestController
 @RequestMapping(TiesConstants.REQUEST_MAPPING)
+@RequiredArgsConstructor
 public class ClassifiersRestController implements ClassifiersApi {
 
+    private final ClassifiersService classifiersService;
+    private final CustomMetrics customMetrics;
+    private final LoggerHandler loggerHandler;
+    private final HttpServletRequest context;
+
+    @Value("${consumer-data.batch-size}")
+    private int limit;
+
+    @Override
+    @Timed("ties_exposure_http_update_classifiers_seconds")
+    public ResponseEntity<Void> updateClassifier(final String accept, final String contentType,
+            final OranTeivClassifier oranTeivClassifier) {
+        return runWithFailCheck(() -> {
+            if (Optional.ofNullable(oranTeivClassifier.getEntityIds()).orElseGet(Collections::emptyList).size() + Optional
+                    .ofNullable(oranTeivClassifier.getRelationshipIds()).orElseGet(Collections::emptyList).size() > limit) {
+                throw TiesException.clientException("Limit exceeded",
+                        "Number of entities and relationships exceeded the limit");
+            }
+            runSafeMethod(() -> classifiersService.update(oranTeivClassifier), status -> loggerHandler.logAudit(log,
+                    AuditMapper.fromClassifiersRequest(oranTeivClassifier, status).toString(), context));
+
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        }, customMetrics::incrementNumUnsuccessfullyUpdatedClassifiers);
+    }
+
+    private <T> T runWithFailCheck(final Supplier<T> supp, final Runnable runnable) {
+        try {
+            return supp.get();
+        } catch (Exception ex) {
+            log.error("Exception during service call", ex);
+            runnable.run();
+            throw ex;
+        }
+    }
+
+    protected void runSafeMethod(final Runnable runnable, final Consumer<HttpStatus> logAudit) {
+        try {
+            runnable.run();
+            logAudit.accept(HttpStatus.NO_CONTENT);
+        } catch (TiesException ex) {
+            logAudit.accept(ex.getStatus());
+            log.error("Exception during service call", ex);
+            throw ex;
+        }
+    }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataOperationRegistry.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataOperationRegistry.java
new file mode 100644 (file)
index 0000000..27877db
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  ============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.teiv.exposure.consumerdata;
+
+import lombok.RequiredArgsConstructor;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exposure.consumerdata.operation.ClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DecoratorsOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteDecoratorsOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.MergeClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.MergeDecoratorsOperation;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class ConsumerDataOperationRegistry {
+    private final MergeClassifiersOperation mergeClassifiersOperation;
+    private final DeleteClassifiersOperation deleteClassifiersOperation;
+    private final MergeDecoratorsOperation mergeDecoratorsOperation;
+    private final DeleteDecoratorsOperation deleteDecoratorsOperation;
+
+    /**
+     * Returns the concrete operation according to the parameter for classifiers.
+     *
+     * @param operation
+     *     coming from the request
+     * @return classifiers operation for execution
+     */
+    public ClassifiersOperation getClassifiersOperation(final OranTeivClassifier.OperationEnum operation) {
+        return switch (operation) {
+            case MERGE -> mergeClassifiersOperation;
+            case DELETE -> deleteClassifiersOperation;
+        };
+    }
+
+    /**
+     * Returns the concrete operation according to the parameter for decorators.
+     *
+     * @param operation
+     *     coming from the request
+     * @return decorators operation for execution
+     */
+    public DecoratorsOperation getDecoratorsOperation(final OranTeivDecorator.OperationEnum operation) {
+        return switch (operation) {
+            case MERGE -> mergeDecoratorsOperation;
+            case DELETE -> deleteDecoratorsOperation;
+        };
+    }
+}
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.exposure.tiespath.refiner;
+package org.oran.smo.teiv.exposure.consumerdata;
 
-import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
-import org.oran.smo.teiv.utils.path.TiesPathQuery;
-import lombok.experimental.UtilityClass;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.NotImplementedException;
+import org.oran.smo.teiv.schema.YangDataTypes;
 
-@UtilityClass
-@Slf4j
-public class TiesPathQueryRefinement {
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface ConsumerDataRepository {
+
+    /**
+     * Load classifiers set.
+     *
+     * @return the classifiers
+     */
+    Set<String> loadClassifiers();
 
     /**
-     * Parses tiesPathQuery to innerLanguageDTO.
+     * Load decorators map.
      *
-     * @param tiesPathQuery
-     *     the ties path query
-     * @return the inner language dto
+     * @return the decorators
+     */
+    Map<String, YangDataTypes> loadDecorators();
+
+    /**
+     * Store classifier in the ties_model.classifiers
+     */
+    void storeClassifiers(final List<String> elements, final String moduleName);
+
+    /**
+     * Store decorators in the ties_model.decorators
      */
-    public static FilterCriteria parseTiesPathQuery(TiesPathQuery tiesPathQuery) {
-        log.trace(tiesPathQuery.toString());
-        throw new NotImplementedException();
-    }
+    void storeDecorators(final Map<String, String> elements, final String moduleName);
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataRepositoryImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataRepositoryImpl.java
new file mode 100644 (file)
index 0000000..b6ebafb
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  ============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.teiv.exposure.consumerdata;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
+import static org.oran.smo.teiv.utils.TiesConstants.DECORATORS;
+import static org.oran.smo.teiv.utils.TiesConstants.MODULE_REFERENCE;
+import static org.oran.smo.teiv.utils.TiesConstants.MODULE_REFERENCE_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+import static org.oran.smo.teiv.utils.TiesConstants.SEMICOLON_SEPARATION;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jooq.DSLContext;
+import org.jooq.Field;
+import org.jooq.InsertValuesStepN;
+import org.jooq.Record;
+import org.jooq.Record1;
+import org.jooq.Record2;
+import org.jooq.SelectConditionStep;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.schema.YangDataTypes;
+import org.oran.smo.teiv.utils.TiesConstants;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ConsumerDataRepositoryImpl implements ConsumerDataRepository {
+    private final DSLContext readDataDslContext;
+    private final DSLContext writeDataDslContext;
+
+    @Override
+    public Set<String> loadClassifiers() {
+        final Field<Object> classifierName = field("classifiers.name").as("classifierName");
+        SelectConditionStep<Record1<Object>> availableClassifiers = runMethodSafe(() -> readDataDslContext.select(
+                classifierName).from(String.format(TIES_CONSUMER_DATA, CLASSIFIERS)).join(String.format(TIES_CONSUMER_DATA,
+                        MODULE_REFERENCE)).on(field("\"moduleReferenceName\"").eq(field(String.format(TIES_CONSUMER_DATA,
+                                MODULE_REFERENCE) + ".name"))).where(field("status").like(TiesConstants.IN_USAGE)));
+        Set<String> result = new HashSet<>();
+        for (Record record : availableClassifiers) {
+            result.add((String) record.get("classifierName"));
+        }
+        return result;
+    }
+
+    @Override
+    public Map<String, YangDataTypes> loadDecorators() {
+        final Field<Object> decoratorName = field("decorators.name").as("decoratorName");
+        final Field<Object> dataType = field("decorators.\"dataType\"").as("dataType");
+        SelectConditionStep<Record2<Object, Object>> availableDecorators = runMethodSafe(() -> readDataDslContext.select(
+                decoratorName, dataType).from(String.format(TIES_CONSUMER_DATA, DECORATORS)).join(String.format(
+                        TIES_CONSUMER_DATA, MODULE_REFERENCE)).on(field("\"moduleReferenceName\"").eq(field(String.format(
+                                TIES_CONSUMER_DATA, MODULE_REFERENCE) + ".name"))).where(field("status").like(
+                                        TiesConstants.IN_USAGE)));
+        Map<String, YangDataTypes> result = new HashMap<>();
+        for (Record record : availableDecorators) {
+            result.put((String) record.get("decoratorName"), YangDataTypes.fromYangDataType("" + record.get("dataType")));
+        }
+        return result;
+    }
+
+    @Override
+    public void storeClassifiers(final List<String> elements, final String moduleName) {
+        insertValues(CLASSIFIERS, List.of(NAME, String.format(QUOTED_STRING, MODULE_REFERENCE_NAME)), executable -> {
+            for (String element : elements) {
+                executable = executable.values(String.format(SEMICOLON_SEPARATION, moduleName, element), moduleName);
+            }
+        });
+    }
+
+    @Override
+    public void storeDecorators(final Map<String, String> elements, final String moduleName) {
+        insertValues(DECORATORS, List.of(NAME, String.format(QUOTED_STRING, "dataType"), String.format(QUOTED_STRING,
+                MODULE_REFERENCE_NAME)), executable -> {
+                    for (Map.Entry<String, String> element : elements.entrySet()) {
+                        executable = executable.values(String.format(SEMICOLON_SEPARATION, moduleName, element.getKey()),
+                                element.getValue(), moduleName);
+                    }
+                });
+    }
+
+    private void insertValues(final String tableName, final List<String> columns,
+            final Consumer<InsertValuesStepN<?>> consumer) {
+        InsertValuesStepN<?> executable = writeDataDslContext.insertInto(table(String.format(TIES_CONSUMER_DATA,
+                tableName))).columns(columns.stream().map(column -> field(column, String.class)).toList());
+
+        consumer.accept(executable);
+
+        runMethodSafe(executable::execute);
+    }
+
+    protected <T> T runMethodSafe(Supplier<T> supp) {
+        try {
+            return supp.get();
+        } catch (TiesException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            log.error("Sql exception during query execution", ex);
+            throw TiesException.serverSQLException();
+        }
+    }
+
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataValidator.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/ConsumerDataValidator.java
new file mode 100644 (file)
index 0000000..5d58247
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  ============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.teiv.exposure.consumerdata;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.consumerdata.model.Classifiers;
+import org.oran.smo.teiv.exposure.consumerdata.model.Decorators;
+import org.oran.smo.teiv.schema.ConsumerDataCache;
+import org.oran.smo.teiv.schema.YangDataTypes;
+import org.springframework.stereotype.Service;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class ConsumerDataValidator {
+
+    private final ConsumerDataCache consumerDataCache;
+
+    public void validate(final Classifiers classifiers) {
+        log.debug(String.format("Validating %s", classifiers));
+
+        final List<String> problems = checkAvailability(classifiers);
+
+        if (!problems.isEmpty()) {
+            throw TiesException.invalidClassifiersException(problems);
+        }
+    }
+
+    private List<String> checkAvailability(final Classifiers classifiers) {
+        final List<String> invalidClassifiers = new ArrayList<>(classifiers.data());
+
+        classifiers.data().stream().filter(classifier -> !consumerDataCache.getValidClassifiers(classifier).isEmpty())
+                .forEach(invalidClassifiers::remove);
+
+        return invalidClassifiers;
+    }
+
+    public void validate(final Decorators decorators) {
+        log.debug(String.format("Validating %s", decorators));
+
+        final Map<String, String> problems = checkAvailability(decorators);
+
+        if (!problems.isEmpty()) {
+            throw TiesException.invalidDecoratorsException(problems);
+        }
+    }
+
+    private Map<String, String> checkAvailability(final Decorators decorators) {
+        final Map<String, String> invalidKeys = new HashMap<>();
+
+        for (String key : decorators.data().keySet()) {
+            invalidKeys.put(key, "is_not_available");
+        }
+
+        decorators.data().forEach((key, value) -> {
+
+            if (consumerDataCache.getDecorators().containsKey(key)) {
+
+                final boolean isCompatible = checkCompatibility(key, value);
+
+                if (isCompatible) {
+                    invalidKeys.remove(key);
+                } else {
+                    invalidKeys.put(key, "is_not_compatible");
+                }
+            }
+        });
+
+        return invalidKeys;
+    }
+
+    private boolean checkCompatibility(final String key, final Object value) {
+        return consumerDataCache.getDecorators().get(key).equals(YangDataTypes.fromRequestDataType(value.getClass()));
+    }
+}
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.exposure.spi.impl;
-
-import lombok.Data;
+package org.oran.smo.teiv.exposure.consumerdata.model;
 
 import java.util.List;
 
-@Data
-public class StoredSchema {
-    private String name;
-    private String namespace;
-    private String domain;
-    private String revision;
-    private List<String> includedModules;
-    private String content;
-    private String ownerAppId;
-    private String status;
+import lombok.Builder;
+
+@Builder
+public record Classifiers(List<String> data, List<String> entityIds, List<String> relationshipIds) implements
+        ConsumerData<List<String>> {
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/ConsumerData.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/ConsumerData.java
new file mode 100644 (file)
index 0000000..23ec8b0
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.model;
+
+import java.util.List;
+
+public interface ConsumerData<T> {
+    /**
+     * Returns the actual consumer data.
+     *
+     * @return data
+     */
+    T data();
+
+    /**
+     * Returns the entity ids.
+     *
+     * @return list of entity ids
+     */
+    List<String> entityIds();
+
+    /**
+     * Returns the relationship ids.
+     *
+     * @return list of relationship ids
+     */
+    List<String> relationshipIds();
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/Decorators.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/Decorators.java
new file mode 100644 (file)
index 0000000..cb56202
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.model;
+
+import lombok.Builder;
+
+import java.util.List;
+import java.util.Map;
+
+@Builder
+public record Decorators(Map<String, Object> data, List<String> entityIds, List<String> relationshipIds) implements
+        ConsumerData<Map<String, Object>> {
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/PersistableIdMap.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/model/PersistableIdMap.java
new file mode 100644 (file)
index 0000000..dee0062
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.model;
+
+import lombok.Builder;
+import org.oran.smo.teiv.schema.Persistable;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Builder
+public record PersistableIdMap(Set<String> idsNotFound, Map<Persistable, List<String>> persistableWithIds) {
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ClassifiersOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ClassifiersOperation.java
new file mode 100644 (file)
index 0000000..9e23820
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import org.jooq.DSLContext;
+
+import lombok.extern.slf4j.Slf4j;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.jooq.Result;
+import org.jooq.Record;
+import org.jooq.JSONB;
+import org.oran.smo.teiv.schema.Persistable;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.oran.smo.teiv.utils.JooqTypeConverter;
+
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Slf4j
+public abstract class ClassifiersOperation extends ConsumerDataOperation<List<String>> {
+
+    protected ClassifiersOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    protected Map<String, OperationResult> createOperationResults(final Persistable persistable,
+            final Result<Record> results) {
+        final Map<String, OperationResult> opResults = new HashMap<>();
+        for (Record record : results) {
+            String id = (String) record.get(persistable.getIdColumnNameWithTableName());
+            List<String> classifierListAfterUpdate = JooqTypeConverter.jsonbToList(record.get(String.format(QUOTED_STRING,
+                    persistable.getClassifiersColumnName()), JSONB.class));
+            OperationResult operationResult = OperationResult.createClassifierOperationResult(id, persistable.getName(),
+                    persistable.getCategory(), classifierListAfterUpdate);
+
+            opResults.put(id, operationResult);
+        }
+        return opResults;
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ConsumerDataOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/ConsumerDataOperation.java
new file mode 100644 (file)
index 0000000..dc329e4
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jooq.Configuration;
+import org.jooq.DSLContext;
+import org.jooq.Record1;
+import org.jooq.Result;
+import org.jooq.SelectConditionStep;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+
+import org.jooq.exception.DataAccessException;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.consumerdata.model.ConsumerData;
+import org.oran.smo.teiv.exposure.consumerdata.model.PersistableIdMap;
+import org.oran.smo.teiv.schema.Persistable;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.service.models.OperationResult;
+
+@Slf4j
+@RequiredArgsConstructor
+public abstract class ConsumerDataOperation<C> {
+
+    private final DSLContext readDataDslContext;
+    protected final DSLContext writeDataDslContext;
+
+    protected abstract List<OperationResult> performOperation(final PersistableIdMap map, final C consumerData,
+            final DSLContext writeDataDslContext);
+
+    /**
+     * Executes the operation for the given consumer data.
+     *
+     * @param consumerData
+     *     which holds the information for classifiers/decorators, entity ids and relationship ids
+     * @return Map of Operation Results. Key is the ID of the Entity/Relationship.
+     */
+    public List<OperationResult> execute(final ConsumerData<C> consumerData) {
+        return runMethodSafe(() -> {
+            final Pair<PersistableIdMap, PersistableIdMap> maps = checkIfIdsExist(consumerData);
+            final PersistableIdMap entityIdMap = maps.getKey();
+            final PersistableIdMap relationshipIdMap = maps.getValue();
+
+            final List<OperationResult> results = new ArrayList<>();
+
+            writeDataDslContext.transaction((Configuration config) -> {
+                if (!consumerData.entityIds().isEmpty()) {
+                    final List<OperationResult> entityResults = performOperation(entityIdMap, consumerData.data(), config
+                            .dsl());
+                    results.addAll(entityResults);
+                }
+
+                if (!consumerData.relationshipIds().isEmpty()) {
+                    final List<OperationResult> relshipResults = performOperation(relationshipIdMap, consumerData.data(),
+                            config.dsl());
+                    results.addAll(relshipResults);
+                }
+            });
+
+            return results;
+        });
+    }
+
+    protected Pair<PersistableIdMap, PersistableIdMap> checkIfIdsExist(final ConsumerData<C> consumerData) {
+        log.debug("Checking entity and relationship ids");
+
+        final List<String> entityNames = SchemaRegistry.getEntityNames();
+        final List<String> relationNames = SchemaRegistry.getRelationNames();
+
+        final PersistableIdMap entityCheckResult = performCheck(consumerData.entityIds(), entityNames,
+                SchemaRegistry::getEntityTypeByName);
+        final PersistableIdMap relationshipCheckResult = performCheck(consumerData.relationshipIds(), relationNames,
+                SchemaRegistry::getRelationTypeByName);
+
+        if (!entityCheckResult.idsNotFound().isEmpty() || !relationshipCheckResult.idsNotFound().isEmpty()) {
+
+            throw TiesException.resourceNotFoundException(entityCheckResult.idsNotFound(), relationshipCheckResult
+                    .idsNotFound());
+        }
+
+        return new ImmutablePair<>(entityCheckResult, relationshipCheckResult);
+    }
+
+    private PersistableIdMap performCheck(final List<String> ids, final List<String> names,
+            final Function<String, Persistable> supp) {
+        final Map<Persistable, List<String>> persistableWithIds = new HashMap<>();
+        final Set<String> idsNotFound = new HashSet<>(ids);
+
+        for (String name : names) {
+            if (!idsNotFound.isEmpty()) {
+
+                final Persistable persistable = supp.apply(name);
+                final SelectConditionStep<Record1<Object>> select = readDataDslContext.select(field(persistable
+                        .getIdColumnNameWithTableName())).from(table(persistable.getTableName())).where(field(persistable
+                                .getIdColumnNameWithTableName()).in(idsNotFound));
+                final Result<Record1<Object>> result = select.fetch();
+
+                for (Record1<Object> record : result) {
+
+                    if (!persistableWithIds.containsKey(persistable)) {
+
+                        List<String> list = new ArrayList<>();
+                        list.add(record.get(0, String.class));
+
+                        persistableWithIds.put(persistable, list);
+                    } else {
+                        persistableWithIds.get(persistable).add(record.get(0, String.class));
+                    }
+
+                    idsNotFound.remove(record.get(0, String.class));
+                }
+            } else {
+                break;
+            }
+        }
+        return PersistableIdMap.builder().persistableWithIds(persistableWithIds).idsNotFound(idsNotFound).build();
+    }
+
+    protected <T> T runMethodSafe(final Supplier<T> supplier) {
+        try {
+            return supplier.get();
+        } catch (DataAccessException ex) {
+            log.error("Sql exception during query execution", ex);
+            throw TiesException.serverSQLException();
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DecoratorsOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DecoratorsOperation.java
new file mode 100644 (file)
index 0000000..1981cd6
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import java.util.Map;
+
+import org.jooq.DSLContext;
+import org.jooq.JSONB;
+import org.jooq.Result;
+import org.jooq.Record;
+
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.schema.Persistable;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.oran.smo.teiv.utils.JooqTypeConverter;
+
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Slf4j
+public abstract class DecoratorsOperation extends ConsumerDataOperation<Map<String, Object>> {
+
+    protected DecoratorsOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    protected void saveResults(final Persistable persistable, final Result<Record> newResults,
+            final Map<String, OperationResult> results) {
+        for (Record record : newResults) {
+            String id = (String) record.get(persistable.getIdColumnNameWithTableName());
+            Map<String, Object> decoratorsAfterUpdate = JooqTypeConverter.jsonbToMap(record.get(String.format(QUOTED_STRING,
+                    persistable.getDecoratorsColumnName()), JSONB.class));
+            OperationResult operationResult = OperationResult.createDecoratorOperationResult(id, persistable.getName(),
+                    persistable.getCategory(), decoratorsAfterUpdate);
+
+            results.put(id, operationResult);
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteClassifiersOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteClassifiersOperation.java
new file mode 100644 (file)
index 0000000..f031072
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.jooq.Configuration;
+import org.jooq.Condition;
+import org.jooq.DSLContext;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.UpdateResultStep;
+import org.oran.smo.teiv.exposure.consumerdata.model.ConsumerData;
+import org.oran.smo.teiv.exposure.consumerdata.model.PersistableIdMap;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Component;
+
+import static org.jooq.impl.DSL.exists;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.select;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Component
+public class DeleteClassifiersOperation extends ClassifiersOperation {
+
+    public DeleteClassifiersOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    @Override
+    protected List<OperationResult> performOperation(final PersistableIdMap map, final List<String> consumerData,
+            final DSLContext writeDataDslContext) {
+
+        final Map<String, OperationResult> allResults = new HashMap<>();
+
+        map.persistableWithIds().forEach((persistable, ids) -> {
+
+            for (String data : consumerData) {
+                final String classifiersColumnName = String.format(QUOTED_STRING, persistable.getClassifiersColumnName());
+                final Field<JSONB> targetField = field(classifiersColumnName, JSONB.class);
+                final Field<JSONB> concatField = field(String.format("%s - '%s'", classifiersColumnName, data),
+                        JSONB.class);
+
+                final UpdateResultStep<Record> update = writeDataDslContext.update(table(persistable.getTableName())).set(
+                        targetField, concatField).where(existsCondition(classifiersColumnName, data)).and(field(persistable
+                                .getIdColumnNameWithTableName()).in(ids)).returning(field(persistable
+                                        .getIdColumnNameWithTableName()), field(String.format(QUOTED_STRING, persistable
+                                                .getClassifiersColumnName()), JSONB.class));
+
+                final Result<Record> newResults = update.fetch();
+                final Map<String, OperationResult> newOpResults = createOperationResults(persistable, newResults);
+                allResults.putAll(newOpResults);
+            }
+        });
+
+        return new ArrayList<>(allResults.values());
+    }
+
+    private Condition existsCondition(final String classifiersColumnName, final String data) {
+        return exists(select(field("1")).from(table("jsonb_array_elements_text(" + classifiersColumnName + ")").as(
+                "element")).where(field("element").eq(data)));
+    }
+
+    /**
+     * Executes the operation for the given consumer data for specific entity type.
+     *
+     * @param consumerData
+     *     which holds the information for classifiers/decorators, entity ids and relationship ids
+     * @param entityType
+     *     entity type
+     */
+    public List<OperationResult> delete(final ConsumerData<List<String>> consumerData, EntityType entityType) {
+        PersistableIdMap persistableIdMap = PersistableIdMap.builder().persistableWithIds(Map.of(entityType, consumerData
+                .entityIds())).build();
+
+        final List<OperationResult> results = new ArrayList<>();
+        writeDataDslContext.transaction((Configuration config) -> results.addAll(performOperation(persistableIdMap,
+                consumerData.data(), config.dsl())));
+        return results;
+    }
+
+    /**
+     * Executes the operation for the given consumer data for specific relation type.
+     *
+     * @param consumerData
+     *     which holds the information for classifiers/decorators, entity ids and relationship ids
+     * @param relationType
+     *     relation type
+     */
+    public List<OperationResult> delete(final ConsumerData<List<String>> consumerData, RelationType relationType) {
+        PersistableIdMap persistableIdMap = PersistableIdMap.builder().persistableWithIds(Map.of(relationType, consumerData
+                .relationshipIds())).build();
+
+        final List<OperationResult> results = new ArrayList<>();
+        writeDataDslContext.transaction((Configuration config) -> results.addAll(performOperation(persistableIdMap,
+                consumerData.data(), config.dsl())));
+        return results;
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteDecoratorsOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/DeleteDecoratorsOperation.java
new file mode 100644 (file)
index 0000000..68e4cf8
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.jooq.Condition;
+import org.jooq.Configuration;
+import org.jooq.DSLContext;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.Record;
+import org.oran.smo.teiv.exposure.consumerdata.model.ConsumerData;
+import org.oran.smo.teiv.exposure.consumerdata.model.PersistableIdMap;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Component;
+
+import org.jooq.Result;
+import org.jooq.UpdateResultStep;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.jooq.impl.DSL.condition;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Component
+public class DeleteDecoratorsOperation extends DecoratorsOperation {
+
+    public DeleteDecoratorsOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    @Override
+    protected List<OperationResult> performOperation(final PersistableIdMap map, final Map<String, Object> consumerData,
+            final DSLContext writeDataDslContext) {
+
+        final Map<String, OperationResult> allResults = new HashMap<>();
+
+        map.persistableWithIds().forEach((persistable, ids) -> consumerData.forEach((key, value) -> {
+
+            final String decoratorsColumnName = String.format(QUOTED_STRING, persistable.getDecoratorsColumnName());
+            final Field<JSONB> targetField = field(decoratorsColumnName, JSONB.class);
+            final Field<JSONB> concatField = field(String.format("%s - '%s'", decoratorsColumnName, key), JSONB.class);
+
+            final UpdateResultStep<Record> update = writeDataDslContext.update(table(persistable.getTableName())).set(
+                    targetField, concatField).where(keyExistsCondition(decoratorsColumnName, key).and(field(persistable
+                            .getIdColumnNameWithTableName()).in(ids))).returning(field(persistable
+                                    .getIdColumnNameWithTableName()), field(String.format(QUOTED_STRING, persistable
+                                            .getDecoratorsColumnName()), JSONB.class));
+
+            final Result<Record> newResults = update.fetch();
+            saveResults(persistable, newResults, allResults);
+        }));
+
+        return new ArrayList<>(allResults.values());
+    }
+
+    private Condition keyExistsCondition(final String decoratorsColumnName, final String key) {
+        return condition(String.format("jsonb_exists(%s, '%s')", decoratorsColumnName, key));
+    }
+
+    /**
+     * Executes the operation for the given consumer data for specific entity type.
+     *
+     * @param consumerData
+     *     which holds the information for classifiers/decorators, entity ids and relationship ids
+     * @param entityType
+     *     entity type
+     */
+    public List<OperationResult> delete(final ConsumerData<Map<String, Object>> consumerData, final EntityType entityType) {
+        PersistableIdMap persistableIdMap = PersistableIdMap.builder().persistableWithIds(Map.of(entityType, consumerData
+                .entityIds())).build();
+        final List<OperationResult> results = new ArrayList<>();
+        writeDataDslContext.transaction((Configuration config) -> results.addAll(performOperation(persistableIdMap,
+                consumerData.data(), config.dsl())));
+        return results;
+    }
+
+    /**
+     * Executes the operation for the given consumer data for specific relation type.
+     *
+     * @param consumerData
+     *     which holds the information for classifiers/decorators, entity ids and relationship ids
+     * @param relationType
+     *     relation type
+     */
+    public List<OperationResult> delete(final ConsumerData<Map<String, Object>> consumerData,
+            final RelationType relationType) {
+        PersistableIdMap persistableIdMap = PersistableIdMap.builder().persistableWithIds(Map.of(relationType, consumerData
+                .relationshipIds())).build();
+        final List<OperationResult> results = new ArrayList<>();
+        writeDataDslContext.transaction((Configuration config) -> results.addAll(performOperation(persistableIdMap,
+                consumerData.data(), config.dsl())));
+        return results;
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeClassifiersOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeClassifiersOperation.java
new file mode 100644 (file)
index 0000000..e251eb7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jooq.DSLContext;
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.UpdateResultStep;
+import org.oran.smo.teiv.exposure.consumerdata.model.PersistableIdMap;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Component;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.notExists;
+import static org.jooq.impl.DSL.select;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Component
+@Slf4j
+public class MergeClassifiersOperation extends ClassifiersOperation {
+
+    public MergeClassifiersOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    @Override
+    protected List<OperationResult> performOperation(final PersistableIdMap map, final List<String> consumerData,
+            final DSLContext writeDataDslContext) {
+
+        // Newer operations on the same entity/relationship makes old OperationResults obsolete,
+        // since we only care about the end result for given entity/relationship.
+        // We use a map with entity/relship ID as key,
+        // so we can automatically discard intermediary results.
+        final Map<String, OperationResult> allResults = new HashMap<>();
+
+        map.persistableWithIds().forEach((persistable, ids) -> {
+
+            for (String data : consumerData) {
+                final String classifiersColumnName = String.format(QUOTED_STRING, persistable.getClassifiersColumnName());
+                final String concat = classifiersColumnName + " || '" + String.format(QUOTED_STRING, data) + "'";
+
+                final Field<JSONB> targetField = field(classifiersColumnName, JSONB.class);
+                final Field<JSONB> concatField = field(concat, JSONB.class);
+
+                final UpdateResultStep<Record> update = writeDataDslContext.update(table(persistable.getTableName())).set(
+                        targetField, concatField).where(notExistsCondition(classifiersColumnName, data)).and(field(
+                                persistable.getIdColumnNameWithTableName()).in(ids)).returning(field(persistable
+                                        .getIdColumnNameWithTableName()), field(String.format(QUOTED_STRING, persistable
+                                                .getClassifiersColumnName()), JSONB.class));
+
+                final Result<Record> newResults = update.fetch();
+                final Map<String, OperationResult> newOpResults = createOperationResults(persistable, newResults);
+                allResults.putAll(newOpResults);
+            }
+        });
+
+        // Simplifying return type, as we need it to be a List anyway.
+        return new ArrayList<>(allResults.values());
+    }
+
+    private Condition notExistsCondition(final String classifiersColumnName, final String data) {
+        return notExists(select(field("1")).from(table("jsonb_array_elements_text(" + classifiersColumnName + ")").as(
+                "element")).where(field("element").eq(data)));
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeDecoratorsOperation.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/consumerdata/operation/MergeDecoratorsOperation.java
new file mode 100644 (file)
index 0000000..3493bb9
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  ============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.teiv.exposure.consumerdata.operation;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jooq.Condition;
+import org.jooq.DSLContext;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.UpdateResultStep;
+import org.oran.smo.teiv.exposure.consumerdata.model.PersistableIdMap;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+import static org.jooq.impl.DSL.condition;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.not;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Slf4j
+@Component
+public class MergeDecoratorsOperation extends DecoratorsOperation {
+
+    public MergeDecoratorsOperation(DSLContext readDataDslContext, DSLContext writeDataDslContext) {
+        super(readDataDslContext, writeDataDslContext);
+    }
+
+    @Override
+    protected List<OperationResult> performOperation(final PersistableIdMap map, final Map<String, Object> consumerData,
+            final DSLContext writeDataDslContext) {
+
+        final Map<String, OperationResult> allResults = new HashMap<>();
+
+        map.persistableWithIds().forEach((persistable, ids) -> consumerData.forEach((key, value) -> {
+
+            final String decoratorsColumnName = String.format(QUOTED_STRING, persistable.getDecoratorsColumnName());
+            final String concat = String.format("%s || '{%s: %s}'", decoratorsColumnName, transformKey(key), transformValue(
+                    value));
+
+            final Field<JSONB> targetField = field(decoratorsColumnName, JSONB.class);
+            final Field<JSONB> concatField = field(concat, JSONB.class);
+
+            final UpdateResultStep<Record> update = writeDataDslContext.update(table(persistable.getTableName())).set(
+                    targetField, concatField).where(not(keyValuePairExistsCondition(decoratorsColumnName, key, value)).or(
+                            not(keyExistsCondition(decoratorsColumnName, key))).and(field(persistable
+                                    .getIdColumnNameWithTableName()).in(ids))).returning(field(persistable
+                                            .getIdColumnNameWithTableName()), field(String.format(QUOTED_STRING, persistable
+                                                    .getDecoratorsColumnName()), JSONB.class));
+
+            final Result<Record> newResults = update.fetch();
+            saveResults(persistable, newResults, allResults);
+        }));
+        return new ArrayList<>(allResults.values());
+    }
+
+    private String transformKey(final String key) {
+        return String.format("\"%s\"", key);
+    }
+
+    private String transformValue(final Object value) {
+        return value instanceof String ? String.format("\"%s\"", value) : value.toString();
+    }
+
+    private Condition keyValuePairExistsCondition(final String decoratorsColumnName, final String key, final Object value) {
+        return condition(String.format("%s -> '%s' = '%s'", decoratorsColumnName, key, transformValue(value)));
+    }
+
+    private Condition keyExistsCondition(final String decoratorsColumnName, final String key) {
+        return condition(String.format("jsonb_exists(%s, '%s')", decoratorsColumnName, key));
+    }
+}
index 85d5c48..99e10be 100644 (file)
@@ -25,45 +25,43 @@ import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
 import org.oran.smo.teiv.api.model.OranTeivEntityTypes;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-
-import java.util.Map;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
 
 public interface DataService {
 
     /**
      * Get all the available topology domain types.
      *
-     * @param paginationDTO
-     *     pagination data
+     * @param requestDetails
+     *     - request details
      *
      * @return a collection of domain types
      */
-    OranTeivDomains getDomainTypes(final PaginationDTO paginationDTO);
+    OranTeivDomains getDomainTypes(final RequestDetails requestDetails);
 
     /**
      * Get all entity types in a topology domain types.
      *
      * @param domain
      *     domain name
-     * @param paginationDTO
-     *     pagination data
+     * @param requestDetails
+     *     - request details
      *
      * @return a collection of domain types
      */
-    OranTeivEntityTypes getTopologyEntityTypes(final String domain, final PaginationDTO paginationDTO);
+    OranTeivEntityTypes getTopologyEntityTypes(final String domain, final RequestDetails requestDetails);
 
     /**
      * Get all relationship types in a topology domain types.
      *
      * @param domain
      *     domain name
-     * @param paginationDTO
-     *     pagination data
+     ** @param requestDetails
+     *     - request details
      *
      * @return a collection of relationship types
      */
-    OranTeivRelationshipTypes getTopologyRelationshipTypes(final String domain, final PaginationDTO paginationDTO);
+    OranTeivRelationshipTypes getTopologyRelationshipTypes(final String domain, final RequestDetails requestDetails);
 
     /**
      * Get topology for entity type with specified id.
@@ -75,7 +73,7 @@ public interface DataService {
      *
      * @return a topology entity
      */
-    Map<String, Object> getTopologyById(final String entityType, final String id);
+    Object getEntityById(final String entityType, final String id);
 
     /**
      * Get topology entities that match target, scope and relationships filters.
@@ -86,13 +84,13 @@ public interface DataService {
      *     specifies the entity type and attributes to be returned to the REST response
      * @param scopeFilter
      *     specifies the attributes to match on
-     * @param paginationDTO
-     *     pagination data
+     * @param requestDetails
+     *     - request details
      *
      * @return a collection of entity data and attributes
      */
-    OranTeivEntitiesResponseMessage getTopologyByType(final String entityType, final String targetFilter,
-            final String scopeFilter, final PaginationDTO paginationDTO);
+    OranTeivEntitiesResponseMessage getTopologyByType(final String domain, final String entityType,
+            final String targetFilter, final String scopeFilter, final RequestDetails requestDetails);
 
     /**
      *
@@ -102,26 +100,34 @@ public interface DataService {
      *     specifies the entity type and attributes to be returned to the REST response
      * @param scopeFilter
      *     specifies the attributes to match on
-     * @param paginationDTO
-     *     pagination data
+     * @param requestDetails
+     *     - request details
      *
      * @return a collection of entity data and attributes
      */
     OranTeivEntitiesResponseMessage getEntitiesByDomain(final String domain, final String targetFilter,
-            final String scopeFilter, final PaginationDTO paginationDTO);
+            final String scopeFilter, final RequestDetails requestDetails);
 
     /**
      * Get all relationships for entityType with specified id
      *
+     * @param domain
+     *     domain name
      * @param entityType
      *     type of entity, e.g. NRCellDU
      * @param id
      *     unique identifier of entity
+     * @param targetFilter
+     *     specifies the entity type and attributes to be returned to the REST response
+     * @param scopeFilter
+     *     specifies the attributes to match on
+     * @param requestDetails
+     *     - request details
      *
      * @return a collection of relationships for entity type
      */
-    OranTeivRelationshipsResponseMessage getAllRelationshipsForObjectId(final String entityType, final String id,
-            final PaginationDTO paginationDTO);
+    OranTeivRelationshipsResponseMessage getAllRelationshipsForObjectId(final String domain, final String entityType,
+            final String targetFilter, final String scopeFilter, final String id, final RequestDetails requestDetails);
 
     /**
      * Get relationship with specified id
@@ -133,7 +139,7 @@ public interface DataService {
      *
      * @return a topology relationship
      */
-    Map<String, Object> getRelationshipById(final String relationshipType, final String id);
+    Object getRelationshipById(final String relationshipType, final String id);
 
     /**
      *
@@ -141,11 +147,11 @@ public interface DataService {
      *     type of relationship
      * @param scopeFilter
      *     specifies the attributes to match on
-     * @param paginationDTO
-     *     pagination data
+     * @param requestDetails
+     *     - request details
      *
      * @return relationships by relationship type
      */
-    OranTeivRelationshipsResponseMessage getRelationshipsByType(final String relationshipType, final String scopeFilter,
-            final PaginationDTO paginationDTO);
+    OranTeivRelationshipsResponseMessage getRelationshipsByType(final String domain, final String relationshipType,
+            final String targetFilter, final String scopeFilter, final RequestDetails requestDetails);
 }
index 1c6f220..323586a 100644 (file)
@@ -22,8 +22,22 @@ package org.oran.smo.teiv.exposure.data.api.impl;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
+import org.oran.smo.teiv.exposure.tiespath.resolver.ScopeResolver;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.DataRepository;
+import org.oran.smo.teiv.exposure.spi.mapper.EntityMapper;
+import org.oran.smo.teiv.exposure.spi.mapper.RelationshipMapper;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.InnerFilterCriteria;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.refiner.BasePathRefinement;
+import org.oran.smo.teiv.exposure.tiespath.resolver.TargetResolver;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
 import org.springframework.stereotype.Service;
 
 import org.oran.smo.teiv.api.model.OranTeivDomains;
@@ -36,224 +50,218 @@ import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipTypesItemsInner;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
 import org.oran.smo.teiv.exposure.data.api.DataService;
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.mapper.MapperUtility;
-import org.oran.smo.teiv.exposure.spi.mapper.PageMetaData;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
 import org.oran.smo.teiv.schema.EntityType;
 import org.oran.smo.teiv.schema.RelationType;
 import org.oran.smo.teiv.schema.SchemaRegistry;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 
-@Slf4j
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.firstHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.getViableLimit;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.lastHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.nextHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.prevHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.selfHref;
+
 @Service
 @RequiredArgsConstructor
 public class DataServiceImpl implements DataService {
-    private final DataPersistanceService dataPersistanceService;
-    private final MapperUtility mapperUtility;
+    private final DataRepository dataRepository;
+    private final ScopeResolver scopeResolver;
+    private final TargetResolver targetResolver;
+    private final EntityMapper entityMapper;
+    private final RelationshipMapper relationshipMapper;
+    private final BasePathRefinement basePathRefinement;
 
     @Override
-    public OranTeivDomains getDomainTypes(final PaginationDTO paginationDTO) {
-        final Map<String, Object> result = mapperUtility.wrapList(new ArrayList<>(SchemaRegistry.getDomains()),
-                paginationDTO);
-        final List<OranTeivDomainsItemsInner> items = new ArrayList<>();
-        final List<Object> itemsList = (List<Object>) result.get("items");
-        itemsList.forEach(domain -> items.add(OranTeivDomainsItemsInner.builder().name(domain.toString()).entityTypes(
-                OranTeivHref.builder().href(paginationDTO.getBasePath() + "/" + domain + "/entity-types").build())
-                .relationshipTypes(OranTeivHref.builder().href(paginationDTO
-                        .getBasePath() + "/" + domain + "/relationship-types").build()).build()));
-        return getDomainsResponseMessage(result, items, paginationDTO.getLimit(), paginationDTO.getOffset());
+    public OranTeivDomains getDomainTypes(final RequestDetails requestDetails) {
+        final Set<String> domains = SchemaRegistry.getDomains();
+        final int totalCount = domains.size();
+
+        final List<OranTeivDomainsItemsInner> items = domains.stream().skip(requestDetails.getOffset()).limit(
+                getViableLimit(requestDetails.getOffset(), requestDetails.getLimit(), totalCount)).map(
+                        domain -> OranTeivDomainsItemsInner.builder().name(domain).entityTypes(OranTeivHref.builder().href(
+                                requestDetails.getBasePath() + "/" + domain + "/entity-types").build()).relationshipTypes(
+                                        OranTeivHref.builder().href(requestDetails
+                                                .getBasePath() + "/" + domain + "/relationship-types").build()).build())
+                .toList();
+
+        return OranTeivDomains.builder().items(items).first(firstHref(requestDetails)).prev(prevHref(requestDetails,
+                totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails, totalCount)).last(lastHref(
+                        requestDetails, totalCount)).totalCount(totalCount).build();
     }
 
     @Override
-    public OranTeivEntityTypes getTopologyEntityTypes(final String domain, final PaginationDTO paginationDTO) {
-        final Map<String, Object> result = mapperUtility.wrapList(new ArrayList<>(SchemaRegistry.getEntityNamesByDomain(
-                domain)), paginationDTO);
-        final List<OranTeivEntityTypesItemsInner> items = new ArrayList<>();
-        final List<String> entities = SchemaRegistry.getEntityNamesByDomain(domain);
-        entities.stream().forEach(entity -> {
-            OranTeivEntityTypesItemsInner inner = new OranTeivEntityTypesItemsInner();
-            OranTeivHref entitiesHref = new OranTeivHref();
-            entitiesHref.setHref(paginationDTO.getBasePath() + "/" + entity + "/entities");
-            inner.setName(entity);
-            inner.setEntities(entitiesHref);
-            items.add(inner);
-        });
-        return getEntityTypesResponseMessage(result, items, paginationDTO.getLimit(), paginationDTO.getOffset());
+    public OranTeivEntityTypes getTopologyEntityTypes(final String domain, final RequestDetails requestDetails) {
+        final List<String> entityTypeNames = SchemaRegistry.getEntityNamesByDomain(domain);
+        final int totalCount = entityTypeNames.size();
+
+        final List<OranTeivEntityTypesItemsInner> items = entityTypeNames.stream().skip(requestDetails.getOffset()).limit(
+                getViableLimit(requestDetails.getOffset(), requestDetails.getLimit(), totalCount)).map(
+                        entityTypeName -> OranTeivEntityTypesItemsInner.builder().name(entityTypeName).entities(OranTeivHref
+                                .builder().href(requestDetails.getBasePath() + "/" + entityTypeName + "/entities").build())
+                                .build()).toList();
+
+        return OranTeivEntityTypes.builder().items(items).first(firstHref(requestDetails)).prev(prevHref(requestDetails,
+                totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails, totalCount)).last(lastHref(
+                        requestDetails, totalCount)).totalCount(totalCount).build();
     }
 
     @Override
-    public OranTeivRelationshipTypes getTopologyRelationshipTypes(final String domain, final PaginationDTO paginationDTO) {
-        final Map<String, Object> result = mapperUtility.wrapList(new ArrayList<>(SchemaRegistry.getRelationNamesByDomain(
-                domain)), paginationDTO);
-        final List<OranTeivRelationshipTypesItemsInner> items = new ArrayList<>();
-        final List<String> relationships = SchemaRegistry.getRelationNamesByDomain(domain);
-        relationships.stream().forEach(relationship -> {
-            OranTeivRelationshipTypesItemsInner inner = new OranTeivRelationshipTypesItemsInner();
-            OranTeivHref relationshipsHref = new OranTeivHref();
-            relationshipsHref.setHref(paginationDTO.getBasePath() + "/" + relationship + "/relationships");
-            inner.setName(relationship);
-            inner.setRelationships(relationshipsHref);
-            items.add(inner);
-        });
-        return getRelationshipTypesResponseMessage(result, items, paginationDTO.getLimit(), paginationDTO.getOffset());
+    public OranTeivRelationshipTypes getTopologyRelationshipTypes(final String domain,
+            final RequestDetails requestDetails) {
+        final List<String> relationNames = SchemaRegistry.getRelationNamesByDomain(domain);
+        final int totalCount = relationNames.size();
+
+        final List<OranTeivRelationshipTypesItemsInner> items = relationNames.stream().skip(requestDetails.getOffset())
+                .limit(getViableLimit(requestDetails.getOffset(), requestDetails.getLimit(), totalCount)).map(
+                        relationName -> OranTeivRelationshipTypesItemsInner.builder().name(relationName).relationships(
+                                OranTeivHref.builder().href(requestDetails
+                                        .getBasePath() + "/" + relationName + "/relationships").build()).build()).toList();
+
+        return OranTeivRelationshipTypes.builder().items(items).first(firstHref(requestDetails)).prev(prevHref(
+                requestDetails, totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails, totalCount)).last(
+                        lastHref(requestDetails, totalCount)).totalCount(totalCount).build();
     }
 
     @Override
-    public Map<String, Object> getTopologyById(final String entityName, final String id) {
+    public Object getEntityById(final String entityName, final String id) {
         final EntityType entityType = SchemaRegistry.getEntityTypeByName(entityName);
-        return dataPersistanceService.getTopology(entityType, id);
+        final Result<Record> result = dataRepository.getEntityById(entityType, id);
+        if (result.isEmpty()) {
+            throw TiesException.resourceNotFoundException();
+        }
+
+        return entityMapper.getItemsWithTotalCount(result).getLeft().get(0);
     }
 
     @Override
-    public OranTeivEntitiesResponseMessage getTopologyByType(final String entityName, final String target,
-            final String scope, final PaginationDTO paginationDTO) {
-        final Map<String, Object> response = dataPersistanceService.getTopologyByType(entityName, target, scope,
-                paginationDTO);
-        return getEntitiesResponseMessage(response);
+    public OranTeivEntitiesResponseMessage getTopologyByType(final String domain, final String entityName,
+            final String target, final String scope, final RequestDetails requestDetails) {
+        final FilterCriteria filterCriteria = FilterCriteria.builder(domain).filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(targetResolver.resolve(entityName, target)).scope(scopeResolver.resolve(entityName,
+                        scope)).build())).resolvingTopologyObjectType(FilterCriteria.ResolvingTopologyObjectType.ENTITY)
+                .build();
+        final Result<Record> result = dataRepository.getTopologyByFilterCriteria(filterCriteria, requestDetails.getLimit(),
+                requestDetails.getOffset());
+        return entityMapper.mapEntities(result, requestDetails);
     }
 
     @Override
     public OranTeivEntitiesResponseMessage getEntitiesByDomain(final String domain, final String fields,
-            final String filters, final PaginationDTO paginationDTO) {
-        final Map<String, Object> response = dataPersistanceService.getEntitiesByDomain(domain, fields, filters,
-                paginationDTO);
-        return getEntitiesResponseMessage(response);
+            final String filters, final RequestDetails requestDetails) {
+        final FilterCriteria filterCriteria = FilterCriteria.builder(domain).filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(targetResolver.resolve(null, fields)).scope(scopeResolver.resolve(null, filters))
+                .build())).resolvingTopologyObjectType(FilterCriteria.ResolvingTopologyObjectType.ENTITY).build();
+        final Result<Record> result = dataRepository.getTopologyByFilterCriteria(filterCriteria, requestDetails.getLimit(),
+                requestDetails.getOffset());
+        return entityMapper.mapEntities(result, requestDetails);
     }
 
     @Override
-    public OranTeivRelationshipsResponseMessage getAllRelationshipsForObjectId(final String entityName, final String id,
-            final PaginationDTO paginationDTO) {
-        final EntityType entityType = SchemaRegistry.getEntityTypeByName(entityName);
-        final List<RelationType> relationTypes = SchemaRegistry.getRelationTypesByEntityName(entityName);
-        final Map<String, Object> response = dataPersistanceService.getAllRelationships(entityType, relationTypes, id,
-                paginationDTO);
-        return getRelationshipsResponseMessage(response);
-    }
+    public OranTeivRelationshipsResponseMessage getAllRelationshipsForObjectId(final String domain, final String entityName,
+            final String id, final String target, final String scope, final RequestDetails requestDetails) {
 
-    @Override
-    public Map<String, Object> getRelationshipById(final String relationName, final String id) {
-        return dataPersistanceService.getRelationshipWithSpecifiedId(id, SchemaRegistry.getRelationTypeByName(
-                relationName));
+        final List<RelationType> relationNamesForEntityByDomain = SchemaRegistry.getRelationNamesForEntityByDomain(
+                entityName, domain);
+        final OranTeivRelationshipsResponseMessage response;
+        if (!relationNamesForEntityByDomain.isEmpty()) {
+            final FilterCriteria filterCriteria = FilterCriteria.builder(domain).filterCriteriaList(List.of(
+                    InnerFilterCriteria.builder().targets(targetResolver.resolve(null, target)).scope(scopeResolver.resolve(
+                            null, scope)).build())).resolvingTopologyObjectType(
+                                    FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP).build();
+
+            basePathRefinement.refine(filterCriteria);
+
+            List<InnerFilterCriteria> resolvedCriteriaList = new ArrayList<>();
+
+            relationNamesForEntityByDomain.forEach(relationType -> filterCriteria.getFilterCriteriaList().forEach(
+                    innerFilterCriteria -> {
+                        final String relationship = innerFilterCriteria.getTargets().get(0).getTopologyObject();
+                        if (relationship.equals(relationType.getName())) {
+                            if (relationType.isConnectsSameEntity()) {
+                                addLogicalBlockForLoopBackRelations(innerFilterCriteria, relationType.getASideAssociation()
+                                        .getName(), relationType.getBSideAssociation().getName(), id, resolvedCriteriaList);
+                            } else if (relationType.getASide().getName().equals(entityName)) {
+                                addAndLogicalBlockToFilter(innerFilterCriteria, relationType.getBSideAssociation()
+                                        .getName(), id, resolvedCriteriaList);
+                            } else if (relationType.getBSide().getName().equals(entityName)) {
+                                addAndLogicalBlockToFilter(innerFilterCriteria, relationType.getASideAssociation()
+                                        .getName(), id, resolvedCriteriaList);
+                            }
+                        }
+                    }));
+
+            final FilterCriteria build = FilterCriteria.builder(domain).resolvingTopologyObjectType(
+                    FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP).filterCriteriaList(resolvedCriteriaList)
+                    .build();
+
+            final Result<Record> result = dataRepository.getTopologyByFilterCriteria(build, requestDetails.getLimit(),
+                    requestDetails.getOffset());
+            response = relationshipMapper.mapRelationships(result, requestDetails);
+        } else {
+            final int totalCount = 0;
+            response = OranTeivRelationshipsResponseMessage.builder().items(List.of()).first(firstHref(requestDetails))
+                    .prev(prevHref(requestDetails, totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails,
+                            totalCount)).last(lastHref(requestDetails, totalCount)).totalCount(totalCount).build();
+        }
+
+        if (response.getItems().isEmpty()) {
+            getEntityById(entityName, id);
+        }
+        return response;
     }
 
     @Override
-    public OranTeivRelationshipsResponseMessage getRelationshipsByType(final String relationName, final String scopeFilter,
-            final PaginationDTO paginationDTO) {
-        final Map<String, Object> response = dataPersistanceService.getRelationshipsByType(SchemaRegistry
-                .getRelationTypeByName(relationName), scopeFilter, paginationDTO);
-        return getRelationshipsResponseMessage(response);
-    }
+    public Object getRelationshipById(final String relationName, final String id) {
+        final RelationType relationType = SchemaRegistry.getRelationTypeByName(relationName);
+        final Result<Record> result = dataRepository.getRelationshipById(id, relationType);
+        if (result.isEmpty()) {
+            throw TiesException.resourceNotFoundException();
+        }
 
-    private OranTeivEntitiesResponseMessage getEntitiesResponseMessage(Map<String, Object> response) {
-        OranTeivEntitiesResponseMessage result = new OranTeivEntitiesResponseMessage();
-        List<Object> items = (List<Object>) response.get("items");
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-        Integer totalCount = (Integer) response.get("totalCount");
-
-        result.setItems(items);
-
-        OranTeivHref selfHref = new OranTeivHref();
-        OranTeivHref firstHref = new OranTeivHref();
-        OranTeivHref prevHref = new OranTeivHref();
-        OranTeivHref nextHref = new OranTeivHref();
-        OranTeivHref lastHref = new OranTeivHref();
-
-        selfHref.setHref(self.getHref());
-        firstHref.setHref(first.getHref());
-        prevHref.setHref(prev.getHref());
-        nextHref.setHref(next.getHref());
-        lastHref.setHref(last.getHref());
-
-        result.setSelf(selfHref);
-        result.setFirst(firstHref);
-        result.setPrev(prevHref);
-        result.setNext(nextHref);
-        result.setLast(lastHref);
-        result.setTotalCount(totalCount);
-        return result;
+        return relationshipMapper.getItemsWithTotalCount(result).getLeft().get(0);
     }
 
-    private OranTeivRelationshipsResponseMessage getRelationshipsResponseMessage(Map<String, Object> response) {
-        OranTeivRelationshipsResponseMessage result = new OranTeivRelationshipsResponseMessage();
-        List<Object> items = (List<Object>) response.get("items");
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-        Integer totalCount = (Integer) response.get("totalCount");
-
-        result.setItems(items);
-
-        OranTeivHref selfHref = new OranTeivHref();
-        OranTeivHref firstHref = new OranTeivHref();
-        OranTeivHref prevHref = new OranTeivHref();
-        OranTeivHref nextHref = new OranTeivHref();
-        OranTeivHref lastHref = new OranTeivHref();
-
-        selfHref.setHref(self.getHref());
-        firstHref.setHref(first.getHref());
-        prevHref.setHref(prev.getHref());
-        nextHref.setHref(next.getHref());
-        lastHref.setHref(last.getHref());
-
-        result.setSelf(selfHref);
-        result.setFirst(firstHref);
-        result.setPrev(prevHref);
-        result.setNext(nextHref);
-        result.setLast(lastHref);
-        result.setTotalCount(totalCount);
-        return result;
+    @Override
+    public OranTeivRelationshipsResponseMessage getRelationshipsByType(final String domain, final String relationshipType,
+            final String targetFilter, final String scopeFilter, final RequestDetails requestDetails) {
+        final FilterCriteria filterCriteria = FilterCriteria.builder(domain).filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(targetResolver.resolve(relationshipType, targetFilter)).scope(scopeResolver.resolve(
+                        relationshipType, scopeFilter)).build())).resolvingTopologyObjectType(
+                                FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP).build();
+        final Result<Record> result = dataRepository.getTopologyByFilterCriteria(filterCriteria, requestDetails.getLimit(),
+                requestDetails.getOffset());
+        return relationshipMapper.mapRelationships(result, requestDetails);
     }
 
-    private OranTeivDomains getDomainsResponseMessage(Map<String, Object> response, List<OranTeivDomainsItemsInner> items,
-            final Integer limit, final Integer offset) {
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-
-        return OranTeivDomains.builder().items(items.subList(offset, Math.min(offset + limit, items.size()))).first(
-                OranTeivHref.builder().href(first.getHref()).build()).prev(OranTeivHref.builder().href(prev.getHref())
-                        .build()).self(OranTeivHref.builder().href(self.getHref()).build()).next(OranTeivHref.builder()
-                                .href(next.getHref()).build()).last(OranTeivHref.builder().href(last.getHref()).build())
-                .totalCount(items.size()).build();
+    // Helper method for adding AndLogicalBlock to FilterCriteria
+    private void addAndLogicalBlockToFilter(final InnerFilterCriteria innerFilterCriteria, final String associationName,
+            final String id, final List<InnerFilterCriteria> resolvedCriteriaList) {
+        AndLogicalBlock andLogicalBlock = createAndLogicalBlock(innerFilterCriteria, associationName, id);
+        innerFilterCriteria.setScope(andLogicalBlock);
+        resolvedCriteriaList.add(innerFilterCriteria);
     }
 
-    private OranTeivEntityTypes getEntityTypesResponseMessage(Map<String, Object> response,
-            List<OranTeivEntityTypesItemsInner> items, final Integer limit, final Integer offset) {
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-
-        return OranTeivEntityTypes.builder().items(items.subList(offset, Math.min(offset + limit, items.size()))).first(
-                OranTeivHref.builder().href(first.getHref()).build()).prev(OranTeivHref.builder().href(prev.getHref())
-                        .build()).self(OranTeivHref.builder().href(self.getHref()).build()).next(OranTeivHref.builder()
-                                .href(next.getHref()).build()).last(OranTeivHref.builder().href(last.getHref()).build())
-                .totalCount(items.size()).build();
+    // Helper method used to add LogicalBlock for Rel connecting same entity to FilterCriteria
+    private void addLogicalBlockForLoopBackRelations(final InnerFilterCriteria innerFilterCriteria,
+            final String aSideAssociationName, final String bSideAssociationName, final String id,
+            final List<InnerFilterCriteria> resolvedCriteriaList) {
+        OrLogicalBlock orLogicalBlock = new OrLogicalBlock();
+        orLogicalBlock.addChild(scopeResolver.resolve(null, "/" + aSideAssociationName + "[@id='" + id + "']"));
+        orLogicalBlock.addChild(scopeResolver.resolve(null, "/" + bSideAssociationName + "[@id='" + id + "']"));
+        AndLogicalBlock andLogicalBlock = new AndLogicalBlock();
+        andLogicalBlock.addChild(innerFilterCriteria.getScope());
+        andLogicalBlock.addChild(orLogicalBlock);
+        innerFilterCriteria.setScope(andLogicalBlock);
+        resolvedCriteriaList.add(innerFilterCriteria);
     }
 
-    private OranTeivRelationshipTypes getRelationshipTypesResponseMessage(Map<String, Object> response,
-            List<OranTeivRelationshipTypesItemsInner> items, final Integer limit, final Integer offset) {
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-
-        return OranTeivRelationshipTypes.builder().items(items.subList(offset, Math.min(offset + limit, items.size())))
-                .first(OranTeivHref.builder().href(first.getHref()).build()).prev(OranTeivHref.builder().href(prev
-                        .getHref()).build()).self(OranTeivHref.builder().href(self.getHref()).build()).next(OranTeivHref
-                                .builder().href(next.getHref()).build()).last(OranTeivHref.builder().href(last.getHref())
-                                        .build()).totalCount(items.size()).build();
+    // Helper method to create AndLogicalBlock
+    private AndLogicalBlock createAndLogicalBlock(final InnerFilterCriteria innerFilterCriteria,
+            final String associationName, final String id) {
+        AndLogicalBlock andLogicalBlock = new AndLogicalBlock();
+        andLogicalBlock.addChild(innerFilterCriteria.getScope());
+        andLogicalBlock.addChild(scopeResolver.resolve(null, "/" + associationName + "[@id='" + id + "']"));
+        return andLogicalBlock;
     }
 }
@@ -20,6 +20,8 @@
  */
 package org.oran.smo.teiv.exposure.data.rest.controller;
 
+import java.util.function.Supplier;
+
 import org.oran.smo.teiv.CustomMetrics;
 import org.oran.smo.teiv.api.EntitiesAndRelationshipsApi;
 import org.oran.smo.teiv.api.model.OranTeivDomains;
@@ -28,30 +30,29 @@ import org.oran.smo.teiv.api.model.OranTeivEntityTypes;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
 import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
 import org.oran.smo.teiv.exposure.data.api.DataService;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
 import org.oran.smo.teiv.exposure.utils.RequestValidator;
 import org.oran.smo.teiv.utils.TiesConstants;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 
 import io.micrometer.core.annotation.Timed;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.Max;
 import jakarta.validation.constraints.Min;
 import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.function.Supplier;
 
 @Slf4j
 @RestController
 @RequestMapping(TiesConstants.REQUEST_MAPPING)
 @RequiredArgsConstructor
-public class DataRestController implements EntitiesAndRelationshipsApi {
+public class DataController implements EntitiesAndRelationshipsApi {
+    public static final String SCOPE_FILTER = "scopeFilter";
+    public static final String TARGET_FILTER = "targetFilter";
 
     private final RequestValidator requestValidator;
     private final DataService dataService;
@@ -61,37 +62,19 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
     @Timed("ties_exposure_http_get_domain_types_seconds")
     public ResponseEntity<OranTeivDomains> getAllDomains(@NotNull String accept, @Min(0) @Valid final Integer offset,
             @Min(1) @Max(500) @Valid final Integer limit) {
-        return runWithFailCheck(() -> new ResponseEntity<>(dataService.getDomainTypes(PaginationDTO.builder().offset(offset)
-                .limit(limit).basePath("/domains").build()), HttpStatus.OK),
+        return runWithFailCheck(() -> new ResponseEntity<>(dataService.getDomainTypes(RequestDetails.builder().offset(
+                offset).limit(limit).basePath("/domains").build()), HttpStatus.OK),
                 customMetrics::incrementNumUnsuccessfullyExposedDomainTypes);
     }
 
-    @Override
-    @Timed("ties_exposure_http_get_relationships_by_type_seconds")
-    public ResponseEntity<OranTeivRelationshipsResponseMessage> getRelationshipsByType(@NotNull String accept,
-            String domain, String relationshipType, @Valid String targetFilter, @Valid String scopeFilter,
-            @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
-        return runWithFailCheck(() -> {
-            requestValidator.validateDomain(domain);
-            requestValidator.validateRelationshipType(relationshipType);
-            requestValidator.validateRelationshipTypeInDomain(relationshipType, domain);
-            requestValidator.validateFiltersForRelationships(targetFilter, scopeFilter);
-            return ResponseEntity.ok(dataService.getRelationshipsByType(relationshipType, scopeFilter, PaginationDTO
-                    .builder().offset(offset).limit(limit).addPathParameters("relationshipType", relationshipType).basePath(
-                            String.format("/domains/%s/relationship-types/%s/relationships", domain, relationshipType))
-                    .addPathParameters("domain", domain).addQueryParameters("scopeFilter", scopeFilter).build()));
-        }, customMetrics::incrementNumUnsuccessfullyExposedRelationshipsByType);
-    }
-
     @Override
     @Timed("ties_exposure_http_get_entity_types_seconds")
     public ResponseEntity<OranTeivEntityTypes> getTopologyEntityTypes(@NotNull String accept, String domain,
             @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
         return runWithFailCheck(() -> {
             requestValidator.validateDomain(domain);
-            return new ResponseEntity<>(dataService.getTopologyEntityTypes(domain, PaginationDTO.builder().offset(offset)
-                    .limit(limit).basePath(String.format("/domains/%s/entity-types", domain)).addPathParameters("domain",
-                            domain).build()), HttpStatus.OK);
+            return new ResponseEntity<>(dataService.getTopologyEntityTypes(domain, RequestDetails.builder().offset(offset)
+                    .limit(limit).basePath(String.format("/domains/%s/entity-types", domain)).build()), HttpStatus.OK);
         }, customMetrics::incrementNumUnsuccessfullyExposedEntityTypes);
     }
 
@@ -101,12 +84,28 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
             @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
         return runWithFailCheck(() -> {
             requestValidator.validateDomain(domain);
-            return new ResponseEntity<>(dataService.getTopologyRelationshipTypes(domain, PaginationDTO.builder().offset(
-                    offset).limit(limit).basePath(String.format("/domains/%s/relationship-types", domain))
-                    .addPathParameters("domain", domain).build()), HttpStatus.OK);
+            return new ResponseEntity<>(dataService.getTopologyRelationshipTypes(domain, RequestDetails.builder().offset(
+                    offset).limit(limit).basePath(String.format("/domains/%s/relationship-types", domain)).build()),
+                    HttpStatus.OK);
         }, customMetrics::incrementNumUnsuccessfullyExposedRelationshipTypes);
     }
 
+    @Override
+    @Timed("ties_exposure_http_get_relationships_by_type_seconds")
+    public ResponseEntity<OranTeivRelationshipsResponseMessage> getRelationshipsByType(@NotNull String accept,
+            String domain, String relationshipType, @Valid String targetFilter, @Valid String scopeFilter,
+            @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
+        return runWithFailCheck(() -> {
+            requestValidator.validateDomain(domain);
+            requestValidator.validateRelationshipType(relationshipType);
+            requestValidator.validateRelationshipTypeInDomain(relationshipType, domain);
+            return ResponseEntity.ok(dataService.getRelationshipsByType(domain, relationshipType, targetFilter, scopeFilter,
+                    RequestDetails.builder().offset(offset).limit(limit).basePath(String.format(
+                            "/domains/%s/relationship-types/%s/relationships", domain, relationshipType)).queryParam(
+                                    SCOPE_FILTER, scopeFilter).queryParam(TARGET_FILTER, targetFilter).build()));
+        }, customMetrics::incrementNumUnsuccessfullyExposedRelationshipsByType);
+    }
+
     @Override
     @Timed("ties_exposure_http_get_entity_by_id_seconds")
     public ResponseEntity<Object> getTopologyById(@NotNull final String accept, final String domain,
@@ -115,7 +114,7 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
             requestValidator.validateDomain(domain);
             requestValidator.validateEntityType(entityType);
             requestValidator.validateEntityTypeInDomain(entityType, domain);
-            return new ResponseEntity<>(dataService.getTopologyById(entityType, id), HttpStatus.OK);
+            return new ResponseEntity<>(dataService.getEntityById(entityType, id), HttpStatus.OK);
         }, customMetrics::incrementNumUnsuccessfullyExposedEntityById);
     }
 
@@ -128,10 +127,10 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
             requestValidator.validateDomain(domain);
             requestValidator.validateEntityType(entityType);
             requestValidator.validateEntityTypeInDomain(entityType, domain);
-            return ResponseEntity.ok(dataService.getTopologyByType(entityType, targetFilter, scopeFilter, PaginationDTO
-                    .builder().offset(offset).limit(limit).basePath(String.format("/domains/%s/entity-types/%s/entities",
-                            domain, entityType)).addPathParameters("domain", domain).addQueryParameters("targetFilter",
-                                    targetFilter).addQueryParameters("scopeFilter", scopeFilter).build()));
+            return ResponseEntity.ok(dataService.getTopologyByType(domain, entityType, targetFilter, scopeFilter,
+                    RequestDetails.builder().offset(offset).limit(limit).basePath(String.format(
+                            "/domains/%s/entity-types/%s/entities", domain, entityType)).queryParam(TARGET_FILTER,
+                                    targetFilter).queryParam(SCOPE_FILTER, scopeFilter).build()));
         }, customMetrics::incrementNumUnsuccessfullyExposedEntitiesByType);
     }
 
@@ -142,10 +141,9 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
             @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
         return runWithFailCheck(() -> {
             requestValidator.validateDomain(domain);
-            return ResponseEntity.ok(dataService.getEntitiesByDomain(domain, targetFilter, scopeFilter, PaginationDTO
-                    .builder().offset(offset).limit(limit).basePath("/domains/" + domain + "/entities").addPathParameters(
-                            "domain", domain).addQueryParameters("targetFilter", targetFilter).addQueryParameters(
-                                    "scopeFilter", scopeFilter).build()));
+            return ResponseEntity.ok(dataService.getEntitiesByDomain(domain, targetFilter, scopeFilter, RequestDetails
+                    .builder().offset(offset).limit(limit).basePath("/domains/" + domain + "/entities").queryParam(
+                            TARGET_FILTER, targetFilter).queryParam(SCOPE_FILTER, scopeFilter).build()));
         }, customMetrics::incrementNumUnsuccessfullyExposedEntitiesByDomain);
     }
 
@@ -159,11 +157,10 @@ public class DataRestController implements EntitiesAndRelationshipsApi {
             requestValidator.validateDomain(domain);
             requestValidator.validateEntityType(entityType);
             requestValidator.validateEntityTypeInDomain(entityType, domain);
-            return ResponseEntity.ok(dataService.getAllRelationshipsForObjectId(entityType, id, PaginationDTO.builder()
-                    .offset(offset).limit(limit).basePath(String.format(
-                            "/domains/%s/entity-types/%s/entities/%s/relationships", domain, entityType, id))
-                    .addPathParameters("domain", domain).addPathParameters("entityType", entityType).addPathParameters("id",
-                            id).build()));
+            return ResponseEntity.ok(dataService.getAllRelationshipsForObjectId(domain, entityType, id, targetFilter,
+                    scopeFilter, RequestDetails.builder().offset(offset).limit(limit).basePath(String.format(
+                            "/domains/%s/entity-types/%s/entities/%s/relationships", domain, entityType, id)).queryParam(
+                                    TARGET_FILTER, targetFilter).queryParam(SCOPE_FILTER, scopeFilter).build()));
         }, customMetrics::incrementNumUnsuccessfullyExposedAllRelationshipsByEntityId);
     }
 
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/DecoratorsService.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/DecoratorsService.java
new file mode 100644 (file)
index 0000000..f7347e5
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  ============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.teiv.exposure.decorators.api;
+
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+
+public interface DecoratorsService {
+    /**
+     * Updates the decorators of the specified entities and/or relationships
+     *
+     * @param oranTeivDecorator
+     *     holds information for updating classifiers
+     */
+    void update(OranTeivDecorator oranTeivDecorator);
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/impl/DecoratorsServiceImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/decorators/api/impl/DecoratorsServiceImpl.java
new file mode 100644 (file)
index 0000000..7f166c5
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ *  ============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.teiv.exposure.decorators.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataOperationRegistry;
+import org.oran.smo.teiv.exposure.consumerdata.model.Decorators;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DecoratorsOperation;
+import org.oran.smo.teiv.exposure.decorators.api.DecoratorsService;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.schema.ConsumerDataCache;
+import org.oran.smo.teiv.schema.YangDataTypes;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.function.Consumer;
+
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DecoratorsServiceImpl implements DecoratorsService {
+
+    private final ModelRepository modelRepository;
+    private final ConsumerDataCache consumerDataCache;
+    private final ConsumerDataOperationRegistry consumerDataOperationRegistry;
+
+    @Override
+    public void update(final OranTeivDecorator oranTeivDecorator) {
+
+        log.debug(String.format("Executing %s on decorators", oranTeivDecorator.getOperation()));
+
+        List<String> entityIds = oranTeivDecorator.getEntityIds();
+        if (entityIds == null) {
+            entityIds = Collections.emptyList();
+        }
+
+        List<String> relationshipIds = oranTeivDecorator.getRelationshipIds();
+        if (relationshipIds == null) {
+            relationshipIds = Collections.emptyList();
+        }
+
+        final Map<String, Object> decoratorNames = oranTeivDecorator.getDecorators();
+        Decorators decorators = Decorators.builder().data(decoratorNames).entityIds(entityIds).relationshipIds(
+                relationshipIds).build();
+
+        if (oranTeivDecorator.getOperation().equals(OranTeivDecorator.OperationEnum.MERGE)) {
+            runMethodSafe(this::validateMerge, decorators);
+        } else {
+            runMethodSafe(this::validateDelete, decorators);
+        }
+
+        final DecoratorsOperation operation = consumerDataOperationRegistry.getDecoratorsOperation(oranTeivDecorator
+                .getOperation());
+
+        List<OperationResult> results = operation.execute(decorators);
+    }
+
+    public void validateMerge(final Decorators decorators) {
+        log.debug(String.format("Validating merging %s", decorators));
+
+        final Map<String, String> problems = checkAvailability(decorators);
+
+        if (!problems.isEmpty()) {
+            throw TiesException.invalidDecoratorsException(problems);
+        }
+    }
+
+    public void validateDelete(final Decorators decorators) {
+        log.debug(String.format("Validating deleting %s", decorators));
+
+        for (String decorator : decorators.data().keySet()) {
+            final String schemaName = decorator.split(":")[0];
+            if (!modelRepository.doesModuleExists(TIES_CONSUMER_DATA, schemaName)) {
+                throw TiesException.invalidSchema(schemaName);
+            }
+        }
+    }
+
+    private Map<String, String> checkAvailability(final Decorators decorators) {
+        final Map<String, String> invalidKeys = new HashMap<>();
+
+        for (String key : decorators.data().keySet()) {
+            invalidKeys.put(key, "is_not_available");
+        }
+
+        decorators.data().forEach((key, value) -> {
+
+            if (consumerDataCache.getDecorators().containsKey(key)) {
+
+                final boolean isCompatible = checkCompatibility(key, value);
+
+                if (isCompatible) {
+                    invalidKeys.remove(key);
+                } else {
+                    invalidKeys.put(key, "is_not_compatible");
+                }
+            }
+        });
+
+        return invalidKeys;
+    }
+
+    private boolean checkCompatibility(final String key, final Object value) {
+        return consumerDataCache.getDecorators().get(key).equals(YangDataTypes.fromRequestDataType(value.getClass()));
+    }
+
+    private void runMethodSafe(Consumer<Decorators> consumer, Decorators classifiers) {
+        try {
+            consumer.accept(classifiers);
+        } catch (TiesException ex) {
+            log.error("Exception during validation", ex);
+            throw ex;
+        }
+    }
+}
index df158f5..3f49902 100644 (file)
  */
 package org.oran.smo.teiv.exposure.decorators.rest.controller;
 
+import java.util.Collections;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import jakarta.servlet.http.HttpServletRequest;
+
+import io.micrometer.core.annotation.Timed;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import org.oran.smo.teiv.CustomMetrics;
 import org.oran.smo.teiv.api.DecoratorsApi;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.audit.AuditMapper;
+import org.oran.smo.teiv.exposure.audit.LoggerHandler;
+import org.oran.smo.teiv.exposure.decorators.api.DecoratorsService;
 import org.oran.smo.teiv.utils.TiesConstants;
-
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+@Slf4j
 @RestController
 @RequestMapping(TiesConstants.REQUEST_MAPPING)
+@RequiredArgsConstructor
 public class DecoratorsRestController implements DecoratorsApi {
 
+    private final DecoratorsService decoratorsService;
+    private final CustomMetrics customMetrics;
+    private final LoggerHandler loggerHandler;
+    private final HttpServletRequest context;
+
+    @Value("${consumer-data.batch-size}")
+    private int limit;
+
+    @Override
+    @Timed("ties_exposure_http_update_decorators_seconds")
+    public ResponseEntity<Void> updateDecorator(final String accept, final String contentType,
+            final OranTeivDecorator oranTeivDecorator) {
+        return runWithFailCheck(() -> {
+            if (Optional.ofNullable(oranTeivDecorator.getEntityIds()).orElseGet(Collections::emptyList).size() + Optional
+                    .ofNullable(oranTeivDecorator.getRelationshipIds()).orElseGet(Collections::emptyList).size() > limit) {
+                throw TiesException.clientException("Limit exceeded",
+                        "Number of entities and relationships exceeded the limit");
+            }
+            runSafeMethod(() -> decoratorsService.update(oranTeivDecorator), status -> loggerHandler.logAudit(log,
+                    AuditMapper.fromDecoratorsRequest(oranTeivDecorator, status).toString(), context));
+
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        }, customMetrics::incrementNumUnsuccessfullyUpdatedDecorators);
+    }
+
+    private <T> T runWithFailCheck(final Supplier<T> supp, final Runnable runnable) {
+        try {
+            return supp.get();
+        } catch (Exception ex) {
+            log.error("Exception during service call", ex);
+            runnable.run();
+            throw ex;
+        }
+    }
+
+    protected void runSafeMethod(final Runnable runnable, final Consumer<HttpStatus> logAudit) {
+        try {
+            runnable.run();
+            logAudit.accept(HttpStatus.NO_CONTENT);
+        } catch (TiesException ex) {
+            logAudit.accept(ex.getStatus());
+            log.error("Exception during service call", ex);
+            throw ex;
+        }
+    }
 }
  */
 package org.oran.smo.teiv.exposure.model.api;
 
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
 import org.oran.smo.teiv.api.model.OranTeivSchemaList;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
 import org.springframework.web.multipart.MultipartFile;
 
-public interface ModelSchemaService {
+public interface ModelService {
 
     /**
-     * Create schema.
+     * Creates module from the yang file.
      *
      * @param yangFile
      *     the yang content
      */
-    void createSchema(final MultipartFile yangFile);
+    void createModule(final MultipartFile yangFile);
 
     /**
-     * Get all schemas extracted from yang models
-     *
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return a map of all schemas
-     */
-    OranTeivSchemaList getSchemas(final PaginationDTO paginationDTO);
-
-    /**
-     * Get all schemas in a domain
+     * Gets all modules in a domain
      *
      * @param domain
      *     domain name
      * @param paginationDTO
      *     pagination data
-     *
      * @return a map of all schemas in a domain
      */
-    OranTeivSchemaList getSchemasInDomain(final String domain, final PaginationDTO paginationDTO);
+    OranTeivSchemaList getModulesByDomain(final String domain, final RequestDetails paginationDTO);
 
     /**
-     * Get a yang schema name
+     * Gets module content
      *
-     * @param schema
-     *     schema name
-     *
-     * @return a schema in a string format
+     * @param name
+     *     name name
+     * @return the content
      */
-    String getSchemaByName(final String schema);
+    String getModuleContentByName(final String name);
 
     /**
-     * Delete schema.
+     * Deletes module.
      *
      * @param name
      *     the schema name
      */
-    void deleteSchema(final String name);
+    void deleteConsumerModule(final String name);
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelSchemaServiceImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelSchemaServiceImpl.java
deleted file mode 100644 (file)
index b43a85f..0000000
+++ /dev/null
@@ -1,117 +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 org.oran.smo.teiv.exposure.model.api.impl;
-
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.api.model.OranTeivSchema;
-import org.oran.smo.teiv.api.model.OranTeivSchemaList;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.impl.StoredSchema;
-import org.oran.smo.teiv.exposure.spi.mapper.PageMetaData;
-import org.oran.smo.teiv.exposure.model.api.ModelSchemaService;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.*;
-
-import static org.oran.smo.teiv.utils.TiesConstants.IN_USAGE;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class ModelSchemaServiceImpl implements ModelSchemaService {
-
-    private final DataPersistanceService dataPersistanceService;
-
-    @Override
-    public void createSchema(MultipartFile yangFile) {
-        log.trace("yang file: {}", yangFile);
-    }
-
-    @Override
-    public OranTeivSchemaList getSchemas(final PaginationDTO paginationDTO) {
-        return getSchemaListResponseMessage(dataPersistanceService.getSchemas(paginationDTO));
-    }
-
-    @Override
-    public OranTeivSchemaList getSchemasInDomain(final String domainName, final PaginationDTO paginationDTO) {
-        return getSchemaListResponseMessage(dataPersistanceService.getSchemas(domainName, paginationDTO));
-    }
-
-    @Override
-    public String getSchemaByName(final String schemaName) {
-        final StoredSchema schema = dataPersistanceService.getSchema(schemaName);
-        if (schema == null || !schema.getStatus().equals(IN_USAGE)) {
-            throw TiesException.invalidSchema(schemaName);
-        }
-        return schema.getContent();
-    }
-
-    @Override
-    public void deleteSchema(String name) {
-        final StoredSchema schema = dataPersistanceService.getSchema(name);
-        if (schema == null) {
-            throw TiesException.invalidSchema(name);
-        }
-        if (schema.getOwnerAppId().equals("BUILT_IN_MODULE")) {
-            throw TiesException.schemaNotOwned(name);
-        }
-        dataPersistanceService.setSchemaToDeleting(name);
-    }
-
-    private OranTeivSchemaList getSchemaListResponseMessage(Map<String, Object> response) {
-        OranTeivSchemaList result = new OranTeivSchemaList();
-        List<OranTeivSchema> items = (List<OranTeivSchema>) response.get("items");
-        PageMetaData self = (PageMetaData) response.get("self");
-        PageMetaData first = (PageMetaData) response.get("first");
-        PageMetaData prev = (PageMetaData) response.get("prev");
-        PageMetaData next = (PageMetaData) response.get("next");
-        PageMetaData last = (PageMetaData) response.get("last");
-        Integer totalCount = (Integer) response.get("totalCount");
-
-        result.setItems(items);
-
-        OranTeivHref selfHref = new OranTeivHref();
-        OranTeivHref firstHref = new OranTeivHref();
-        OranTeivHref prevHref = new OranTeivHref();
-        OranTeivHref nextHref = new OranTeivHref();
-        OranTeivHref lastHref = new OranTeivHref();
-
-        selfHref.setHref(self.getHref());
-        firstHref.setHref(first.getHref());
-        prevHref.setHref(prev.getHref());
-        nextHref.setHref(next.getHref());
-        lastHref.setHref(last.getHref());
-
-        result.setSelf(selfHref);
-        result.setFirst(firstHref);
-        result.setPrev(prevHref);
-        result.setNext(nextHref);
-        result.setLast(lastHref);
-        result.setTotalCount(totalCount);
-        return result;
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelServiceImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/model/api/impl/ModelServiceImpl.java
new file mode 100644 (file)
index 0000000..2deee52
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ *  ============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.teiv.exposure.model.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.api.model.OranTeivHref;
+import org.oran.smo.teiv.api.model.OranTeivSchema;
+import org.oran.smo.teiv.api.model.OranTeivSchemaList;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exception.YangModelException;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataRepository;
+import org.oran.smo.teiv.exposure.model.api.ModelService;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.exposure.spi.Module;
+import org.oran.smo.teiv.exposure.spi.ModuleStatus;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.oran.smo.teiv.schema.ConsumerDataCache;
+import org.oran.smo.teiv.service.SchemaCleanUpService;
+import org.oran.smo.teiv.utils.YangParser;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.firstHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.getViableLimit;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.lastHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.nextHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.prevHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.selfHref;
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
+import static org.oran.smo.teiv.utils.TiesConstants.DECORATORS;
+import static org.oran.smo.teiv.utils.TiesConstants.INVALID_SCHEMA;
+import static org.oran.smo.teiv.utils.TiesConstants.SCHEMA_ALREADY_EXISTS;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_MODEL;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ModelServiceImpl implements ModelService {
+    private static final String CONTENT_HREF = "%s/%s/content";
+
+    private final ModelRepository modelRepository;
+    private final YangParser yangParser;
+    private final ConsumerDataRepository consumerDataRepository;
+    private final ConsumerDataCache consumerDataCaches;
+    private final SchemaCleanUpService schemaCleanUpService;
+
+    @Override
+    public void createModule(final MultipartFile yangFile) {
+        log.debug("Create module with file: {}", yangFile);
+        final Map<String, Object> result;
+        final String content;
+
+        try {
+            result = yangParser.validateSchemasYang(yangFile);
+            content = Base64.getEncoder().encodeToString(yangFile.getBytes());
+        } catch (IOException | YangModelException e) {
+            log.warn(INVALID_SCHEMA, e);
+            throw TiesException.invalidFileInput(INVALID_SCHEMA);
+        }
+
+        String moduleName = (String) result.get("moduleName");
+        String revision = (String) result.get("revision");
+        List<String> classifiers = (List<String>) result.get(CLASSIFIERS);
+        Map<String, String> decorators = (Map<String, String>) result.get(DECORATORS);
+
+        if (modelRepository.doesModuleExists(TIES_MODEL, moduleName) || modelRepository.doesModuleExists(TIES_CONSUMER_DATA,
+                moduleName)) {
+            throw TiesException.invalidFileInput(SCHEMA_ALREADY_EXISTS);
+        }
+
+        if (classifiers.isEmpty() && decorators.isEmpty()) {
+            throw TiesException.invalidFileInput(INVALID_SCHEMA);
+        }
+
+        modelRepository.createModule(Module.builder().name(moduleName).content(content).revision(revision).ownerAppId("APP")
+                .status(ModuleStatus.IN_USAGE).build());
+
+        if (!classifiers.isEmpty()) {
+            consumerDataRepository.storeClassifiers(classifiers, moduleName);
+        }
+
+        if (!decorators.isEmpty()) {
+            consumerDataRepository.storeDecorators(decorators, moduleName);
+        }
+
+        consumerDataCaches.emptyConsumerDataCaches();
+
+    }
+
+    @Override
+    public OranTeivSchemaList getModulesByDomain(final String domain, final RequestDetails requestDetails) {
+        log.debug("Get modules with domain : {}", domain);
+        final List<Module> modulesByDomain = modelRepository.getModules().stream().filter(s -> (domain == null) || (s
+                .getDomain() != null && s.getDomain().matches(domain))).toList();
+        int totalCount = modulesByDomain.size();
+
+        final List<OranTeivSchema> items = modulesByDomain.stream().skip(requestDetails.getOffset()).limit(getViableLimit(
+                requestDetails.getOffset(), requestDetails.getLimit(), totalCount)).map(module -> OranTeivSchema.builder()
+                        .name(module.getName()).domain(module.getDomain() == null ? "" : module.getDomain()).revision(module
+                                .getRevision()).content(OranTeivHref.builder().href(String.format(CONTENT_HREF,
+                                        requestDetails.getBasePath(), module.getName())).build()).build()).toList();
+
+        return OranTeivSchemaList.builder().items(items).first(firstHref(requestDetails)).prev(prevHref(requestDetails,
+                totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails, totalCount)).last(lastHref(
+                        requestDetails, totalCount)).totalCount(totalCount).build();
+    }
+
+    @Override
+    public String getModuleContentByName(final String name) {
+        log.debug("Get {} module content", name);
+        return Optional.ofNullable(modelRepository.getModuleContentByName(name)).map(content -> new String(Base64
+                .getDecoder().decode(content), StandardCharsets.UTF_8)).orElseGet(() -> {
+                    log.warn("No schema found with name: {}", name);
+                    throw TiesException.invalidSchema(name);
+                });
+    }
+
+    @Override
+    public void deleteConsumerModule(final String name) {
+        log.debug("Delete module: {}", name);
+        modelRepository.getConsumerModuleByName(name).ifPresentOrElse(module -> {
+            modelRepository.updateModuleStatus(name, ModuleStatus.DELETING);
+            schemaCleanUpService.cleanUpModule(name);
+        }, () -> {
+            log.warn("No module found with name: {}", name);
+            throw TiesException.invalidSchema(name);
+        });
+    }
+
+}
  */
 package org.oran.smo.teiv.exposure.model.rest.controller;
 
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
 import org.oran.smo.teiv.api.SchemasApi;
 import org.oran.smo.teiv.api.model.OranTeivSchemaList;
-import org.oran.smo.teiv.exposure.model.api.ModelSchemaService;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.audit.LoggerHandler;
+import org.oran.smo.teiv.exposure.model.api.ModelService;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.oran.smo.teiv.exposure.utils.RequestValidator;
 import org.oran.smo.teiv.utils.TiesConstants;
-
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
-import jakarta.validation.constraints.NotNull;
-import java.util.Objects;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.Max;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotNull;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 @RestController
 @RequestMapping(TiesConstants.REQUEST_MAPPING)
 @RequiredArgsConstructor
-public class ModelSchemaRestController implements SchemasApi {
+public class ModelController implements SchemasApi {
 
-    private final ModelSchemaService modelSchemaService;
+    private final ModelService modelService;
+    private final RequestValidator requestValidator;
+    private final Logger logger = LoggerFactory.getLogger(ModelController.class);
+    private final LoggerHandler loggerHandler;
+    private final HttpServletRequest context;
 
     @Override
     public ResponseEntity<Void> createSchema(String accept, String contentType, MultipartFile file) {
-        modelSchemaService.createSchema(file);
-        return new ResponseEntity<>(HttpStatus.OK);
+        requestValidator.validateYangFile(file);
+        runSafeMethod(() -> modelService.createModule(file), "create");
+        return new ResponseEntity<>(HttpStatus.CREATED);
     }
 
-    /**
-     * Return a list of all schemas/schemas filtered by domain extracted from yang models
-     */
     @Override
     public ResponseEntity<OranTeivSchemaList> getSchemas(@NotNull final String accept, @Valid final String domain,
             @Min(0) @Valid final Integer offset, @Min(1) @Max(500) @Valid final Integer limit) {
-        final PaginationDTO.PaginationDTOBuilder builder = PaginationDTO.builder().offset(offset).limit(limit);
-        if (Objects.isNull(domain)) {
-            return new ResponseEntity<>(modelSchemaService.getSchemas(builder.basePath("/schemas").build()), HttpStatus.OK);
-        } else {
-            return new ResponseEntity<>(modelSchemaService.getSchemasInDomain(domain, builder.basePath("/schemas")
-                    .addPathParameters("domain", domain).build()), HttpStatus.OK);
+        final RequestDetails.RequestDetailsBuilder builder = RequestDetails.builder().basePath("/schemas").offset(offset)
+                .limit(limit);
+        if (!Objects.isNull(domain)) {
+            builder.queryParam("domain", domain);
         }
+
+        return new ResponseEntity<>(modelService.getModulesByDomain(domain, builder.build()), HttpStatus.OK);
     }
 
-    /**
-     * Return a schema by schema name
-     */
     @Override
     @SneakyThrows
     public ResponseEntity<String> getSchemaByName(@NotNull final String accept, final String schemaName) {
-        final String module = modelSchemaService.getSchemaByName(schemaName);
+        final String module = modelService.getModuleContentByName(schemaName);
         return new ResponseEntity<>(module, HttpStatus.OK);
     }
 
     @Override
     public ResponseEntity<Void> deleteSchema(String accept, String schemaName) {
-        modelSchemaService.deleteSchema(schemaName);
-        return new ResponseEntity<>(HttpStatus.OK);
+        runSafeMethod(() -> modelService.deleteConsumerModule(schemaName), "delete");
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
+
+    protected void runSafeMethod(final Runnable runnable, String operation) {
+        try {
+            runnable.run();
+            loggerHandler.logAudit(logger, String.format("%s schema (successful)", StringUtils.capitalize(operation)),
+                    context);
+        } catch (TiesException ex) {
+            loggerHandler.logAudit(logger, String.format("%s schema (failed)", StringUtils.capitalize(operation)), context);
+            log.error("Exception during service call", ex);
+            throw ex;
+        }
+    }
+
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataPersistanceService.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataPersistanceService.java
deleted file mode 100644 (file)
index df347dd..0000000
+++ /dev/null
@@ -1,197 +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 org.oran.smo.teiv.exposure.spi;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.oran.smo.teiv.exposure.spi.impl.StoredSchema;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.DataType;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.RelationType;
-
-public interface DataPersistanceService {
-    /**
-     * Gets topology.
-     *
-     * @param entityType
-     *     the entityType
-     * @param id
-     *     the id
-     *
-     * @return the topology
-     */
-    Map<String, Object> getTopology(EntityType entityType, String id);
-
-    /**
-     * Gets topology by type.
-     *
-     * @param entityName
-     *     type of entity, e.g. NrCellDU
-     * @param targetFilter
-     *     specifies the entity type and attributes to be returned in the REST response
-     * @param scopeFilter
-     *     specifies the attributes to match on
-     * @param relationshipsFilter
-     *     specifies the relationships to match on
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return the all entities of type that match the filter criteria
-     */
-    Map<String, Object> getTopologyByType(final String entityName, final String targetFilter, final String scopeFilter,
-            final PaginationDTO paginationDTO);
-
-    /**
-     * Gets all relationships for objectType with specified id.
-     *
-     * @param entityType
-     *     the entity type
-     * @param relationTypes
-     *     the relation type
-     * @param id
-     *     the id
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return the all relationships
-     */
-    Map<String, Object> getAllRelationships(final EntityType entityType, final List<RelationType> relationTypes,
-            final String id, final PaginationDTO paginationDTO);
-
-    /**
-     * Gets relationship by id
-     *
-     * @param id
-     *     the relationType id
-     * @param relationType
-     *     the relationType
-     *
-     * @return relationship
-     */
-    Map<String, Object> getRelationshipWithSpecifiedId(final String id, final RelationType relationType);
-
-    /**
-     * Gets relationships for given edge.
-     *
-     * @param relationType
-     *     represents the actual relationship type
-     * @param scopeFilter
-     *     for filtering
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return filtered relationships by given relationship type
-     */
-    Map<String, Object> getRelationshipsByType(final RelationType relationType, final String scopeFilter,
-            final PaginationDTO paginationDTO);
-
-    /**
-     * Get topology entities by domain, using specified targetFilter as mandatory query parameter
-     *
-     * @param domain
-     *     specifies the domain
-     * @param targetFilter
-     *     specifies the entity type and attributes to be returned in the REST response
-     * @param scopeFilter
-     *     specifies the attributes to match on
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return the all entities of type that match the filter criteria
-     */
-    Map<String, Object> getEntitiesByDomain(final String domain, final String targetFilter, final String scopeFilter,
-            final PaginationDTO paginationDTO);
-
-    /**
-     * Load classifiers set.
-     *
-     * @return the classifiers
-     */
-    Set<String> loadClassifiers();
-
-    /**
-     * Load decorators map.
-     *
-     * @return the decorators
-     */
-    Map<String, DataType> loadDecorators();
-
-    /**
-     * Gets schemas.
-     *
-     * @param paginationDTO
-     *     the pagination dto
-     * @return the schemas
-     */
-    Map<String, Object> getSchemas(final PaginationDTO paginationDTO);
-
-    /**
-     * Gets schemas.
-     *
-     * @param domain
-     *     the domain
-     * @param paginationDTO
-     *     the pagination dto
-     * @return the schemas
-     */
-    Map<String, Object> getSchemas(final String domain, final PaginationDTO paginationDTO);
-
-    /**
-     * Gets schema.
-     *
-     * @param name
-     *     the name
-     * @return the schema
-     */
-    StoredSchema getSchema(final String name);
-
-    /**
-     * Post schema.
-     *
-     * @param name
-     *     the name
-     * @param namespace
-     *     the namespace
-     * @param domain
-     *     the domain
-     * @param includedModules
-     *     the included modules
-     * @param content
-     *     the content
-     * @param ownerAppId
-     *     the owner App id
-     */
-    void postSchema(final String name, final String namespace, final String domain, final List<String> includedModules,
-            final String content, final String ownerAppId);
-
-    /**
-     * Sets schema to deleting.
-     */
-    void setSchemaToDeleting(final String name);
-
-    /**
-     * Delete schema.
-     */
-    void deleteSchema(final String name);
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataRepository.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/DataRepository.java
new file mode 100644 (file)
index 0000000..ab15d24
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *  ============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.teiv.exposure.spi;
+
+import java.util.List;
+import java.util.Set;
+
+import org.jooq.Record;
+import org.jooq.Result;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+
+public interface DataRepository {
+    /**
+     * Gets topology.
+     *
+     * @param entityType
+     *     the entityType
+     * @param id
+     *     the id
+     * @return the topology
+     */
+    Result<Record> getEntityById(final EntityType entityType, final String id);
+
+    /**
+     * Gets relationship by id
+     *
+     * @param id
+     *     the relationType id
+     * @param relationType
+     *     the relationType
+     * @return relationship
+     */
+    Result<Record> getRelationshipById(final String id, final RelationType relationType);
+
+    /**
+     * Get topology objects by a filter criteria
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     * @param limit
+     *     the limit
+     * @param offset
+     *     the offset
+     *
+     * @return the all topology objects of type that match the filter criteria
+     */
+    Result<Record> getTopologyByFilterCriteria(final FilterCriteria filterCriteria, final int limit, final int offset);
+
+    /**
+     * Gets classifiers for schema.
+     *
+     * @param schemaName
+     *     the schema name
+     * @return the classifiers for schema
+     */
+    Set<String> getClassifiersForSchema(final String schemaName);
+
+    /**
+     * Gets decorators for schema.
+     *
+     * @param schemaName
+     *     the schema name
+     * @return the decorators for schema
+     */
+    Set<String> getDecoratorsForSchema(final String schemaName);
+
+    /**
+     * Gets relationship ids for decorator deletion.
+     *
+     * @param relationType
+     *     the relation type
+     * @param decorators
+     *     the decorators
+     * @return the relationship ids for decorator deletion
+     */
+    List<String> getRelationshipIdsForDecoratorDeletion(final RelationType relationType, final Set<String> decorators);
+
+    /**
+     * Gets relationship ids for classifier deletion.
+     *
+     * @param relationType
+     *     the relation type
+     * @param classifiers
+     *     the classifiers
+     * @return the relationship ids for classifier deletion
+     */
+    List<String> getRelationshipIdsForClassifierDeletion(final RelationType relationType, final Set<String> classifiers);
+
+    /**
+     * Gets entity ids for decorator deletion.
+     *
+     * @param entityType
+     *     the entity type
+     * @param decorators
+     *     the decorators
+     * @return the entity ids for decorator deletion
+     */
+    List<String> getEntityIdsForDecoratorDeletion(final EntityType entityType, final Set<String> decorators);
+
+    /**
+     * Gets entity ids for classifier deletion.
+     *
+     * @param entityType
+     *     the entity type
+     * @param classifiers
+     *     the classifiers
+     * @return the entity ids for classifier deletion
+     */
+    List<String> getEntityIdsForClassifierDeletion(final EntityType entityType, final Set<String> classifiers);
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModelRepository.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModelRepository.java
new file mode 100644 (file)
index 0000000..320f29e
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  ============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.teiv.exposure.spi;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Handles database operations for {@link Module}
+ */
+public interface ModelRepository {
+
+    /**
+     * Checks whether the given module exists in the given schema.
+     *
+     * @param schemaName
+     *     - schemaName name
+     * @param name
+     *     - module name
+     * @return true if module exists
+     */
+
+    boolean doesModuleExists(final String schemaName, final String name);
+
+    /**
+     * Gets module by name.
+     *
+     * @param name
+     *     - the name
+     * @return the module
+     */
+    Optional<Module> getConsumerModuleByName(final String name);
+
+    /**
+     * Gets modules.
+     *
+     * @return the modules
+     */
+    List<Module> getModules();
+
+    /**
+     * Gets module that were in the process of being deleted prior to pod restart.
+     *
+     * @return the module
+     */
+    List<Module> getDeletingModulesOnStartup();
+
+    /**
+     * Gets module content by name.
+     *
+     * @param name
+     *     the name
+     * @return the schema
+     */
+    String getModuleContentByName(final String name);
+
+    /**
+     * Creates module.
+     *
+     * @param module
+     *     - module to create
+     */
+    void createModule(Module module);
+
+    /**
+     * Updates module status.
+     *
+     * @param name
+     *     - name of the module
+     * @param status
+     *     - status to update
+     */
+    void updateModuleStatus(final String name, final ModuleStatus status);
+
+    /**
+     * Deletes a module.
+     *
+     * @param name
+     *     - name of the module
+     */
+    void deleteModuleByName(final String name);
+
+}
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.schema;
+package org.oran.smo.teiv.exposure.spi;
 
 import java.util.List;
 
 import lombok.Builder;
-import lombok.Getter;
 import lombok.Singular;
-import lombok.ToString;
+import lombok.Value;
 
-@Getter
+@Value
 @Builder
-@ToString
 public class Module {
-    private final String name;
-    private final String namespace;
-    private final String domain;
-
+    String name;
+    String namespace;
+    String domain;
     @Singular
-    private final List<String> includedModuleNames;
+    List<String> includedModuleNames;
+    String revision;
+    String content;
+    String ownerAppId;
+    ModuleStatus status;
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModuleStatus.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/ModuleStatus.java
new file mode 100644 (file)
index 0000000..c9d6d10
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  ============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.teiv.exposure.spi;
+
+/**
+ * Status of the {@link Module}
+ */
+public enum ModuleStatus {
+    IN_USAGE,
+    DELETING
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistanceServiceImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistanceServiceImpl.java
deleted file mode 100644 (file)
index 1ee5811..0000000
+++ /dev/null
@@ -1,289 +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 org.oran.smo.teiv.exposure.spi.impl;
-
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
-import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
-import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_MODEL;
-import static org.jooq.impl.DSL.exists;
-import static org.jooq.impl.DSL.field;
-import static org.jooq.impl.DSL.select;
-import static org.jooq.impl.DSL.table;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Supplier;
-
-import org.oran.smo.teiv.schema.DataType;
-import org.oran.smo.teiv.utils.TiesConstants;
-import org.jooq.DSLContext;
-import org.jooq.JSONB;
-import org.jooq.Record;
-import org.jooq.Record1;
-import org.jooq.Result;
-import org.jooq.ResultQuery;
-import org.jooq.tools.json.JSONArray;
-import org.jooq.SelectConditionStep;
-import org.springframework.stereotype.Service;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.RelationMappedRecordsDTO;
-import org.oran.smo.teiv.exposure.spi.mapper.MapperUtility;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.utils.query.QueryMonad;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class DataPersistanceServiceImpl implements DataPersistanceService {
-
-    private final DSLContext readDataDslContext;
-    private final DSLContext writeDataDslContext;
-    private final MapperUtility mapperUtility;
-
-    @Override
-    public Map<String, Object> getTopology(final EntityType entityType, final String eiId) {
-        return runMethodSafe(() -> {
-            final Result<Record> result = readDataDslContext.select(entityType.getAllFieldsWithId()).from(entityType
-                    .getTableName()).where(field(ID_COLUMN_NAME).eq(eiId)).fetch();
-            if (result.isEmpty()) {
-                throw TiesException.resourceNotFoundException();
-            }
-            return mapperUtility.mapEntity(entityType, result);
-        });
-    }
-
-    @Override
-    public Map<String, Object> getTopologyByType(final String entityType, final String target, final String scope,
-            final PaginationDTO paginationDTO) {
-        final QueryMonad queryMonad = QueryMonad.builder().managedObject(entityType).targets(target).scope(scope).build();
-        final ResultQuery<Record1<Integer>> queryCount = queryMonad.countWithSchema().apply(readDataDslContext);
-        paginationDTO.setTotalSize(runMethodSafe(() -> (int) queryCount.fetch().get(0).getValue(0)));
-        final ResultQuery<Record> query = queryMonad.withSchema(paginationDTO).apply(readDataDslContext);
-        log.trace("SQL ::  " + query.getSQL());
-        return runMethodSafe(() -> mapperUtility.mapComplexQuery(query.fetch(), paginationDTO));
-    }
-
-    @Override
-    public Map<String, Object> getAllRelationships(final EntityType entityType, final List<RelationType> relationTypes,
-            final String id, final PaginationDTO paginationDTO) {
-        List<RelationMappedRecordsDTO> relationMappedRecordsDTOS = new ArrayList<>();
-        int resultSize = 0;
-
-        for (RelationType relationType : relationTypes) {
-            String columnNameToFindBy;
-            String columnNameToCheckIfNull;
-
-            if (relationType.getASide().equals(entityType)) {
-                columnNameToFindBy = relationType.aSideColumnName();
-                columnNameToCheckIfNull = relationType.bSideColumnName();
-            } else {
-                columnNameToFindBy = relationType.bSideColumnName();
-                columnNameToCheckIfNull = relationType.aSideColumnName();
-            }
-
-            Result<Record> result = runMethodSafe(() -> readDataDslContext.select(relationType.getBaseFieldsWithId()).from(
-                    table(relationType.getTableName())).where(field(String.format(QUOTED_STRING, columnNameToFindBy)).eq(id)
-                            .and(field(String.format(QUOTED_STRING, columnNameToCheckIfNull)).isNotNull())).fetch());
-
-            if (result.isNotEmpty()) {
-                result.forEach(record -> relationMappedRecordsDTOS.add(RelationMappedRecordsDTO.builder().relationType(
-                        relationType).record(record).build()));
-                resultSize += result.size();
-            } else if (!checkIfEntityWithIdExists(entityType, id)) {
-                throw TiesException.resourceNotFoundException();
-
-            }
-
-        }
-
-        paginationDTO.setTotalSize(resultSize);
-        return mapperUtility.wrapRelationships(relationMappedRecordsDTOS, relationTypes, readDataDslContext, paginationDTO);
-    }
-
-    @Override
-    public Map<String, Object> getRelationshipWithSpecifiedId(final String id, final RelationType relationType) {
-        return runMethodSafe(() -> {
-            final Result<Record> result = readDataDslContext.select(relationType.getAllFieldsWithId()).from(table(
-                    relationType.getTableName())).where(field(String.format(QUOTED_STRING, relationType.getIdColumnName()))
-                            .eq(id)).fetch();
-            if (result.isEmpty()) {
-                throw TiesException.resourceNotFoundException();
-            }
-            return mapperUtility.mapRelationship(result, relationType);
-        });
-    }
-
-    @Override
-    public Map<String, Object> getRelationshipsByType(final RelationType relationType, final String scopeFilter,
-            final PaginationDTO paginationDTO) {
-        return runMethodSafe(() -> {
-            String attribute1;
-            String attribute2;
-            if (!relationType.getRelationshipStorageLocation().equals(RELATION)) {
-                attribute1 = relationType.getIdColumnName();
-                attribute2 = relationType.aSideColumnName().equals("id") ?
-                        relationType.bSideColumnName() :
-                        relationType.aSideColumnName();
-            } else {
-                attribute1 = relationType.aSideColumnName();
-                attribute2 = relationType.bSideColumnName();
-            }
-            final QueryMonad queryMonad = QueryMonad.builder().managedObject(relationType.getTableNameWithoutSchema())
-                    .targets(String.format("/id;/attributes(%s,%s)", getModelledName(attribute1), getModelledName(
-                            attribute2))).scope(scopeFilter).relationships(relationType.getName()).build();
-            final ResultQuery<Record1<Integer>> queryCount = queryMonad.countWithSchema().apply(readDataDslContext);
-            paginationDTO.setTotalSize(runMethodSafe(() -> (int) queryCount.fetch().get(0).getValue(0)));
-            final ResultQuery<Record> query = queryMonad.withSchema(paginationDTO).apply(readDataDslContext);
-            log.trace("SQL ::  " + query.getSQL());
-            return mapperUtility.wrapMapObject(mapperUtility.mapRelationships(query.fetch(), relationType), paginationDTO);
-        });
-    }
-
-    @Override
-    public Map<String, Object> getEntitiesByDomain(final String domain, final String targetFilter, final String scopeFilter,
-            final PaginationDTO paginationDTO) {
-        final QueryMonad queryMonad = QueryMonad.builder().managedObject(null).targets(targetFilter).scope(scopeFilter)
-                .domain(domain).build();
-        final ResultQuery<Record> query = queryMonad.withSchema(paginationDTO).apply(readDataDslContext);
-        final ResultQuery<Record1<Integer>> queryCount = queryMonad.countWithSchema().apply(readDataDslContext);
-        paginationDTO.setTotalSize(runMethodSafe(() -> (int) queryCount.fetch().get(0).getValue(0)));
-        log.trace("SQL ::  " + query.getSQL());
-        return runMethodSafe(() -> mapperUtility.mapComplexQuery(query.fetch(), paginationDTO));
-    }
-
-    @Override
-    public Set<String> loadClassifiers() {
-        SelectConditionStep<Record> availableClassifiers = runMethodSafe(() -> readDataDslContext.select().from(String
-                .format(TIES_MODEL, "classifiers")).join(String.format(TIES_MODEL, "module_reference")).on(field(
-                        "\"moduleReferenceName\"").eq(field(String.format(TIES_MODEL, "module_reference") + ".name")))
-                .where(field("status").like(TiesConstants.IN_USAGE)));
-        Set<String> result = new HashSet<>();
-        for (Record record : availableClassifiers) {
-            result.add((String) record.get("name"));
-        }
-        return result;
-    }
-
-    @Override
-    public Map<String, DataType> loadDecorators() {
-        SelectConditionStep<Record> availableDecorators = runMethodSafe(() -> readDataDslContext.select().from(String
-                .format(TIES_MODEL, "decorators")).join(String.format(TIES_MODEL, "module_reference")).on(field(
-                        "\"moduleReferenceName\"").eq(field(String.format(TIES_MODEL, "module_reference") + ".name")))
-                .where(field("status").like(TiesConstants.IN_USAGE)));
-        Map<String, DataType> result = new HashMap<>();
-        for (Record record : availableDecorators) {
-            result.put((String) record.get("name"), DataType.fromDbDataType("" + record.get("dataType")));
-        }
-        return result;
-    }
-
-    @Override
-    public Map<String, Object> getSchemas(PaginationDTO paginationDTO) {
-        final List<StoredSchema> schemas = runMethodSafe(() -> readDataDslContext.select().from(table(String.format(
-                TIES_MODEL, "module_reference"))).where(field("status").eq(TiesConstants.IN_USAGE)).fetchInto(
-                        StoredSchema.class));
-
-        return mapperUtility.wrapSchema(new ArrayList<>(schemas), paginationDTO);
-    }
-
-    @Override
-    public Map<String, Object> getSchemas(String domain, PaginationDTO paginationDTO) {
-        final List<StoredSchema> schemas = runMethodSafe(() -> readDataDslContext.select().from(table(String.format(
-                TIES_MODEL, "module_reference"))).where(field("status").eq(TiesConstants.IN_USAGE)).fetchInto(
-                        StoredSchema.class));
-
-        return mapperUtility.wrapSchema(schemas.stream().filter(s -> s.getDomain() != null && s.getDomain().matches(domain))
-                .toList(), paginationDTO);
-    }
-
-    @Override
-    public StoredSchema getSchema(String name) {
-        List<StoredSchema> schemas = readDataDslContext.select().from(table(String.format(TIES_MODEL, "module_reference")))
-                .where(field("name").eq(name)).fetchInto(StoredSchema.class);
-        if (schemas.isEmpty()) {
-            return null;
-        }
-
-        schemas.get(0).setContent(new String(Base64.getDecoder().decode(schemas.get(0).getContent()),
-                StandardCharsets.UTF_8));
-
-        return schemas.get(0);
-    }
-
-    @Override
-    public void postSchema(String name, String namespace, String domain, List<String> includedModules, String content,
-            String ownerAppId) {
-        writeDataDslContext.insertInto(table(String.format(TIES_MODEL, "module_reference"))).set(field("name"), name).set(
-                field("namespace"), namespace).set(field("domain"), domain).set(field("\"includedModules\""), JSONB.valueOf(
-                        JSONArray.toJSONString(includedModules))).set(field("content"), new String(Base64.getEncoder()
-                                .encode(content.replaceAll("\\r\\n?", "\n").getBytes(StandardCharsets.UTF_8)),
-                                StandardCharsets.UTF_8)).set(field("\"ownerAppId\""), ownerAppId).set(field("status"),
-                                        TiesConstants.IN_USAGE).execute();
-    }
-
-    @Override
-    public void setSchemaToDeleting(String name) {
-        writeDataDslContext.update(table(String.format(TIES_MODEL, "module_reference"))).set(field("status"), "DELETING")
-                .where(field("name").eq(name)).execute();
-    }
-
-    @Override
-    public void deleteSchema(String name) {
-        writeDataDslContext.deleteFrom(table(String.format(TIES_MODEL, "module_reference"))).where(field("name").eq(name))
-                .execute();
-    }
-
-    private boolean checkIfEntityWithIdExists(final EntityType entityType, final String id) {
-        return readDataDslContext.select(exists(select(field("1")).from(table(entityType.getTableName())).where(field(
-                ID_COLUMN_NAME).eq(id)))).fetch().get(0).value1();
-    }
-
-    protected <T> T runMethodSafe(Supplier<T> supp) {
-        try {
-            return supp.get();
-        } catch (TiesException ex) {
-            throw ex;
-        } catch (TiesPathException ex) {
-            log.error("Exception during query construction", ex);
-            throw ex;
-        } catch (Exception ex) {
-            log.error("Sql exception during query execution", ex);
-            throw TiesException.serverSQLException();
-        }
-    }
-
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImpl.java
new file mode 100644 (file)
index 0000000..f21039f
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ *  ============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.teiv.exposure.spi.impl;
+
+import static org.jooq.impl.DSL.falseCondition;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.jooq.impl.DSL.val;
+import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import org.jooq.Condition;
+import org.jooq.DSLContext;
+import org.jooq.JSONB;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.SelectConditionStep;
+import org.jooq.SelectOrderByStep;
+import org.jooq.impl.DSL;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.DataRepository;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
+import org.oran.smo.teiv.exposure.tiespath.refiner.BasePathRefinement;
+import org.oran.smo.teiv.exposure.tiespath.refiner.PathToJooqRefinement;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DataRepositoryImpl implements DataRepository {
+    private final BasePathRefinement basePathRefinement;
+
+    private final DSLContext readDataDslContext;
+
+    @Value("${consumer-data.batch-size:100}")
+    private int batchSize = 100;
+
+    @Override
+    public Result<Record> getEntityById(final EntityType entityType, final String id) {
+        return runMethodSafe(() -> readDataDslContext.select(entityType.getAllFieldsWithId()).from(entityType
+                .getTableName()).where(field(ID_COLUMN_NAME).eq(id)).fetch());
+    }
+
+    @Override
+    public Result<Record> getRelationshipById(final String id, final RelationType relationType) {
+        return runMethodSafe(() -> readDataDslContext.select(relationType.getAllFieldsWithId()).from(table(relationType
+                .getTableName())).where(field(String.format(QUOTED_STRING, relationType.getIdColumnName())).eq(id))
+                .fetch());
+    }
+
+    @Override
+    public Result<Record> getTopologyByFilterCriteria(final FilterCriteria filterCriteria, final int limit,
+            final int offset) {
+        basePathRefinement.refine(filterCriteria);
+        SelectOrderByStep<Record> query = PathToJooqRefinement.toJooq(filterCriteria, offset, limit);
+        log.debug("SQL: {}", query);
+
+        return runMethodSafe(() -> readDataDslContext.fetch(query));
+    }
+
+    @Override
+    public Set<String> getClassifiersForSchema(final String schemaName) {
+        SelectConditionStep<Record> availableClassifiers = runMethodSafe(() -> readDataDslContext.select().from(String
+                .format(TIES_CONSUMER_DATA, "classifiers")).where(field("\"moduleReferenceName\"").eq(schemaName)));
+        Set<String> result = new HashSet<>();
+        for (Record record : availableClassifiers) {
+            result.add((String) record.get("name"));
+        }
+        return result;
+    }
+
+    @Override
+    public Set<String> getDecoratorsForSchema(final String schemaName) {
+        SelectConditionStep<Record> availableDecorators = runMethodSafe(() -> readDataDslContext.select().from(String
+                .format(TIES_CONSUMER_DATA, "decorators")).where(field("\"moduleReferenceName\"").like(schemaName)));
+        Set<String> result = new HashSet<>();
+        for (Record record : availableDecorators) {
+            result.add((String) record.get("name"));
+        }
+        return result;
+    }
+
+    @Override
+    public List<String> getRelationshipIdsForDecoratorDeletion(final RelationType relationType,
+            final Set<String> decorators) {
+        Condition condition = falseCondition();
+        for (String decorator : decorators) {
+            condition = condition.or(DSL.condition("{0}->>{1} IS NOT NULL", field(String.format(QUOTED_STRING, relationType
+                    .getDecoratorsColumnName()), JSONB.class), val(decorator)));
+        }
+
+        final Condition finalCondition = condition;
+        return runMethodSafe(() -> readDataDslContext.select(field(relationType.getTableName() + "." + String.format(
+                QUOTED_STRING, relationType.getIdColumnName()))).from(table(relationType.getTableName())).where(field(
+                        relationType.getTableName() + "." + String.format(QUOTED_STRING, relationType.getIdColumnName()))
+                                .isNotNull().and(finalCondition)).orderBy(field(String.format(QUOTED_STRING, "id"))).limit(
+                                        batchSize).fetchInto(String.class));
+    }
+
+    @Override
+    public List<String> getRelationshipIdsForClassifierDeletion(final RelationType relationType,
+            final Set<String> classifiers) {
+        Condition condition = falseCondition();
+        for (String classifier : classifiers) {
+            condition = condition.or(field(String.format(QUOTED_STRING, relationType.getClassifiersColumnName()),
+                    JSONB.class).contains(JSONB.valueOf("[\"" + classifier + "\"]")));
+        }
+
+        final Condition finalCondition = condition;
+        return runMethodSafe(() -> readDataDslContext.select(field(relationType.getTableName() + "." + String.format(
+                QUOTED_STRING, relationType.getIdColumnName()))).from(table(relationType.getTableName())).where(field(
+                        relationType.getTableName() + "." + String.format(QUOTED_STRING, relationType.getIdColumnName()))
+                                .isNotNull().and(finalCondition)).orderBy(field(String.format(QUOTED_STRING, "id"))).limit(
+                                        batchSize).fetchInto(String.class));
+    }
+
+    @Override
+    public List<String> getEntityIdsForDecoratorDeletion(final EntityType entityType, final Set<String> decorators) {
+        Condition condition = falseCondition();
+        for (String decorator : decorators) {
+            condition = condition.or(DSL.condition("{0}->>{1} IS NOT NULL", field(String.format(QUOTED_STRING, entityType
+                    .getDecoratorsColumnName()), JSONB.class), val(decorator)));
+        }
+
+        final Condition finalCondition = condition;
+        return runMethodSafe(() -> readDataDslContext.select(field(entityType.getIdColumnName())).from(table(entityType
+                .getTableName())).where(finalCondition).orderBy(field(String.format(QUOTED_STRING, "id"))).limit(batchSize)
+                .fetchInto(String.class));
+    }
+
+    @Override
+    public List<String> getEntityIdsForClassifierDeletion(final EntityType entityType, final Set<String> classifiers) {
+        Condition condition = falseCondition();
+        for (String classifier : classifiers) {
+            condition = condition.or(field(String.format(QUOTED_STRING, entityType.getClassifiersColumnName()), JSONB.class)
+                    .contains(JSONB.valueOf("[\"" + classifier + "\"]")));
+        }
+
+        final Condition finalCondition = condition;
+        return runMethodSafe(() -> readDataDslContext.select(field(entityType.getIdColumnName())).from(table(entityType
+                .getTableName())).where(finalCondition).orderBy(field(String.format(QUOTED_STRING, "id"))).limit(batchSize)
+                .fetchInto(String.class));
+    }
+
+    protected <T> T runMethodSafe(Supplier<T> supp) {
+        try {
+            return supp.get();
+        } catch (TiesException ex) {
+            throw ex;
+        } catch (TiesPathException ex) {
+            log.error("Exception during query construction", ex);
+            throw ex;
+        } catch (Exception ex) {
+            log.error("Sql exception during query execution", ex);
+            throw TiesException.serverSQLException();
+        }
+    }
+
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/ModelRepositoryImpl.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/impl/ModelRepositoryImpl.java
new file mode 100644 (file)
index 0000000..1e40eea
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ *  ============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.teiv.exposure.spi.impl;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.name;
+import static org.jooq.impl.DSL.noCondition;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.IN_USAGE;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_MODEL;
+import static org.oran.smo.teiv.utils.TiesConstants.MODULE_REFERENCE;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.jooq.DSLContext;
+import org.jooq.Record;
+import org.jooq.Record1;
+import org.jooq.Select;
+import org.jooq.SelectConditionStep;
+import org.springframework.stereotype.Component;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.exposure.spi.Module;
+import org.oran.smo.teiv.exposure.spi.ModuleStatus;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class ModelRepositoryImpl implements ModelRepository {
+    public static final String STATUS = "status";
+    public static final String REVISION = "revision";
+    public static final String NAME = "name";
+
+    private final DSLContext readDataDslContext;
+    private final DSLContext readWriteDataDslContext;
+    private final DSLContext writeDataDslContext;
+
+    @Override
+    public boolean doesModuleExists(final String schemaName, final String name) {
+        final SelectConditionStep<Record1<Integer>> query = readDataDslContext.selectOne().from(String.format(schemaName,
+                MODULE_REFERENCE)).where(field(name(NAME)).eq(name));
+        return query.fetchAny() != null;
+    }
+
+    @Override
+    public Optional<Module> getConsumerModuleByName(final String name) {
+        final Record moduleRecord = runMethodSafe(() -> readDataDslContext.select().from(table(String.format(
+                TIES_CONSUMER_DATA, MODULE_REFERENCE))).where(field("name").eq(name)).and(field(STATUS).eq(
+                        ModuleStatus.IN_USAGE.name())).fetchAny());
+        return Optional.ofNullable(moduleRecord).map(module -> Module.builder().name((String) module.get(NAME)).namespace(
+                (String) module.get("namespace")).revision((String) module.get(REVISION)).ownerAppId((String) module.get(
+                        "ownerAppId")).status(ModuleStatus.valueOf((String) module.get(STATUS))).build());
+    }
+
+    @Override
+    public List<Module> getModules() {
+        return runMethodSafe(() -> {
+            final List<Module> modules = new ArrayList<>();
+            final List<Module> modulesFromModelSchema = getModulesBySchema(TIES_MODEL);
+            final List<Module> modulesFromConsumerDataSchema = getModulesBySchema(TIES_CONSUMER_DATA);
+            modules.addAll(modulesFromModelSchema);
+            modules.addAll(modulesFromConsumerDataSchema);
+            return modules;
+        });
+    }
+
+    @Override
+    public List<Module> getDeletingModulesOnStartup() {
+        return runMethodSafe(() -> readWriteDataDslContext.select().from(table(String.format(TIES_CONSUMER_DATA,
+                MODULE_REFERENCE))).where(field(STATUS).eq(ModuleStatus.DELETING.name())).fetchInto(Module.class));
+    }
+
+    @Override
+    public String getModuleContentByName(final String name) {
+        return runMethodSafe(() -> {
+            String content = getModuleContentByNameFromSchema(TIES_MODEL, name);
+            if (content == null || content.equals("")) {
+                content = getModuleContentByNameFromSchema(TIES_CONSUMER_DATA, name);
+            }
+            return content;
+        });
+    }
+
+    @Override
+    public void createModule(Module module) {
+        runMethodSafe(() -> writeDataDslContext.insertInto(table(String.format(TIES_CONSUMER_DATA, MODULE_REFERENCE))).set(
+                field(NAME), module.getName()).set(field("content"), module.getContent()).set(field("\"ownerAppId\""),
+                        module.getOwnerAppId()).set(field(STATUS), module.getStatus().name()).set(field(REVISION), module
+                                .getRevision()).execute());
+    }
+
+    @Override
+    public void updateModuleStatus(String name, ModuleStatus status) {
+        runMethodSafe(() -> writeDataDslContext.update(table(String.format(TIES_CONSUMER_DATA, MODULE_REFERENCE))).set(
+                field(STATUS), status.name()).where(field("name").eq(name)).execute());
+    }
+
+    @Override
+    public void deleteModuleByName(String name) {
+        runMethodSafe(() -> writeDataDslContext.deleteFrom(table(String.format(TIES_CONSUMER_DATA, MODULE_REFERENCE)))
+                .where(field("name").eq(name)).execute());
+    }
+
+    private List<Module> getModulesBySchema(final String schemaName) {
+        Select<Record> moduleRecords = readDataDslContext.select().from(table(String.format(schemaName, MODULE_REFERENCE)))
+                .where(noCondition());
+        Function<Record, Module> buildModuleFunction;
+
+        if (schemaName.equals(TIES_CONSUMER_DATA)) {
+            moduleRecords = moduleRecords.$where((field(STATUS).eq(IN_USAGE)));
+            buildModuleFunction = buildConsumerModules();
+        } else {
+            buildModuleFunction = buildBuiltInModule();
+        }
+
+        return moduleRecords.stream().map(buildModuleFunction).toList();
+    }
+
+    private Function<Record, Module> buildBuiltInModule() {
+        return moduleRecord -> Module.builder().name((String) moduleRecord.get(NAME)).namespace((String) moduleRecord.get(
+                "namespace")).domain((String) moduleRecord.get("domain")).revision((String) moduleRecord.get(REVISION))
+                .build();
+    }
+
+    private Function<Record, Module> buildConsumerModules() {
+        return moduleRecord -> Module.builder().name((String) moduleRecord.get(NAME)).namespace((String) moduleRecord.get(
+                "namespace")).revision((String) moduleRecord.get(REVISION)).ownerAppId((String) moduleRecord.get(
+                        "ownerAppId")).status(ModuleStatus.valueOf((String) moduleRecord.get(STATUS))).build();
+    }
+
+    private String getModuleContentByNameFromSchema(final String schemaName, final String name) {
+        return readDataDslContext.select(field("content")).from(table(String.format(schemaName, MODULE_REFERENCE))).where(
+                field("name").eq(name)).limit(1).fetchAnyInto(String.class);
+    }
+
+    private <T> T runMethodSafe(Supplier<T> supp) {
+        try {
+            return supp.get();
+        } catch (Exception ex) {
+            log.warn("Exception occurred during query execution.", ex);
+            throw TiesException.serverSQLException();
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapper.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapper.java
deleted file mode 100644 (file)
index b4dac6d..0000000
+++ /dev/null
@@ -1,102 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import org.jooq.Field;
-import org.jooq.Record;
-import org.jooq.Result;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import org.oran.smo.teiv.schema.SchemaRegistry;
-
-@RequiredArgsConstructor
-@Slf4j
-public class ComplexMapper extends ResponseMapper {
-
-    /**
-     * Maps the results of the queries created by the QueryModal to a REST response
-     *
-     * @param results
-     *     results of the query
-     * @return a map of the results
-     */
-    @Override
-    public Map<String, Object> map(Result<Record> results) {
-        final Map<String, List<Map<String, Object>>> response = new HashMap<>();
-        results.forEach(result -> {
-            Map<String, Object> record = new HashMap<>();
-            Map<String, Object> mappedRecords = new HashMap<>();
-            String currentObject = "";
-            String objectName = "";
-            for (Field field : result.fields()) {
-                String[] nameTokens = field.getName().split("\\.");
-                objectName = nameTokens[1].substring(1, nameTokens[1].length() - 1);
-
-                if (!currentObject.isEmpty() && !objectName.equals(currentObject)) {
-                    fillResult(currentObject, response, mappedRecords, record);
-                    mappedRecords.clear();
-                    record.clear();
-                }
-                fillRecord(nameTokens[2], record, mappedRecords, result, field);
-                currentObject = objectName;
-            }
-            fillResult(currentObject, response, mappedRecords, record);
-        });
-        return Collections.unmodifiableMap(response);
-    }
-
-    private void fillRecord(String nameToken, Map<String, Object> record, Map<String, Object> mappedRecords, Record result,
-            Field field) {
-        if (nameToken.replace("\"", "").equals(ID_COLUMN_NAME)) {
-            record.put(nameToken.replace("\"", ""), result.getValue(field));
-        } else {
-            mappedRecords.put(getModelledName(nameToken.replace("\"", "")), mapField(result, field));
-        }
-    }
-
-    private void fillResult(String currentObject, Map<String, List<Map<String, Object>>> response,
-            Map<String, Object> mappedRecords, Map<String, Object> record) {
-        if (!mappedRecords.values().stream().allMatch(Objects::isNull) || !record.values().stream().allMatch(
-                Objects::isNull)) {
-            String qualifiedName = SchemaRegistry.getEntityTypeByName(getModelledName(currentObject))
-                    .getFullyQualifiedName();
-            response.putIfAbsent(qualifiedName, new ArrayList<>());
-            if (!mappedRecords.values().stream().allMatch(Objects::isNull)) {
-                record.put(ATTRIBUTES, new HashMap<>(mappedRecords));
-            }
-            response.get(qualifiedName).add(new HashMap<>(record));
-        }
-    }
-
-}
index 4e303db..fdacaa8 100644 (file)
  */
 package org.oran.smo.teiv.exposure.spi.mapper;
 
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.CONSUMER_DATA_PREFIX;
-import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.firstHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.lastHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.nextHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.prevHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.selfHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.validateOffset;
 
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Record;
 import org.jooq.Result;
 
-import lombok.RequiredArgsConstructor;
+import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.springframework.stereotype.Component;
 
-import org.oran.smo.teiv.schema.EntityType;
-
-@RequiredArgsConstructor
+@Slf4j
+@Component
 public class EntityMapper extends ResponseMapper {
-
-    final EntityType entityType;
-
-    /**
-     * Maps the query results to an api response
-     *
-     * @param result
-     *     result of the query
-     * @return response
-     */
-    @Override
-    public Map<String, Object> map(final Result<Record> result) {
-        final Map<String, Object> responseData = new HashMap<>();
-        final Map<String, Object> mappedRecords = new HashMap<>();
-        result.forEach(record -> Arrays.stream(record.fields()).forEach(field -> {
-            if (getModelledName(field.getName()).equals(ID_COLUMN_NAME)) {
-                responseData.put(getModelledName(field.getName()), record.getValue(field));
-            } else if (getModelledName(field.getName()).startsWith(CONSUMER_DATA_PREFIX)) {
-                responseData.put(getModelledName(field.getName()).substring(CONSUMER_DATA_PREFIX.length()), mapField(record,
-                        field));
-            } else {
-                mappedRecords.put(getModelledName(field.getName()), mapField(record, field));
-            }
-        }));
-        responseData.put(ATTRIBUTES, mappedRecords);
-        return Map.of(entityType.getFullyQualifiedName(), List.of(responseData));
+    public OranTeivEntitiesResponseMessage mapEntities(final Result<Record> results, final RequestDetails requestDetails) {
+        //Pair<items, totalCount>
+        final Pair<List<Object>, Integer> pair = getItemsWithTotalCount(results);
+        int totalCount = pair.getRight();
+        validateOffset(requestDetails.getOffset(), totalCount);
+        return OranTeivEntitiesResponseMessage.builder().items(pair.getLeft()).first(firstHref(requestDetails)).prev(
+                prevHref(requestDetails, totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails,
+                        totalCount)).last(lastHref(requestDetails, totalCount)).totalCount(totalCount).build();
     }
-
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtility.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtility.java
deleted file mode 100644 (file)
index b044516..0000000
+++ /dev/null
@@ -1,209 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.spi.impl.StoredSchema;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-
-import java.util.Collections;
-import java.util.stream.Collectors;
-import org.jooq.DSLContext;
-import org.jooq.Record;
-import org.jooq.Result;
-import org.springframework.stereotype.Service;
-
-import org.oran.smo.teiv.exposure.spi.RelationMappedRecordsDTO;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.RelationType;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Service
-@Slf4j
-public class MapperUtility {
-
-    /**
-     * Maps the query results to an api response
-     *
-     * @param entityType
-     *     entityType
-     * @param result
-     *     result of the query
-     *
-     * @return response
-     */
-    public Map<String, Object> mapEntity(final EntityType entityType, final Result<Record> result) {
-        return new EntityMapper(entityType).map(result);
-    }
-
-    /**
-     * Maps all relationships
-     *
-     * @param result
-     * @param relationType
-     * @return all relationships
-     */
-    public Map<String, Object> mapRelationships(final Result<Record> result, final RelationType relationType) {
-        return new RelationshipsMapper(relationType).map(result);
-    }
-
-    /**
-     * Maps one relationship
-     *
-     * @param result
-     * @param relationType
-     * @return one relationship
-     */
-    public Map<String, Object> mapRelationship(final Result<Record> result, final RelationType relationType) {
-        return new RelationshipMapper(relationType).map(result);
-    }
-
-    /**
-     * Maps the results of the queries created by the QueryModal to a REST response
-     *
-     * @param results
-     *     results of the query
-     * @param paginationDTO
-     *     pagination data
-     *
-     * @return a map of the results
-     */
-    public Map<String, Object> mapComplexQuery(final Result<Record> results, final PaginationDTO paginationDTO) {
-        return wrapResponse(results, new ComplexMapper(), paginationDTO);
-    }
-
-    public Map<String, Object> wrapMapObject(final Map<String, Object> results, final PaginationDTO paginationDTO) {
-
-        validateOffset(paginationDTO);
-
-        Map<String, Object> response = new HashMap<>();
-        response.put("items", List.of(results));
-
-        PaginationMetaData paginationMetaData = new PaginationMetaData();
-        response.putAll(paginationMetaData.getObjectList(paginationDTO));
-
-        response.put("query", queryPart(paginationDTO));
-        return response;
-    }
-
-    public Map<String, Object> wrapList(final List<Object> objectsList, final PaginationDTO paginationDTO) {
-        Map<String, Object> response = new HashMap<>();
-        paginationDTO.setTotalSize(objectsList.size());
-
-        if (objectsList.size() <= paginationDTO.getOffset() && !objectsList.isEmpty()) {
-            throw TiesException.invalidValueException("Offset", objectsList.size() - 1, true);
-        } else {
-            response.put("items", objectsList.subList(paginationDTO.getOffset(), Math.min(paginationDTO
-                    .getOffset() + paginationDTO.getLimit(), objectsList.size())));
-        }
-
-        PaginationMetaData paginationMetaData = new PaginationMetaData();
-        response.putAll(paginationMetaData.getObjectList(paginationDTO));
-
-        return response;
-    }
-
-    public Map<String, Object> wrapSchema(final List<StoredSchema> schemaList, final PaginationDTO paginationDTO) {
-        List<Map<String, Object>> response = new ArrayList<>();
-
-        for (StoredSchema schema : schemaList) {
-            Map<String, Object> innerResponse = new HashMap<>();
-            innerResponse.put("name", schema.getName());
-            innerResponse.put("domain", schema.getDomain() == null ?
-                    Collections.emptyList() :
-                    Collections.singletonList(schema.getDomain()));
-            innerResponse.put("revision", schema.getRevision());
-            innerResponse.put("content", Collections.singletonMap("href", "/schemas/" + schema.getName() + "/content"));
-            response.add(innerResponse);
-        }
-
-        return wrapList(new ArrayList<>(response), paginationDTO);
-    }
-
-    private Map<String, Object> wrapResponse(final Result<Record> results, final ResponseMapper responseMapper,
-            final PaginationDTO paginationDTO) {
-        validateOffset(paginationDTO);
-
-        Map<String, Object> response = new HashMap<>();
-        response.put("items", List.of(responseMapper.map(results)));
-
-        PaginationMetaData paginationMetaData = new PaginationMetaData();
-        response.putAll(paginationMetaData.getObjectList(paginationDTO));
-
-        response.put("query", queryPart(paginationDTO));
-        return response;
-    }
-
-    private Map<String, Object> queryPart(final PaginationDTO paginationDTO) {
-        Map<String, Object> response = new HashMap<>();
-        response.putAll(paginationDTO.getPathParameters());
-        Map<String, String> notNullQueryParameters = paginationDTO.getQueryParameters().entrySet().stream().filter(
-                entry -> entry.getValue() != null).collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry
-                        .getValue()));
-        response.putAll(notNullQueryParameters);
-
-        return response;
-    }
-
-    public Map<String, Object> wrapRelationships(List<RelationMappedRecordsDTO> records, List<RelationType> relationTypes,
-            DSLContext readDataDslContext, final PaginationDTO paginationDTO) {
-        Map<String, Object> response = new HashMap<>();
-
-        if (paginationDTO.getTotalSize() <= paginationDTO.getOffset() && !records.isEmpty()) {
-            throw TiesException.invalidValueException("Offset", records.size() - 1, true);
-        } else {
-            //TODO: Refactor the logic since RelationMappedRecordsDTO already contains the relation type
-            List<RelationMappedRecordsDTO> pagedRecords = records.subList(paginationDTO.getOffset(), Math.min(paginationDTO
-                    .getOffset() + paginationDTO.getLimit(), records.size()));
-            Map<String, Result<Record>> batch = new HashMap<>();
-            for (RelationMappedRecordsDTO record : pagedRecords) {
-                RelationType relTypeForCurrentRecord = record.getRelationType();
-                if (!batch.containsKey(relTypeForCurrentRecord.getFullyQualifiedName())) {
-                    batch.put(relTypeForCurrentRecord.getFullyQualifiedName(), readDataDslContext.newResult());
-                }
-                batch.get(relTypeForCurrentRecord.getFullyQualifiedName()).add(record.getRecord());
-            }
-            List<Map<String, Object>> mappedResults = new ArrayList<>();
-            for (Map.Entry<String, Result<Record>> entry : batch.entrySet()) {
-                mappedResults.add(mapRelationships(entry.getValue(), relationTypes.stream().filter(relType -> relType
-                        .getFullyQualifiedName().equals(entry.getKey())).findFirst().orElseThrow()));
-            }
-            response.put("items", mappedResults);
-
-        }
-
-        PaginationMetaData paginationMetaData = new PaginationMetaData();
-        response.putAll(paginationMetaData.getObjectList(paginationDTO));
-
-        return response;
-    }
-
-    private void validateOffset(PaginationDTO paginationDTO) {
-        if (paginationDTO.getTotalSize() < paginationDTO.getOffset()) {
-            throw TiesException.invalidValueException("Offset", paginationDTO.getTotalSize() - 1, true);
-        }
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PageMetaData.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PageMetaData.java
deleted file mode 100644 (file)
index b0d6ca5..0000000
+++ /dev/null
@@ -1,51 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import lombok.Getter;
-
-import java.util.Map;
-
-@Getter
-public class PageMetaData {
-
-    private final String href;
-
-    public PageMetaData(final PaginationDTO paginationDTO) {
-        this(paginationDTO.getOffset(), paginationDTO.getLimit(), paginationDTO);
-    }
-
-    public PageMetaData(final int offset, final PaginationDTO paginationDTO) {
-        this(offset, paginationDTO.getLimit(), paginationDTO);
-    }
-
-    public PageMetaData(final int offset, final int limit, final PaginationDTO paginationDTO) {
-        StringBuilder stringBuilder = new StringBuilder(paginationDTO.getBasePath() + String.format("?offset=%s&limit=%s",
-                offset, limit));
-        for (Map.Entry<String, String> entry : paginationDTO.getQueryParameters().entrySet()) {
-            if (entry.getValue() != null) {
-                stringBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue());
-            }
-        }
-        this.href = stringBuilder.toString();
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaData.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaData.java
deleted file mode 100644 (file)
index 3a44586..0000000
+++ /dev/null
@@ -1,74 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class PaginationMetaData {
-
-    public Map<String, Object> getObjectList(final PaginationDTO paginationDTO) {
-        Map<String, Object> innerResponse = new HashMap<>();
-        PageMetaData self = new PageMetaData(paginationDTO);
-        innerResponse.put("self", self);
-
-        innerResponse.put("next", hasNextPage(paginationDTO) ?
-                new PageMetaData(Math.min(paginationDTO.getOffset() + paginationDTO.getLimit(), paginationDTO
-                        .getTotalSize()), paginationDTO) :
-                self);
-
-        innerResponse.put("last", hasNextPage(paginationDTO) ?
-                new PageMetaData(calculateLastPageOffset(paginationDTO), paginationDTO) :
-                self);
-
-        innerResponse.put("first", new PageMetaData(0, paginationDTO));
-
-        innerResponse.put("prev", hasPrevPage(paginationDTO) ?
-                new PageMetaData(Math.max(paginationDTO.getOffset() - paginationDTO.getLimit(), 0), paginationDTO) :
-                self);
-
-        innerResponse.put("totalCount", paginationDTO.getTotalSize());
-
-        return innerResponse;
-    }
-
-    private boolean hasNextPage(final PaginationDTO paginationDTO) {
-        return (paginationDTO.getOffset() + paginationDTO.getLimit()) < paginationDTO.getTotalSize() && paginationDTO
-                .getTotalSize() > 0;
-    }
-
-    private boolean hasPrevPage(final PaginationDTO paginationDTO) {
-        return paginationDTO.getOffset() > 0 && paginationDTO.getTotalSize() > 0;
-    }
-
-    private int calculateLastPageOffset(final PaginationDTO paginationDTO) {
-        int diff = paginationDTO.getTotalSize() - paginationDTO.getOffset();
-
-        if (diff % paginationDTO.getLimit() == 0) {
-            return (diff / paginationDTO.getLimit() - 1) * paginationDTO.getLimit() + paginationDTO.getOffset();
-        }
-
-        return (diff / paginationDTO.getLimit()) * paginationDTO.getLimit() + paginationDTO.getOffset();
-
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/QueryMetaData.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/QueryMetaData.java
deleted file mode 100644 (file)
index 92287a1..0000000
+++ /dev/null
@@ -1,59 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import lombok.AllArgsConstructor;
-
-import static org.oran.smo.teiv.utils.TiesConstants.QUERY;
-import static org.oran.smo.teiv.utils.TiesConstants.SCOPE_FILTER;
-import static org.oran.smo.teiv.utils.TiesConstants.TARGET_FILTER;
-
-@AllArgsConstructor
-public class QueryMetaData {
-
-    private String targetFilter;
-    private String scopeFilter;
-
-    public Map<String, Object> getObjectList() {
-        Map<String, Object> response = new HashMap<>();
-        Map<String, Object> innerResponse = new HashMap<>();
-
-        boolean hasResponse = false;
-
-        if (!targetFilter.isEmpty()) {
-            innerResponse.put(TARGET_FILTER, targetFilter);
-            hasResponse = true;
-
-        }
-        if (!scopeFilter.isEmpty()) {
-            innerResponse.put(SCOPE_FILTER, scopeFilter);
-            hasResponse = true;
-        }
-        if (hasResponse) {
-            response.put(QUERY, innerResponse);
-        }
-        return response;
-    }
-
-}
index bfbe520..a4900e9 100644 (file)
  */
 package org.oran.smo.teiv.exposure.spi.mapper;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Record;
 import org.jooq.Result;
 
-import org.oran.smo.teiv.schema.RelationType;
-import lombok.RequiredArgsConstructor;
+import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.springframework.stereotype.Component;
 
-@RequiredArgsConstructor
-public class RelationshipMapper extends ResponseMapper {
-    final RelationType relationType;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.firstHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.lastHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.nextHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.prevHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.selfHref;
+import static org.oran.smo.teiv.exposure.utils.PaginationUtil.validateOffset;
 
-    @Override
-    public Map<String, Object> map(final Result<Record> record) {
-        final Map<String, List<Object>> relationshipMap = new HashMap<>();
-        relationshipMap.put(relationType.getFullyQualifiedName(), List.of(createProperties(record.get(0), relationType)));
-        return Collections.unmodifiableMap(relationshipMap);
+@Component
+public class RelationshipMapper extends ResponseMapper {
+    public OranTeivRelationshipsResponseMessage mapRelationships(final Result<Record> results,
+            final RequestDetails requestDetails) {
+        //Pair<items, totalCount>
+        final Pair<List<Object>, Integer> pair = getItemsWithTotalCount(results);
+        int totalCount = pair.getRight();
+        validateOffset(requestDetails.getOffset(), totalCount);
+        return OranTeivRelationshipsResponseMessage.builder().items(pair.getLeft()).first(firstHref(requestDetails)).prev(
+                prevHref(requestDetails, totalCount)).self(selfHref(requestDetails)).next(nextHref(requestDetails,
+                        totalCount)).last(lastHref(requestDetails, totalCount)).totalCount(totalCount).build();
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapper.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapper.java
deleted file mode 100644 (file)
index 9a6baf1..0000000
+++ /dev/null
@@ -1,50 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jooq.Record;
-import org.jooq.Result;
-
-import org.oran.smo.teiv.schema.RelationType;
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public class RelationshipsMapper extends ResponseMapper {
-
-    final RelationType relationType;
-
-    @Override
-    public Map<String, Object> map(final Result<Record> result) {
-        final Map<String, List<Object>> relationshipsMap = new HashMap<>();
-        final List<Object> relationships = new ArrayList<>();
-        result.stream().filter(record -> Arrays.stream(record.valuesRow().fields()).noneMatch(field -> field.getName()
-                .equals("null"))).forEach(record -> relationships.add(createProperties(record, relationType)));
-        relationshipsMap.put(relationType.getFullyQualifiedName(), relationships);
-        return Collections.unmodifiableMap(relationshipsMap);
-    }
-}
index 0316f8d..e5a8d68 100644 (file)
  */
 package org.oran.smo.teiv.exposure.spi.mapper;
 
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.getOriginalAlias;
 import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
 import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_A_SIDE;
 import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_B_SIDE;
 import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
 import static org.oran.smo.teiv.utils.TiesConstants.SOURCE_IDS;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Field;
 import org.jooq.JSONB;
 import org.jooq.Record;
@@ -38,12 +41,13 @@ import org.jooq.exception.DataTypeException;
 
 import org.oran.smo.teiv.schema.RelationType;
 import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.utils.TiesConstants;
 
 @Slf4j
 public abstract class ResponseMapper {
-    public abstract Map<String, Object> map(final Result<Record> result);
+    private static final String COUNT_FIELD = "count";
 
-    protected Map<String, Object> createProperties(final Record record, RelationType relationType) {
+    protected Map<String, Object> createProperties(final Record record, final RelationType relationType) {
         final Map<String, Object> dataMap = new HashMap<>();
         dataMap.put(ID_COLUMN_NAME, String.valueOf(record.get(relationType.getTableName() + "." + String.format(
                 QUOTED_STRING, relationType.getIdColumnName()))));
@@ -61,7 +65,7 @@ public abstract class ResponseMapper {
         return dataMap;
     }
 
-    protected Object mapField(Record record, org.jooq.Field<?> field) {
+    protected Object mapField(final Record record, org.jooq.Field<?> field) {
         try {
             return !field.getType().equals(JSONB.class) ? record.getValue(field) : record.get(field, Map.class);
         } catch (DataTypeException e) {
@@ -69,4 +73,62 @@ public abstract class ResponseMapper {
             return record.get(field, List.class);
         }
     }
+
+    public Pair<List<Object>, Integer> getItemsWithTotalCount(final Result<Record> results) {
+        List<Object> items = new ArrayList<>();
+        int totalCount = 0;
+        for (Record result : results) {
+            String managedObject = null;
+            for (Field field : result.fields()) {
+                final String alias = getOriginalAlias(field.getName());
+                String[] nameTokens = alias.split("\\.");
+                if (isCountField(nameTokens)) {
+                    final Object count = result.get(COUNT_FIELD);
+                    if (null != count) {
+                        totalCount = (int) count;
+                    }
+                    break;
+                }
+
+                if (isIdFieldNotNull(result, field, nameTokens)) {
+                    managedObject = nameTokens[0];
+                }
+            }
+
+            if (managedObject != null) {
+                items.add(getItem(result, managedObject));
+            }
+        }
+        return Pair.of(items, totalCount);
+    }
+
+    private boolean isIdFieldNotNull(final Record result, final Field field, final String[] nameTokens) {
+        return nameTokens[1].equals(ID_COLUMN_NAME) && result.get(field) != null;
+    }
+
+    private boolean isCountField(final String[] nameTokens) {
+        return nameTokens.length < 2 && nameTokens[0].equals(COUNT_FIELD);
+    }
+
+    private Map<String, Object> getItem(final Record result, final String managedObject) {
+        Map<String, Object> item = new HashMap<>();
+        Map<String, Object> data = new HashMap<>();
+        Map<String, Object> attributes = new HashMap<>();
+        for (Field field : result.fields()) {
+            final String alias = getOriginalAlias(field.getName());
+            String[] nameTokens = alias.split("\\.");
+            if (nameTokens[0].equals(managedObject)) {
+                if (nameTokens[1].equals("attr")) {
+                    attributes.put(nameTokens[2], mapField(result, field));
+                } else {
+                    data.put(nameTokens[1], mapField(result, field));
+                }
+            }
+        }
+        if (!attributes.isEmpty()) {
+            data.put(TiesConstants.ATTRIBUTES, attributes);
+        }
+        item.put(managedObject, List.of(data));
+        return item;
+    }
 }
index c68279c..9f1bb95 100644 (file)
@@ -22,7 +22,9 @@ package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.jooq.util.xml.jaxb.Table;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jooq.Field;
+import org.jooq.Table;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -40,4 +42,16 @@ public abstract class AndOrLogicalBlock extends LogicalBlock {
         tables.addAll(children.get(1).getTables());
         return tables;
     }
+
+    @Override
+    public Set<Pair<String, Field>> getJoinCondition() {
+        Set<Pair<String, Field>> tables = new HashSet<>();
+        tables.addAll(children.get(0).getJoinCondition());
+        tables.addAll(children.get(1).getJoinCondition());
+        return tables;
+    }
+
+    public void addChild(LogicalBlock logicalBlock) {
+        children.add(logicalBlock);
+    }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ConditionFactory.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ConditionFactory.java
new file mode 100644 (file)
index 0000000..54faceb
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ *  ============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.teiv.exposure.tiespath.innerlanguage;
+
+import static org.jooq.impl.DSL.condition;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.name;
+import static org.oran.smo.teiv.exposure.tiespath.innerlanguage.QueryFunction.EQ;
+import static org.oran.smo.teiv.utils.PersistableUtil.getTableNameWithColumnName;
+import static org.oran.smo.teiv.utils.TiesConstants.ITEM;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Objects;
+
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.JSONB;
+
+import lombok.experimental.UtilityClass;
+import org.oran.smo.teiv.schema.DataType;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.Persistable;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.RelationshipDataLocation;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+@UtilityClass
+public class ConditionFactory {
+    private static final String INVALID_TOPOLOGY_OBJECT_TYPE = "Invalid topology object type";
+    private static final String INVALID_QUERY_FUNCTION = "Invalid query function";
+
+    public static AnyCondition create(final ScopeObject scopeObject) {
+
+        return switch (scopeObject.getContainer()) {
+            case ATTRIBUTES -> new AttributesCondition();
+            case RELATION -> new RelationCondition();
+            case ID -> new IdCondition();
+            case ASSOCIATION -> new AssociationCondition();
+            case CLASSIFIERS, SOURCE_IDS -> new ConsumerDataListCondition();
+            case DECORATORS -> new ConsumerDataMapCondition();
+        };
+    }
+
+    abstract static class AnyCondition {
+
+        public abstract Condition getCondition(final ScopeObject scopeObject);
+
+        protected static Object convert(final ScopeObject scopeObject) {
+
+            switch (scopeObject.getDataType()) {
+                case PRIMITIVE -> {
+                    return String.valueOf(scopeObject.getParameter());
+                }
+                case INTEGER -> {
+                    return Integer.valueOf(scopeObject.getParameter());
+                }
+                case BIGINT -> {
+                    return new BigInteger(scopeObject.getParameter());
+                }
+                case DECIMAL -> {
+                    return new BigDecimal(scopeObject.getParameter());
+                }
+                case CONTAINER -> {
+                    return JSONB.valueOf(scopeObject.getParameter());
+                }
+                case GEOGRAPHIC -> {
+                    validateGeographicParameter(scopeObject.getParameter());
+                    return scopeObject.getParameter();
+                }
+                default -> throw TiesPathException.invalidQueryCondition("Unexpected value: " + scopeObject.getDataType());
+            }
+        }
+
+        protected static Persistable getPersistable(final ScopeObject scopeObject) {
+            switch (scopeObject.getTopologyObjectType()) {
+                case ENTITY -> {
+                    return SchemaRegistry.getEntityTypeByName(scopeObject.getTopologyObject());
+                }
+                case RELATION -> {
+                    return SchemaRegistry.getRelationTypeByName(scopeObject.getTopologyObject());
+                }
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_TOPOLOGY_OBJECT_TYPE);
+            }
+        }
+
+        private static void validateGeographicParameter(final String parameter) {
+            if (!parameter.toLowerCase().startsWith("point(") || !parameter.endsWith(")")) {
+                throw TiesPathException.invalidQueryCondition("Invalid geographic format.");
+            }
+
+            final String[] coordinates = parameter.substring(parameter.indexOf("(") + 1, parameter.indexOf(")")).split(" ");
+            if (coordinates.length != 2) {
+                throw TiesPathException.invalidQueryCondition(
+                        "A point should have 2 coordinates (longitude and latitude).");
+            }
+
+            for (String coord : coordinates) {
+                try {
+                    new BigDecimal(coord);
+                } catch (NumberFormatException ex) {
+                    throw TiesPathException.invalidQueryCondition(String.format("Invalid coordinate: %s", coord));
+                }
+            }
+        }
+    }
+
+    static class AttributesCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+            if (scopeObject.getInnerContainer().isEmpty()) {
+                return handleSimpleAttribute(scopeObject);
+            }
+            return handleComplexAttribute(scopeObject);
+        }
+
+        private Condition handleSimpleAttribute(final ScopeObject scopeObject) {
+            switch (scopeObject.getQueryFunction()) {
+                case EQ -> {
+                    if (scopeObject.getDataType().equals(DataType.GEOGRAPHIC)) {
+                        return condition(String.format("%s = st_geomfromtext('%s')", handleSimpleLeaf(scopeObject), convert(
+                                scopeObject)));
+                    }
+                    return field(handleSimpleLeaf(scopeObject)).eq(convert(scopeObject));
+                }
+                case CONTAINS -> {
+                    if (scopeObject.getDataType().equals(DataType.GEOGRAPHIC)) {
+                        throw TiesPathException.invalidQueryCondition("Cannot have CONTAINS on geography type data");
+                    }
+                    return field(handleSimpleLeaf(scopeObject)).contains(convert(scopeObject));
+                }
+                default -> {
+                    return field(handleSimpleLeaf(scopeObject)).isNotNull();
+                }
+            }
+        }
+
+        private Condition handleComplexAttribute(final ScopeObject scopeObject) {
+            switch (scopeObject.getQueryFunction()) {
+                case EQ -> {
+                    if (scopeObject.getLeaf().equals(ITEM)) {
+                        return condition(handleContainers(scopeObject) + String.format(" @> '%s'", handleEqComplexParameter(
+                                scopeObject)));
+                    }
+                    return field(handleContainers(scopeObject) + String.format(" -> '%s'", scopeObject.getLeaf())).eq(field(
+                            applyQuotes(handleEqComplexParameter(scopeObject))));
+                }
+                case CONTAINS -> {
+                    if (scopeObject.getLeaf().equals(ITEM)) {
+                        return condition(handleContainersForArray(scopeObject) + String.format("::text like '%%%s%%'",
+                                scopeObject.getParameter()));
+                    }
+                    return condition(field(handleContainers(scopeObject) + String.format(" ->> '%s'", scopeObject
+                            .getLeaf())).like(handleLikeComplexParameter(scopeObject)));
+                }
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_QUERY_FUNCTION);
+            }
+        }
+
+        private String handleEqComplexParameter(final ScopeObject scopeObject) {
+            if (scopeObject.getDataType().equals(DataType.INTEGER)) {
+                return scopeObject.getParameter();
+            }
+            return String.valueOf(name(scopeObject.getParameter()));
+        }
+
+        private String handleLikeComplexParameter(final ScopeObject scopeObject) {
+            if (scopeObject.getDataType().equals(DataType.INTEGER)) {
+                return scopeObject.getParameter();
+            }
+            return String.format("%%%s%%", scopeObject.getParameter());
+        }
+
+        private String handleSimpleLeaf(final ScopeObject scopeObject) {
+            return handleTopologyObjectType(scopeObject).getTableName() + "." + name(scopeObject.getLeaf());
+        }
+
+        private String handleContainers(final ScopeObject scopeObject) {
+
+            if (scopeObject.getInnerContainer().size() > 1) {
+                StringBuilder sb = new StringBuilder();
+
+                for (String element : scopeObject.getInnerContainer().subList(1, scopeObject.getInnerContainer().size())) {
+                    sb.append(" -> ").append(applyQuotes(element));
+                }
+                return handleTopologyObjectType(scopeObject).getTableName() + "." + name(scopeObject.getInnerContainer()
+                        .get(0)) + sb;
+            }
+            return handleTopologyObjectType(scopeObject).getTableName() + "." + name(scopeObject.getInnerContainer().get(
+                    0));
+        }
+
+        private String handleContainersForArray(final ScopeObject scopeObject) {
+
+            if (scopeObject.getInnerContainer().size() > 1) {
+                StringBuilder sb = new StringBuilder();
+
+                for (String element : scopeObject.getInnerContainer().subList(1, scopeObject.getInnerContainer()
+                        .size() - 1)) {
+                    sb.append(" -> ").append(applyQuotes(element));
+                }
+                sb.append(" ->> ").append(applyQuotes(scopeObject.getInnerContainer().get(scopeObject.getInnerContainer()
+                        .size() - 1)));
+                return handleTopologyObjectType(scopeObject).getTableName() + "." + name(scopeObject.getInnerContainer()
+                        .get(0)) + sb;
+            }
+            return handleTopologyObjectType(scopeObject).getTableName() + "." + name(scopeObject.getInnerContainer().get(
+                    0));
+        }
+
+        private Persistable handleTopologyObjectType(final ScopeObject scopeObject) {
+            Persistable persistable;
+
+            switch (scopeObject.getTopologyObjectType()) {
+                case ENTITY -> persistable = SchemaRegistry.getEntityTypeByName(scopeObject.getTopologyObject());
+                case RELATION -> persistable = SchemaRegistry.getRelationTypeByName(scopeObject.getTopologyObject());
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_TOPOLOGY_OBJECT_TYPE);
+            }
+
+            return persistable;
+        }
+
+        private static String applyQuotes(String element) {
+            return String.format("'%s'", element);
+        }
+    }
+
+    static class RelationCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+
+            switch (scopeObject.getQueryFunction()) {
+                case EQ -> {
+                    return equalsCondition(scopeObject);
+                }
+                case NOT_NULL -> {
+                    return notNullCondition(scopeObject);
+                }
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_QUERY_FUNCTION);
+            }
+        }
+
+        private static Condition equalsCondition(final ScopeObject scopeObject) {
+
+            return field(getColumnName(scopeObject)).eq(convert(scopeObject));
+        }
+
+        private static String getColumnName(final ScopeObject scopeObject) {
+
+            if (Objects.requireNonNull(scopeObject.getTopologyObjectType()) == TopologyObjectType.ENTITY) {
+
+                final List<String> relationNames = SchemaRegistry.getRelationNamesByEntityName(scopeObject
+                        .getTopologyObject());
+
+                final String relationName = relationNames.stream().filter(name -> name.equals(scopeObject
+                        .getInnerContainer().get(0))).findFirst().orElseThrow(() -> TiesPathException.invalidQueryCondition(
+                                "Relationship was not found for topology object"));
+
+                final Persistable persistable = SchemaRegistry.getRelationTypeByName(relationName);
+
+                return Objects.requireNonNull(persistable).getTableName() + "." + name(persistable.getIdColumnName());
+            } else {
+                throw TiesPathException.invalidQueryCondition(INVALID_TOPOLOGY_OBJECT_TYPE);
+            }
+        }
+
+        private static Condition notNullCondition(final ScopeObject scopeObject) {
+
+            return field(getColumnName(scopeObject)).isNotNull();
+        }
+    }
+
+    static class AssociationCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+
+            RelationType relation;
+
+            switch (scopeObject.getTopologyObjectType()) {
+
+                case ENTITY -> {
+                    final List<RelationType> relationTypes = SchemaRegistry.getAllRelationNamesByAssociationName(scopeObject
+                            .getInnerContainer().get(0));
+                    relation = relationTypes.stream().filter(r -> r.getASide().getName().equals(scopeObject
+                            .getTopologyObject()) || r.getBSide().getName().equals(scopeObject.getTopologyObject()))
+                            .findFirst().orElseThrow(() -> TiesPathException.invalidQueryCondition(
+                                    "Relation was not found"));
+                }
+                case RELATION -> relation = SchemaRegistry.getRelationTypeByName(scopeObject.getTopologyObject());
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_TOPOLOGY_OBJECT_TYPE);
+            }
+
+            switch (scopeObject.getQueryFunction()) {
+                case EQ, CONTAINS -> {
+
+                    EntityType entityType;
+                    String sideColumnName;
+
+                    if (Objects.requireNonNull(relation).getRelationshipStorageLocation().equals(
+                            RelationshipDataLocation.A_SIDE)) {
+                        entityType = relation.getASide();
+                        sideColumnName = relation.bSideColumnName();
+                    } else if (relation.getRelationshipStorageLocation().equals(RelationshipDataLocation.B_SIDE)) {
+                        entityType = relation.getBSide();
+                        sideColumnName = relation.aSideColumnName();
+                    } else {
+                        if (relation.isConnectsSameEntity()) {
+                            sideColumnName = checkSameEntityRelationship(relation, scopeObject);
+                        } else {
+                            sideColumnName = checkManyToMany(relation, scopeObject);
+                        }
+                        if (scopeObject.getQueryFunction().equals(EQ)) {
+                            return condition(field(getTableNameWithColumnName(relation.getTableName(), sideColumnName)).eq(
+                                    scopeObject.getParameter()));
+                        }
+                        return condition(field(getTableNameWithColumnName(relation.getTableName(), sideColumnName))
+                                .contains(scopeObject.getParameter()));
+
+                    }
+                    return ConditionFactory.getConditionContainsOrEquals(scopeObject, relation, entityType, sideColumnName);
+                }
+                case NOT_NULL -> {
+                    return condition(field(SchemaRegistry.getReferenceColumnName(Objects.requireNonNull(relation)))
+                            .isNotNull());
+                }
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_QUERY_FUNCTION);
+            }
+        }
+
+        private static String checkManyToMany(RelationType relation, ScopeObject scopeObject) {
+            if (relation.getASide().getName().equals(scopeObject.getTopologyObject()) || SchemaRegistry
+                    .getEntityTypeOnAssociationSide(relation, scopeObject.getInnerContainer().get(0)).getName().equals(
+                            relation.getASide().getName())) {
+                return relation.bSideColumnName();
+            } else {
+                return relation.aSideColumnName();
+            }
+        }
+
+        private static String checkSameEntityRelationship(RelationType relation, ScopeObject scopeObject) {
+            if (relation.getASideAssociation().getName().equals(scopeObject.getInnerContainer().get(0))) {
+                return relation.aSideColumnName();
+            } else {
+                return relation.bSideColumnName();
+            }
+        }
+    }
+
+    private static Condition getConditionContainsOrEquals(ScopeObject scopeObject, RelationType relation,
+            EntityType entityType, String sideColumnName) {
+        if (scopeObject.getTopologyObject().equals(entityType.getName()) || SchemaRegistry.getEntityTypeOnAssociationSide(
+                relation, scopeObject.getInnerContainer().get(0)).getName().equals(entityType.getName())) {
+            Field<Object> field = field(getTableNameWithColumnName(Objects.requireNonNull(entityType).getTableName(),
+                    sideColumnName));
+
+            if (scopeObject.getQueryFunction().equals(EQ)) {
+                return condition(field.eq(scopeObject.getParameter()));
+            }
+            return condition(field.contains(scopeObject.getParameter()));
+
+        } else {
+            if (scopeObject.getQueryFunction().equals(EQ)) {
+                return condition(field(getTableNameWithColumnName(entityType.getTableName(), sideColumnName)).isNotNull())
+                        .and(condition(field(getTableNameWithColumnName(entityType.getTableName(), entityType
+                                .getIdColumnName())).eq(scopeObject.getParameter())));
+            }
+            return condition(field(getTableNameWithColumnName(entityType.getTableName(), sideColumnName)).isNotNull()).and(
+                    condition(field(getTableNameWithColumnName(entityType.getTableName(), entityType.getIdColumnName()))
+                            .contains(scopeObject.getParameter())));
+        }
+    }
+
+    static class ConsumerDataMapCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+            if (scopeObject.getQueryFunction().equals(EQ)) {
+
+                return equalsCondition(scopeObject);
+            }
+
+            return containsCondition(scopeObject);
+        }
+
+        private static String getColumnName(final ScopeObject scopeObject) {
+
+            final Persistable persistable = getPersistable(scopeObject);
+
+            return Objects.requireNonNull(persistable).getTableName() + "." + name(persistable.getDecoratorsColumnName());
+        }
+
+        private static Condition equalsCondition(final ScopeObject scopeObject) {
+
+            String newValue = scopeObject.getParameter();
+
+            if (scopeObject.getDataType().equals(DataType.PRIMITIVE)) {
+                newValue = String.format("\"%s\"", convert(scopeObject));
+
+            }
+
+            return field(getColumnName(scopeObject) + " -> '" + scopeObject.getLeaf() + "'").eq(field(
+                    "'" + newValue + "'"));
+        }
+
+        private static Condition containsCondition(final ScopeObject scopeObject) {
+
+            return field(getColumnName(scopeObject) + " ->> '" + scopeObject.getLeaf() + "'").like("%" + scopeObject
+                    .getParameter() + "%");
+        }
+    }
+
+    static class ConsumerDataListCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+            if (scopeObject.getQueryFunction().equals(EQ)) {
+
+                return equalsCondition(scopeObject);
+            }
+
+            return containsCondition(scopeObject);
+        }
+
+        private static String getColumnName(final ScopeObject scopeObject) {
+
+            final Persistable persistable = getPersistable(scopeObject);
+
+            if (scopeObject.getContainer().equals(ContainerType.CLASSIFIERS)) {
+                return Objects.requireNonNull(persistable).getTableName() + "." + name(persistable
+                        .getClassifiersColumnName());
+            }
+
+            return Objects.requireNonNull(persistable).getTableName() + "." + name(persistable.getSourceIdsColumnName());
+        }
+
+        private static Condition equalsCondition(final ScopeObject scopeObject) {
+
+            return condition(String.format("%s @> '\"%s\"'", getColumnName(scopeObject), scopeObject.getParameter()));
+        }
+
+        private static Condition containsCondition(final ScopeObject scopeObject) {
+
+            return condition(String.format("%s::text like '%%%s%%'", getColumnName(scopeObject), scopeObject
+                    .getParameter()));
+        }
+    }
+
+    static class IdCondition extends AnyCondition {
+
+        @Override
+        public Condition getCondition(final ScopeObject scopeObject) {
+
+            switch (scopeObject.getQueryFunction()) {
+                case EQ -> {
+                    return field(getColumnName(scopeObject)).eq(convert(scopeObject));
+                }
+                case CONTAINS -> {
+                    return field(getColumnName(scopeObject)).contains(convert(scopeObject));
+                }
+                case NOT_NULL -> {
+                    return field(getColumnName(scopeObject)).isNotNull();
+                }
+                default -> throw TiesPathException.invalidQueryCondition(INVALID_QUERY_FUNCTION);
+            }
+        }
+
+        private static String getColumnName(final ScopeObject scopeObject) {
+            final Persistable persistable = getPersistable(scopeObject);
+            return persistable.getIdColumnNameWithTableName();
+        }
+    }
+}
index 46de5ff..3543c5d 100644 (file)
@@ -22,21 +22,23 @@ package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
 import jakarta.annotation.Nullable;
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 
 @Getter
+@RequiredArgsConstructor
 public enum ContainerType {
-    ATTRIBUTES("attributes"),
-    DECORATORS("decorators"),
-    CLASSIFIERS("classifiers"),
-    ID("id"),
-    SOURCE_IDS("sourceIds"),
-    ASSOCIATION("association");
+    ATTRIBUTES("attributes", true),
+    DECORATORS("decorators", false),
+    CLASSIFIERS("classifiers", false),
+    ID("id", false),
+    SOURCE_IDS("sourceIds", false),
 
-    private final String value;
+    //ToDo Resolver should not treat below two as containers but refinement do so this needs to be fixed
+    ASSOCIATION("association", false),
+    RELATION("relation", false);
 
-    ContainerType(String value) {
-        this.value = value;
-    }
+    private final String value;
+    private final boolean isParamAllowedInTargetFilter;
 
     @Nullable
     public static ContainerType fromValue(String value) {
index 5ee9223..10e59c3 100644 (file)
@@ -22,8 +22,13 @@ package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
 import java.util.Collections;
 import java.util.Set;
+
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Condition;
-import org.jooq.util.xml.jaxb.Table;
+import org.jooq.Field;
+import org.jooq.Table;
+
+import static org.jooq.impl.DSL.noCondition;
 
 public class EmptyLogicalBlock extends LogicalBlock {
     private static EmptyLogicalBlock emptyLogicalBlock = null;
@@ -40,11 +45,15 @@ public class EmptyLogicalBlock extends LogicalBlock {
 
     @Override
     public Condition getCondition() {
-        return null;
+        return noCondition();
     }
 
     @Override
     public Set<Table> getTables() {
         return Collections.emptySet();
     }
+
+    public Set<Pair<String, Field>> getJoinCondition() {
+        return Collections.emptySet();
+    }
 }
index 56bb0ce..26b55e9 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
+import lombok.Getter;
+import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
-import org.jooq.Condition;
 import org.jooq.SelectField;
-import org.jooq.util.xml.jaxb.Table;
+import org.oran.smo.teiv.schema.DataType;
 
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 
 @Data
+@Builder(builderMethodName = "hiddenBuilder")
 @Slf4j
 public class FilterCriteria {
+    @NonNull
     private final String domain;
-    private List<TargetObject> targets = new ArrayList<>();
-    private LogicalBlock scope;
+    private final ResolvingTopologyObjectType resolvingTopologyObjectType;
+    private List<InnerFilterCriteria> filterCriteriaList;
 
-    public FilterCriteria(String domain) {
-        this.domain = domain;
+    public static FilterCriteriaBuilder builder(final String domain) {
+        return hiddenBuilder().domain(domain);
     }
 
-    public Condition getCondition() {
-        return scope.getCondition();
-    }
-
-    public Set<Table> getTables() {
-        Set<Table> tables = new HashSet<>();
-        tables.addAll(scope.getTables());
+    public Map<SelectField, Map<SelectField, DataType>> getSelects() {
+        Map<SelectField, Map<SelectField, DataType>> selectFields = new HashMap<>();
 
-        targets.forEach(t -> tables.add(getTablesFromTarget(t)));
-
-        return tables;
-    }
-
-    public Set<SelectField> getSelects() {
-        Set<SelectField> selectFields = new HashSet<>();
-
-        targets.forEach(t -> selectFields.add(getSelectFromTarget(t)));
+        filterCriteriaList.forEach(t -> {
+            Map<SelectField, Map<SelectField, DataType>> selects = t.getSelects();
+            for (Map.Entry<SelectField, Map<SelectField, DataType>> select : selects.entrySet()) {
+                if (!selectFields.containsKey(select.getKey())) {
+                    selectFields.put(select.getKey(), new HashMap<>());
+                }
+                selectFields.get(select.getKey()).putAll(select.getValue());
+            }
+        });
 
         return selectFields;
     }
 
-    private SelectField getSelectFromTarget(TargetObject t) {
-        log.trace(t.toString());
-        return null;
-    }
+    @Getter
+    @AllArgsConstructor
+    public enum ResolvingTopologyObjectType {
+        RELATIONSHIP(true, false),
+        ENTITY(false, true),
+        ALL(true, true);
 
-    @SuppressWarnings("squid:S4144")
-    private Table getTablesFromTarget(TargetObject t) {
-        log.trace(t.toString());
-        return null;
+        private final boolean resolveRelationships;
+        private final boolean resolveEntities;
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/InnerFilterCriteria.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/InnerFilterCriteria.java
new file mode 100644 (file)
index 0000000..b44c7d0
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  ============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.teiv.exposure.tiespath.innerlanguage;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
+import static org.oran.smo.teiv.utils.PersistableUtil.getFullyQualifiedNameWithColumnName;
+import static org.oran.smo.teiv.utils.PersistableUtil.getTableNameWithColumnName;
+import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_A_SIDE;
+import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_B_SIDE;
+import static org.oran.smo.teiv.utils.TiesConstants.SOURCE_IDS;
+import static org.oran.smo.teiv.utils.TiesConstants.DECORATORS;
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.SelectField;
+import org.jooq.Table;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.schema.DataType;
+import org.oran.smo.teiv.schema.Persistable;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Data
+@Slf4j
+@Builder
+public class InnerFilterCriteria {
+    private List<TargetObject> targets;
+    private LogicalBlock scope;
+
+    public Condition getCondition() {
+        return scope.getCondition();
+    }
+
+    public Set<Table> getTables() {
+        Set<Table> tables = new HashSet<>();
+        tables.addAll(scope.getTables());
+
+        targets.forEach(t -> tables.add(getTableFromTarget(t)));
+
+        return tables;
+    }
+
+    public Set<Pair<String, Field>> getJoinCondition() {
+        Set<Pair<String, Field>> joins = new HashSet<>();
+        joins.addAll(scope.getJoinCondition());
+
+        return joins;
+    }
+
+    public Map<SelectField, Map<SelectField, DataType>> getSelects() {
+        Map<SelectField, Map<SelectField, DataType>> selectFields = new HashMap<>();
+
+        targets.forEach(t -> {
+            Pair<SelectField, Map<SelectField, DataType>> select = getSelectFromTarget(t);
+            if (!selectFields.containsKey(select.getLeft())) {
+                selectFields.put(select.getLeft(), new HashMap<>());
+            }
+            selectFields.get(select.getLeft()).putAll(select.getRight());
+        });
+
+        return selectFields;
+    }
+
+    @SuppressWarnings({ "java:S108", "java:S5738" })
+    private Pair<SelectField, Map<SelectField, DataType>> getSelectFromTarget(TargetObject targetObject) {
+        Map<SelectField, DataType> select = new HashMap<>();
+
+        final Persistable persistable;
+        String idColumn;
+        switch (targetObject.getTopologyObjectType()) {
+            case ENTITY -> {
+                persistable = SchemaRegistry.getEntityTypeByName(targetObject.getTopologyObject());
+                idColumn = getTableNameWithColumnName(persistable.getTableName(), ID_COLUMN_NAME);
+            }
+            case RELATION -> {
+                persistable = SchemaRegistry.getRelationTypeByName(targetObject.getTopologyObject());
+                idColumn = getTableNameWithColumnName(persistable.getTableName(), persistable.getIdColumnName());
+
+                select.put(field(getTableNameWithColumnName(persistable.getTableName(), ((RelationType) persistable)
+                        .aSideColumnName())).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable
+                                .getFullyQualifiedName(), PROPERTY_A_SIDE))), DataType.PRIMITIVE);
+                select.put(field(getTableNameWithColumnName(persistable.getTableName(), ((RelationType) persistable)
+                        .bSideColumnName())).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable
+                                .getFullyQualifiedName(), PROPERTY_B_SIDE))), DataType.PRIMITIVE);
+            }
+            default -> throw TiesException.unParsedTopologyObjectType(targetObject.getTopologyObject());
+        }
+
+        select.put(field(idColumn).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable.getFullyQualifiedName(),
+                ID_COLUMN_NAME))), DataType.PRIMITIVE);
+
+        switch (targetObject.getContainer()) {
+            case ATTRIBUTES -> {
+                if (targetObject.isAllParamQueried()) {
+                    select.putAll(persistable.getSpecificAttributeColumns(List.of()));
+                } else {
+                    select.putAll(persistable.getSpecificAttributeColumns(targetObject.getParams()));
+                }
+            }
+            case DECORATORS -> select.put(field(getTableNameWithColumnName(persistable.getTableName(), persistable
+                    .getDecoratorsColumnName()), JSONB.class).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable
+                            .getFullyQualifiedName(), DECORATORS))), DataType.CONTAINER);
+            case CLASSIFIERS -> select.put(field(getTableNameWithColumnName(persistable.getTableName(), persistable
+                    .getClassifiersColumnName()), JSONB.class).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable
+                            .getFullyQualifiedName(), CLASSIFIERS))), DataType.CONTAINER);
+            case ID -> {
+            }
+            case SOURCE_IDS -> select.put(field(getTableNameWithColumnName(persistable.getTableName(), persistable
+                    .getSourceIdsColumnName()), JSONB.class).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable
+                            .getFullyQualifiedName(), SOURCE_IDS))), DataType.CONTAINER);
+            default -> throw TiesException.invalidContainerType(targetObject.getContainer().getValue());
+        }
+
+        return Pair.of(field(idColumn).as(hashAlias(getFullyQualifiedNameWithColumnName(persistable.getFullyQualifiedName(),
+                ID_COLUMN_NAME))), select);
+    }
+
+    public Table getTableFromTarget(TargetObject targetObject) {
+        switch (targetObject.getTopologyObjectType()) {
+            case ENTITY -> {
+                return table(SchemaRegistry.getEntityTypeByName(targetObject.getTopologyObject()).getTableName());
+            }
+            case RELATION -> {
+                return table(SchemaRegistry.getRelationTypeByName(targetObject.getTopologyObject()).getTableName());
+            }
+            default -> throw TiesException.unParsedTopologyObjectType(targetObject.getTopologyObject());
+        }
+    }
+}
index b5154f7..e44e101 100644 (file)
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
 import lombok.Data;
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Condition;
-import org.jooq.util.xml.jaxb.Table;
+import org.jooq.Field;
+import org.jooq.Table;
 
 import java.util.Set;
 
@@ -33,4 +35,6 @@ public abstract class LogicalBlock {
     public abstract Condition getCondition();
 
     public abstract Set<Table> getTables();
+
+    public abstract Set<Pair<String, Field>> getJoinCondition();
 }
index fee1f36..a52fe57 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
+import lombok.Getter;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+@Getter
 public enum QueryFunction {
-    EQ,
-    CONTAINS
+    EQ("="),
+    CONTAINS("contains"),
+    NOT_NULL("notNull");
+
+    private final String value;
+
+    QueryFunction(String value) {
+        this.value = value;
+    }
+
+    public static QueryFunction fromValue(String value) {
+        for (QueryFunction queryFunction : QueryFunction.values()) {
+            if (queryFunction.getValue().equals(value)) {
+                return queryFunction;
+            }
+        }
+        throw TiesPathException.grammarError("Unsupported operation: " + value);
+    }
 }
index 373b858..ccd17db 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
-import java.util.Collections;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.jooq.Condition;
-import org.jooq.util.xml.jaxb.Table;
+import org.jooq.Field;
+import org.jooq.Table;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.RelationshipDataLocation;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
 
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.PersistableUtil.getTableNameWithColumnName;
+import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
 @Data
 @EqualsAndHashCode(callSuper = true)
 @RequiredArgsConstructor
@@ -37,11 +54,96 @@ public class ScopeLogicalBlock extends LogicalBlock {
 
     @Override
     public Condition getCondition() {
-        return null;
+        return ConditionFactory.create(scopeObject).getCondition(scopeObject);
     }
 
     @Override
     public Set<Table> getTables() {
-        return Collections.emptySet();
+
+        Set<Table> result = new HashSet<>();
+
+        if (scopeObject.getContainer().equals(ContainerType.ASSOCIATION)) {
+            result.add(addAssociationToTable());
+        } else if (scopeObject.getTopologyObjectType() == TopologyObjectType.ENTITY) {
+            result.add(addEntityToTable());
+        } else if (scopeObject.getTopologyObjectType() == TopologyObjectType.RELATION) {
+            result.add(addRelationToTable());
+        } else if (scopeObject.getTopologyObjectType() == TopologyObjectType.UNDEFINED) {
+            throw TiesException.unknownTopologyObjectType(scopeObject.getTopologyObject());
+        }
+
+        return result;
     }
+
+    public Set<Pair<String, Field>> getJoinCondition() {
+        HashSet<Pair<String, Field>> joinCondition = new HashSet<>();
+        if (scopeObject.getContainer().equals(ContainerType.ASSOCIATION) && scopeObject.getTopologyObjectType().equals(
+                TopologyObjectType.ENTITY)) {
+            EntityType entityType = SchemaRegistry.getEntityTypeByName(scopeObject.getTopologyObject());
+            String association = scopeObject.getInnerContainer().get(0);
+            List<RelationType> relationTypes = SchemaRegistry.getAllRelationNamesByAssociationName(association);
+
+            RelationType relationType = relationTypes.stream().filter(relation -> relation.getASide().equals(
+                    entityType) || relation.getBSide().equals(entityType)).findFirst().orElseThrow(() -> TiesPathException
+                            .invalidAssociation(entityType.getName(), association));
+
+            if (relationType.getRelationshipStorageLocation().equals(RelationshipDataLocation.RELATION)) {
+                String columnName = "";
+                if (relationType.getASide().equals(entityType)) {
+                    columnName = relationType.aSideColumnName();
+                } else {
+                    columnName = relationType.bSideColumnName();
+                }
+                String col1 = constructColumnNameForJoinCondition(relationType, columnName);
+                String col2 = getTableNameWithColumnName(entityType.getTableName(), ID_COLUMN_NAME);
+
+                joinCondition.add(constructJoinConditionPair(relationType, col1, col2));
+            } else if (!relationType.getStoringSideEntityType().equals(scopeObject.getTopologyObject())) {
+                String col1 = constructColumnNameForJoinCondition(relationType, relationType
+                        .getNotStoringSideEntityIdColumnNameInStoringSideTable());
+                String col2 = getTableNameWithColumnName(relationType.getNotStoringSideTableName(), ID_COLUMN_NAME);
+
+                joinCondition.add(constructJoinConditionPair(relationType, col1, col2));
+            }
+        }
+        return joinCondition;
+    }
+
+    private static String constructColumnNameForJoinCondition(RelationType relationType, String columnName) {
+        return relationType.getTableName() + "." + String.format(QUOTED_STRING, columnName);
+    }
+
+    private static Pair<String, Field> constructJoinConditionPair(RelationType relationType, String col1, String col2) {
+        Field equalsField = field(col1 + "=" + col2);
+        return new ImmutablePair<>(relationType.getTableName(), equalsField);
+    }
+
+    private Table addEntityToTable() {
+        return table(SchemaRegistry.getEntityTypeByName(scopeObject.getTopologyObject()).getTableName());
+    }
+
+    private Table addRelationToTable() {
+        return table(SchemaRegistry.getRelationTypeByName(scopeObject.getTopologyObject()).getTableName());
+    }
+
+    private Table addAssociationToTable() {
+        List<RelationType> relationTypes = SchemaRegistry.getAllRelationNamesByAssociationName(scopeObject
+                .getInnerContainer().get(0));
+        if (scopeObject.getTopologyObjectType().equals(TopologyObjectType.ENTITY)) {
+            for (RelationType relation : relationTypes) {
+                if (relation.getASide().getName().equals(scopeObject.getTopologyObject()) || relation.getBSide().getName()
+                        .equals(scopeObject.getTopologyObject())) {
+                    return table(relation.getTableName());
+                }
+            }
+        } else {
+            Optional<RelationType> relation = relationTypes.stream().filter(relationType -> relationType.getName().equals(
+                    scopeObject.getTopologyObject())).findFirst();
+            if (relation.isPresent()) {
+                return table(relation.get().getTableName());
+            }
+        }
+        throw TiesException.invalidAssociationType(scopeObject.getInnerContainer().get(0));
+    }
+
 }
index f2a51f7..52e0396 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
+import lombok.Builder;
+import org.oran.smo.teiv.exposure.tiespath.resolver.ResolverDataType;
 import org.oran.smo.teiv.schema.DataType;
 import lombok.Data;
 
-import java.util.ArrayList;
 import java.util.List;
 
 @Data
+@Builder(builderMethodName = "hiddenBuilder")
 public class ScopeObject {
     private String topologyObject;
+    @Builder.Default
     private TopologyObjectType topologyObjectType = TopologyObjectType.UNDEFINED;
     private ContainerType container;
-    private List<String> innerContainer = new ArrayList<>(); // in first round it is not supported
+    @Builder.Default
+    private List<String> innerContainer = List.of(); // in first round it is not supported
     private String leaf;
     private QueryFunction queryFunction;
     private String parameter;
     private DataType dataType;
+    private ResolverDataType resolverDataType;
 
-    public ScopeObject(String topologyObject, ContainerType container, QueryFunction queryFunction, String parameter,
-            DataType dataType) {
-        this(topologyObject, container, null, queryFunction, parameter, dataType);
-    }
-
-    public ScopeObject(String topologyObject, ContainerType container, String leaf, QueryFunction queryFunction,
-            String parameter, DataType dataType) {
-        this.topologyObject = topologyObject;
-        this.container = container;
-        this.leaf = leaf;
-        this.queryFunction = queryFunction;
-        this.parameter = parameter;
-        this.dataType = dataType;
+    public static ScopeObjectBuilder builder(final String topologyObject) {
+        return hiddenBuilder().topologyObject(topologyObject);
     }
 }
index 815babb..d497592 100644 (file)
@@ -24,10 +24,12 @@ import java.util.List;
 
 import lombok.Builder;
 import lombok.Data;
+import lombok.NonNull;
 
 @Data
 @Builder(builderMethodName = "hiddenBuilder")
 public class TargetObject {
+    @NonNull
     private String topologyObject;
     @Builder.Default
     private TopologyObjectType topologyObjectType = TopologyObjectType.UNDEFINED;
@@ -36,7 +38,11 @@ public class TargetObject {
     @Builder.Default
     private List<String> params = List.of();
 
-    public static TargetObjectBuilder builder(String topologyObject) {
+    private boolean isAllParamQueried;
+
+    private boolean isGenerated;
+
+    public static TargetObjectBuilder builder(final String topologyObject) {
         return hiddenBuilder().topologyObject(topologyObject);
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapper.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapper.java
new file mode 100644 (file)
index 0000000..17196ee
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  ============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.teiv.exposure.tiespath.refiner;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+
+import jakarta.xml.bind.DatatypeConverter;
+import org.oran.smo.teiv.exception.TiesException;
+
+@Slf4j
+@UtilityClass
+public class AliasMapper {
+    private static final String SHA_1 = "SHA-1";
+    private static final int POSTGRES_MAX_IDENTIFIER_LENGTH = 63;
+    private static final Map<String, String> originalToHashed = new ConcurrentHashMap<>();
+    private static final Map<String, String> hashedToOriginal = new ConcurrentHashMap<>();
+
+    /**
+     * Hashes the original alias if it is more than 63 characters and stores in the originalToHashed & hashedToOriginal
+     * maps.
+     *
+     * @param originalAlias
+     *     - original alias
+     * @return hashed alias if more than 63 characters otherwise original alias
+     */
+    public static String hashAlias(final String originalAlias) {
+        if (originalAlias.length() <= POSTGRES_MAX_IDENTIFIER_LENGTH) {
+            return originalAlias;
+        }
+        if (originalToHashed.containsKey(originalAlias)) {
+            return originalToHashed.get(originalAlias);
+        }
+        final String hashedAlias = generateSha1Hash(originalAlias);
+        originalToHashed.put(originalAlias, hashedAlias);
+        hashedToOriginal.put(hashedAlias, originalAlias);
+        return hashedAlias;
+    }
+
+    /**
+     * Gets the original alias from the hashed alias.
+     *
+     * @param hashedAlias
+     *     - hashed alias
+     * @return original alias
+     */
+    public static String getOriginalAlias(String hashedAlias) {
+        return hashedToOriginal.getOrDefault(hashedAlias, hashedAlias);
+    }
+
+    private static String generateSha1Hash(final String stringToHash) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance(SHA_1);
+            byte[] hashBytes = digest.digest(stringToHash.getBytes(StandardCharsets.UTF_8));
+            return DatatypeConverter.printHexBinary(hashBytes).toUpperCase(Locale.US);
+        } catch (NoSuchAlgorithmException exception) {
+            log.warn("Not a valid algorithm", exception);
+            throw TiesException.serverException("Invalid Hashing algorithm", "Error while hashing alias", exception);
+        }
+    }
+}
index 755aca2..37cd05f 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.refiner;
 
+import lombok.RequiredArgsConstructor;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataValidator;
+import org.oran.smo.teiv.exposure.consumerdata.model.Classifiers;
+import org.oran.smo.teiv.exposure.consumerdata.model.Decorators;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndOrLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.EmptyLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
 
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.QueryFunction;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.InnerFilterCriteria;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeObject;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TopologyObjectType;
+import org.oran.smo.teiv.exposure.tiespath.resolver.ResolverDataType;
+import org.oran.smo.teiv.schema.DataType;
 import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.Persistable;
 import org.oran.smo.teiv.schema.RelationType;
 import org.oran.smo.teiv.schema.SchemaRegistry;
 import org.oran.smo.teiv.utils.query.exception.TiesPathException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TargetObject;
 
 import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.function.BiConsumer;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-import lombok.experimental.UtilityClass;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.NotImplementedException;
+import org.springframework.stereotype.Component;
 
-import static org.oran.smo.teiv.utils.TiesConstants.ITEMS;
+import static org.oran.smo.teiv.schema.DataType.BIGINT;
+import static org.oran.smo.teiv.schema.DataType.DECIMAL;
+import static org.oran.smo.teiv.schema.DataType.INTEGER;
+import static org.oran.smo.teiv.schema.DataType.PRIMITIVE;
+import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.ITEM;
 
-@UtilityClass
+@Component
 @Slf4j
+@RequiredArgsConstructor
 public class BasePathRefinement {
+    private final ConsumerDataValidator consumerDataValidator;
 
-    @SuppressWarnings("squid:S4144")
-    public static void resolveWildCardObjectsInScopeAndTarget(FilterCriteria filterCriteria) {
-        // change every * to the possible topology object
-        // get the intersection of all possibilities to resolve the * (base set come from domain)
-        // there are topology objects in TO or SO-s we only can work with them
-        // there is no matching entity for the * throw error!
-        // on multiple match connect with OR
-        log.trace(filterCriteria.toString());
-        throw new NotImplementedException(filterCriteria.toString());
+    /**
+     * Main method to orchestrate the refinement process
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void refine(FilterCriteria filterCriteria) {
+        processTopologyObjectsWithContainerTypeNull(filterCriteria);
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> resolveWildCardObjectsInScopeAndTarget(
+                innerFilterCriteria, filterCriteria.getDomain(), filterCriteria.getResolvingTopologyObjectType()));
+        resolveUndefinedTopologyObjectTypes(filterCriteria);
+        validateContainers(filterCriteria);
+        validateScopeParametersDataType(filterCriteria);
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> checkIfTargetMatchesWithScope(
+                innerFilterCriteria, filterCriteria.getDomain()));
+        splitFilterCriteria(filterCriteria);
+        validateQuery(filterCriteria);
+        applyRelationshipCriteria(filterCriteria);
+    }
+
+    /**
+     * Process topology objects with container type null.
+     * If scopeResolver can not differentiate ASSOCIATION from ENTITY and RELATION,
+     * this function does additional settings of ScopeObjects.
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void processTopologyObjectsWithContainerTypeNull(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> runOnTree(innerFilterCriteria.getScope(),
+                filterCriteria.getDomain(), this::setContainerTypesAndTopologyObjects));
+    }
+
+    private void setContainerTypesAndTopologyObjects(ScopeLogicalBlock slb, String domain) {
+        if (slb.getScopeObject().getContainer() == null) {
+            if (slb.getScopeObject().getInnerContainer().isEmpty()) {
+                throw TiesPathException.grammarError("invalid scopeFilter");
+            }
+            boolean isResolved = false;
+            if (SchemaRegistry.getEntityNames().stream().anyMatch(entityName -> SchemaRegistry
+                    .getAssociationNamesByEntityName(entityName).contains(slb.getScopeObject().getInnerContainer().get(
+                            0))) || !SchemaRegistry.getAllRelationNamesByAssociationName(slb.getScopeObject()
+                                    .getInnerContainer().get(0)).isEmpty()) {
+                setContainerTypeForScopeLogicalBlocksScopeObject(slb, ContainerType.ASSOCIATION);
+                isResolved = true;
+            }
+            if (SchemaRegistry.getRelationNames().contains(slb.getScopeObject().getInnerContainer().get(0))) {
+                checkIfAlreadyResolved(slb.getScopeObject().getInnerContainer().get(0), isResolved);
+                setContainerTypeForScopeLogicalBlocksScopeObject(slb, ContainerType.RELATION);
+                isResolved = true;
+            }
+            isResolved = entityTopologyObjectSettings(slb, isResolved);
+            if (!isResolved) {
+                throw TiesPathException.invalidInnerContainer(slb.getScopeObject().getInnerContainer().get(0));
+            }
+        } else if (slb.getScopeObject().getContainer().equals(ContainerType.ATTRIBUTES) && !slb.getScopeObject()
+                .getInnerContainer().isEmpty() && slb.getScopeObject().getTopologyObject() == null) {
+            slb.getScopeObject().setTopologyObject("*");
+        }
+    }
+
+    private void setContainerTypeForScopeLogicalBlocksScopeObject(ScopeLogicalBlock slb, ContainerType containerType) {
+        slb.getScopeObject().setContainer(containerType);
+        if (slb.getScopeObject().getTopologyObject() == null) {
+            slb.getScopeObject().setTopologyObject("*");
+        }
+    }
+
+    private boolean entityTopologyObjectSettings(ScopeLogicalBlock slb, boolean isResolved) {
+        if (SchemaRegistry.getEntityNames().contains(slb.getScopeObject().getInnerContainer().get(0))) {
+            checkIfAlreadyResolved(slb.getScopeObject().getInnerContainer().get(0), isResolved);
+            if (slb.getScopeObject().getLeaf().equals(ID_COLUMN_NAME)) {
+                slb.getScopeObject().setContainer(ContainerType.ID);
+                slb.getScopeObject().setLeaf(null);
+            } else {
+                throw TiesPathException.grammarError("invalid scopeFilter, missing containerType");
+            }
+            if (slb.getScopeObject().getTopologyObject() == null) {
+                slb.getScopeObject().setTopologyObject(slb.getScopeObject().getInnerContainer().get(0));
+                slb.getScopeObject().getInnerContainer().remove(0);
+            } else {
+                throw TiesPathException.grammarError("invalid ScopeFilter");
+            }
+            isResolved = true;
+        }
+        return isResolved;
+    }
+
+    private void checkIfAlreadyResolved(String innerContainer, boolean isResolved) {
+        if (isResolved) {
+            throw TiesPathException.ambiguousTopologyObject(innerContainer);
+        }
+    }
+
+    /**
+     * Unifies duplicated targets by container type.
+     * e.g. TargetFilter: /NRCellDU/attributes(fdn); /NRCellDU/attributes(nCI) --> /NRCellDU/attributes(fdn,nCI)
+     * TargetFilter: /attributes; /attributes(fdn) --> /attributes(fdn) and isAllParamQueried = true (every attribute of
+     * TopologyObjects if they have attribute fdn)
+     */
+    private void unifyDuplicatedTargetsByContainerType(List<TargetObject> targetObjects, ContainerType containerType) {
+        Set<String> uniqueTopologyObjects = new HashSet<>();
+        targetObjects.stream().filter(targetObject -> targetObject.getContainer().equals(containerType)).forEach(
+                targetObject -> uniqueTopologyObjects.add(targetObject.getTopologyObject()));
+
+        for (String topologyObject : uniqueTopologyObjects) {
+            final Set<String> unifiedParams = new HashSet<>();
+            boolean isAllParamQueried = containerType == ContainerType.ATTRIBUTES && targetObjects.stream().anyMatch(
+                    targetObject -> targetObject.getTopologyObject().equals(topologyObject) && (targetObject.getParams()
+                            .isEmpty() || targetObject.isAllParamQueried()) && targetObject.getContainer().equals(
+                                    containerType));
+
+            targetObjects.stream().filter(targetObject -> targetObject.getTopologyObject().equals(
+                    topologyObject) && targetObject.getContainer().equals(containerType)).forEach(
+                            targetObject -> unifiedParams.addAll(targetObject.getParams()));
+
+            targetObjects.removeIf(targetObject -> targetObject.getTopologyObject().equals(topologyObject) && targetObject
+                    .getContainer().equals(containerType));
+            TargetObject unifiedTarget = TargetObject.builder(topologyObject).container(containerType).params(unifiedParams
+                    .stream().toList()).isAllParamQueried(isAllParamQueried).build();
+
+            targetObjects.add(unifiedTarget);
+        }
+    }
+
+    /**
+     * Resolve wildcard topologyObjects in scopeObjects and in targetObjects.
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void resolveWildCardObjectsInScopeAndTarget(InnerFilterCriteria filterCriteria, String domain,
+            FilterCriteria.ResolvingTopologyObjectType resolvingTopologyObjectType) {
+        if (filterCriteria.getTargets() == null || filterCriteria.getTargets().isEmpty()) {
+            filterCriteria.setTargets(List.of(TargetObject.builder("*").container(ContainerType.ID).build()));
+        }
+
+        // merge targets
+        Arrays.stream(ContainerType.values()).toList().forEach(containerType -> unifyDuplicatedTargetsByContainerType(
+                filterCriteria.getTargets(), containerType));
+
+        // calculate situation
+        final List<ScopeLogicalBlock> wildCardsInScope = new ArrayList<>();
+        final List<ScopeLogicalBlock> nonWildCardsInScope = new ArrayList<>();
+        runOnTree(filterCriteria.getScope(), domain, (lb, s) -> {
+            if (lb.getScopeObject().getTopologyObject().equals("*")) {
+                wildCardsInScope.add(lb);
+            } else {
+                nonWildCardsInScope.add(lb);
+            }
+        });
+
+        boolean wildCardInTarget = filterCriteria.getTargets().stream().anyMatch(t -> t.getTopologyObject().equals("*"));
+        boolean wildCardInScope = (filterCriteria.getScope() instanceof EmptyLogicalBlock) || !wildCardsInScope.isEmpty();
+        boolean isAllParamRequired = filterCriteria.getTargets().stream().anyMatch(t -> t.getTopologyObject().equals(
+                "*") && t.getContainer().equals(ContainerType.ATTRIBUTES) && t.isAllParamQueried());
+
+        // skip when nothing to do
+        if ((!wildCardInScope || filterCriteria.getScope() instanceof EmptyLogicalBlock) && !wildCardInTarget) {
+            return;
+        }
+
+        List<Persistable> possibleTypes = listPossibleTypes(filterCriteria, domain, nonWildCardsInScope, wildCardInTarget,
+                wildCardInScope, resolvingTopologyObjectType);
+
+        filterPossibleTypesInTarget(filterCriteria, possibleTypes);
+        filterPossibleTypesInScope(wildCardsInScope, possibleTypes);
+
+        // check
+        if (possibleTypes.isEmpty()) {
+            throw TiesPathException.notMatchingScopeAndTargetFilter();
+        }
+
+        resolveTargets(filterCriteria, isAllParamRequired, possibleTypes);
+
+        // merge targets
+        Arrays.stream(ContainerType.values()).toList().forEach(containerType -> unifyDuplicatedTargetsByContainerType(
+                filterCriteria.getTargets(), containerType));
+
+        //resolve scope
+        List<LogicalBlock> resolvedTrees = new ArrayList<>();
+        if (!(filterCriteria.getScope() instanceof EmptyLogicalBlock) && wildCardInScope) {
+            possibleTypes.forEach(t -> resolvedTrees.add(copyTree(filterCriteria.getScope(), t.getName())));
+        } else {
+            return;
+        }
+
+        rebuildBinaryTree(filterCriteria, resolvedTrees);
+    }
+
+    private List<Persistable> listPossibleTypes(InnerFilterCriteria filterCriteria, String domain,
+            List<ScopeLogicalBlock> nonWildCardsInScope, boolean wildCardInTarget, boolean wildCardInScope,
+            FilterCriteria.ResolvingTopologyObjectType resolvingTopologyObjectType) {
+        List<Persistable> result = new ArrayList<>();
+        if (!wildCardInTarget) {
+            if (resolvingTopologyObjectType.isResolveEntities()) {
+                result.addAll(filterCriteria.getTargets().stream().map(TargetObject::getTopologyObject).map(
+                        SchemaRegistry::getEntityTypeByName).filter(Objects::nonNull).toList());
+            }
+            if (resolvingTopologyObjectType.isResolveRelationships()) {
+                result.addAll(filterCriteria.getTargets().stream().map(TargetObject::getTopologyObject).map(
+                        SchemaRegistry::getRelationTypeByName).filter(Objects::nonNull).toList());
+            }
+        } else if (!wildCardInScope) {
+            if (resolvingTopologyObjectType.isResolveEntities()) {
+                result.addAll(nonWildCardsInScope.stream().map(ScopeLogicalBlock::getScopeObject).map(
+                        ScopeObject::getTopologyObject).map(SchemaRegistry::getEntityTypeByName).filter(Objects::nonNull)
+                        .toList());
+            }
+            if (resolvingTopologyObjectType.isResolveRelationships()) {
+                result.addAll(nonWildCardsInScope.stream().map(ScopeLogicalBlock::getScopeObject).map(
+                        ScopeObject::getTopologyObject).map(SchemaRegistry::getRelationTypeByName).filter(Objects::nonNull)
+                        .toList());
+            }
+        } else {
+            if (resolvingTopologyObjectType.isResolveEntities()) {
+                result.addAll(SchemaRegistry.getEntityTypesByDomain(domain));
+            }
+            if (resolvingTopologyObjectType.isResolveRelationships()) {
+                result.addAll(SchemaRegistry.getRelationTypesByDomain(domain));
+            }
+        }
+        return result;
+    }
+
+    private void filterPossibleTypesInTarget(InnerFilterCriteria filterCriteria, List<Persistable> possibleTypes) {
+        for (TargetObject targetObject : filterCriteria.getTargets().stream().filter(t -> t.getTopologyObject().equals("*"))
+                .toList()) {
+            if (targetObject.getContainer().equals(ContainerType.ATTRIBUTES)) {
+                for (String parameter : targetObject.getParams()) {
+                    possibleTypes.removeIf(t -> !t.getAttributeNames().contains(parameter));
+                }
+            }
+        }
+    }
+
+    private void filterPossibleTypesInScope(List<ScopeLogicalBlock> wildCardsInScope, List<Persistable> possibleTypes) {
+        for (ScopeObject scopeObject : wildCardsInScope.stream().map(ScopeLogicalBlock::getScopeObject).toList()) {
+            if (scopeObject.getContainer().equals(ContainerType.ATTRIBUTES)) {
+                if (!scopeObject.getInnerContainer().isEmpty()) {
+                    possibleTypes.removeIf(t -> !t.getAttributeNames().contains(scopeObject.getInnerContainer().get(0)));
+                } else {
+                    possibleTypes.removeIf(t -> !t.getAttributeNames().contains(scopeObject.getLeaf()));
+                }
+            }
+            if (scopeObject.getContainer().equals(ContainerType.ASSOCIATION)) {
+                filterPossibleTypesInScopeByAssociations(possibleTypes, scopeObject);
+            }
+        }
+    }
+
+    private void filterPossibleTypesInScopeByAssociations(List<Persistable> possibleTypes, ScopeObject scopeObject) {
+        String innerContainer = scopeObject.getInnerContainer().get(0);
+        List<Persistable> entityTypesCopy = new ArrayList<>(possibleTypes);
+        for (Persistable t : entityTypesCopy) {
+            if ((t instanceof RelationType && !(SchemaRegistry.getRelationTypeByName(t.getName()).getASideAssociation()
+                    .getName().equals(innerContainer) || SchemaRegistry.getRelationTypeByName(t.getName())
+                            .getBSideAssociation().getName().equals(
+                                    innerContainer))) || (t instanceof EntityType && !SchemaRegistry
+                                            .getAssociationNamesByEntityName(t.getName()).contains(innerContainer))) {
+                possibleTypes.remove(t);
+            }
+        }
+    }
+
+    private void resolveTargets(InnerFilterCriteria filterCriteria, boolean isAllParamRequired,
+            List<Persistable> possibleTypes) {
+        List<TargetObject> resolvedTargets = new ArrayList<>();
+        for (TargetObject targetObject : filterCriteria.getTargets()) {
+            if (targetObject.getTopologyObject().equals("*")) {
+                possibleTypes.forEach(t -> resolvedTargets.add(TargetObject.builder(t.getName()).container(targetObject
+                        .getContainer()).params(targetObject.getParams()).isAllParamQueried(isAllParamRequired).build()));
+            } else {
+                resolvedTargets.add(targetObject);
+            }
+        }
+        filterCriteria.setTargets(resolvedTargets);
+    }
+
+    private LogicalBlock copyTree(LogicalBlock logicalBlock, String topologyObject) {
+        if (logicalBlock instanceof AndLogicalBlock andLogicalBlock) {
+            AndLogicalBlock lb = new AndLogicalBlock();
+            lb.setValid(logicalBlock.isValid());
+            lb.getChildren().addAll(andLogicalBlock.getChildren().stream().map(child -> copyTree(child, topologyObject))
+                    .toList());
+            return lb;
+        }
+        if (logicalBlock instanceof OrLogicalBlock orLogicalBlock) {
+            OrLogicalBlock lb = new OrLogicalBlock();
+            lb.setValid(logicalBlock.isValid());
+            lb.getChildren().addAll(orLogicalBlock.getChildren().stream().map(child -> copyTree(child, topologyObject))
+                    .toList());
+            return lb;
+        }
+        if (logicalBlock instanceof ScopeLogicalBlock scopeLogicalBlock) {
+            ScopeObject scopeObject = ScopeObject.builder((topologyObject == null || !scopeLogicalBlock.getScopeObject()
+                    .getTopologyObject().equals("*")) ?
+                            scopeLogicalBlock.getScopeObject().getTopologyObject() :
+                            topologyObject).topologyObjectType((topologyObject == null || !scopeLogicalBlock
+                                    .getScopeObject().getTopologyObject().equals("*")) ?
+                                            scopeLogicalBlock.getScopeObject().getTopologyObjectType() :
+                                            TopologyObjectType.UNDEFINED).container(scopeLogicalBlock.getScopeObject()
+                                                    .getContainer()).innerContainer(scopeLogicalBlock.getScopeObject()
+                                                            .getInnerContainer()).leaf(scopeLogicalBlock.getScopeObject()
+                                                                    .getLeaf()).queryFunction(scopeLogicalBlock
+                                                                            .getScopeObject().getQueryFunction()).parameter(
+                                                                                    scopeLogicalBlock.getScopeObject()
+                                                                                            .getParameter()).dataType(
+                                                                                                    scopeLogicalBlock
+                                                                                                            .getScopeObject()
+                                                                                                            .getDataType())
+                    .resolverDataType(scopeLogicalBlock.getScopeObject().getResolverDataType()).build();
+
+            if (scopeObject.getLeaf() != null && scopeObject.getLeaf().equals(ID_COLUMN_NAME) && scopeObject.getContainer()
+                    .equals(ContainerType.ID)) {
+                scopeObject.setLeaf(null);
+            }
+
+            ScopeLogicalBlock lb = new ScopeLogicalBlock(scopeObject);
+            lb.setValid(logicalBlock.isValid());
+            return lb;
+        }
+        return EmptyLogicalBlock.getInstance();
+    }
+
+    private void rebuildBinaryTree(InnerFilterCriteria filterCriteria, List<LogicalBlock> resolvedTrees) {
+        LogicalBlock subTree = resolvedTrees.get(0);
+        for (int i = 1; i < resolvedTrees.size(); i++) {
+            OrLogicalBlock lb = new OrLogicalBlock();
+            lb.getChildren().add(copyTree(subTree, null));
+            lb.getChildren().add(resolvedTrees.get(i));
+            subTree = lb;
+        }
+
+        filterCriteria.setScope(subTree);
     }
 
     /**
@@ -72,23 +420,23 @@ public class BasePathRefinement {
      * @param filterCriteria
      *     the filter criteria
      */
-    public static void resolveUndefinedTopologyObjectTypes(FilterCriteria filterCriteria) {
+    public void resolveUndefinedTopologyObjectTypes(FilterCriteria filterCriteria) {
         resolveUndefinedObjectTypesInTarget(filterCriteria);
         resolveUndefinedObjectTypesInScope(filterCriteria);
     }
 
-    private static void resolveUndefinedObjectTypesInScope(FilterCriteria filterCriteria) {
-        runOnTree(filterCriteria.getScope(), filterCriteria.getDomain(),
-                BasePathRefinement::defineTopologyObjectTypeInScope);
+    private void resolveUndefinedObjectTypesInScope(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> runOnTree(innerFilterCriteria.getScope(),
+                filterCriteria.getDomain(), this::defineTopologyObjectTypeInScope));
     }
 
-    private static void resolveUndefinedObjectTypesInTarget(FilterCriteria filterCriteria) {
-        filterCriteria.getTargets().stream().filter(targetObject -> targetObject.getTopologyObjectType().equals(
-                TopologyObjectType.UNDEFINED)).forEach(targetObject -> defineTopologyObjectTypeForTarget(targetObject,
-                        filterCriteria.getDomain()));
+    private void resolveUndefinedObjectTypesInTarget(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> innerFilterCriteria.getTargets().stream()
+                .filter(targetObject -> targetObject.getTopologyObjectType().equals(TopologyObjectType.UNDEFINED)).forEach(
+                        targetObject -> defineTopologyObjectTypeForTarget(targetObject, filterCriteria.getDomain())));
     }
 
-    private static void defineTopologyObjectTypeInScope(ScopeLogicalBlock scopeLogicalBlock, String domain) {
+    private void defineTopologyObjectTypeInScope(ScopeLogicalBlock scopeLogicalBlock, String domain) {
         if (scopeLogicalBlock.getScopeObject().getTopologyObjectType().equals(TopologyObjectType.UNDEFINED)) {
             boolean isResolved = false;
             if (SchemaRegistry.getEntityNamesByDomain(domain).contains(scopeLogicalBlock.getScopeObject()
@@ -111,7 +459,7 @@ public class BasePathRefinement {
         }
     }
 
-    private static void defineTopologyObjectTypeForTarget(TargetObject targetObject, String domain) {
+    private void defineTopologyObjectTypeForTarget(TargetObject targetObject, String domain) {
         boolean isResolved = false;
         if (SchemaRegistry.getEntityNamesByDomain(domain).contains(targetObject.getTopologyObject())) {
             targetObject.setTopologyObjectType(TopologyObjectType.ENTITY);
@@ -138,32 +486,38 @@ public class BasePathRefinement {
      * @param filterCriteria
      *     the filter criteria
      */
-    public static void validateContainers(FilterCriteria filterCriteria) {
-        filterCriteria.getTargets().stream().forEach(targetObject -> validateContainerWithMatchingParameters(targetObject
-                .getContainer(), targetObject.getParams(), targetObject.getTopologyObject(), targetObject
-                        .getTopologyObjectType(), Collections.emptyList()));
-        runOnTree(filterCriteria.getScope(), filterCriteria.getDomain(), BasePathRefinement::validateScope);
+    public void validateContainers(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> innerFilterCriteria.getTargets().forEach(
+                targetObject -> validateContainerWithMatchingParameters(targetObject.getContainer(), targetObject
+                        .getParams(), targetObject.getTopologyObject(), targetObject.getTopologyObjectType(), Collections
+                                .emptyList())));
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> runOnTree(innerFilterCriteria.getScope(),
+                filterCriteria.getDomain(), this::validateScope));
     }
 
-    private static void validateScope(LogicalBlock logicalBlock, String domain) {
+    private void validateScope(LogicalBlock logicalBlock, String domain) {
         ScopeObject scopeObject = ((ScopeLogicalBlock) logicalBlock).getScopeObject();
-        validateContainerWithMatchingParameters(scopeObject.getContainer(), new ArrayList<>(Arrays.asList(scopeObject
-                .getLeaf())), scopeObject.getTopologyObject(), scopeObject.getTopologyObjectType(), scopeObject
+        validateContainerWithMatchingParameters(scopeObject.getContainer(), new ArrayList<>(Collections.singletonList(
+                scopeObject.getLeaf())), scopeObject.getTopologyObject(), scopeObject.getTopologyObjectType(), scopeObject
                         .getInnerContainer());
     }
 
-    private static void validateContainerWithMatchingParameters(ContainerType containerType, List<String> params,
+    private void validateContainerWithMatchingParameters(ContainerType containerType, List<String> params,
             String topologyObject, TopologyObjectType topologyObjectType, List<String> innerContainer) {
         switch (containerType) {
             case ID:
-                if (!params.isEmpty()) {
+                if (!params.isEmpty() && !(params.size() == 1 && params.contains(null))) {
                     throw TiesPathException.grammarError("Adding parameters for id container is not supported");
                 }
                 break;
             case ATTRIBUTES:
-                checkAttributesOfTopologyObject(params, topologyObject, topologyObjectType);
+                if (innerContainer.isEmpty()) {
+                    checkAttributesOfTopologyObject(params, topologyObject, topologyObjectType);
+                } else {
+                    checkAttributesOfTopologyObject(List.of(innerContainer.get(0)), topologyObject, topologyObjectType);
+                }
                 break;
-            case SOURCE_IDS:
+            case SOURCE_IDS, CLASSIFIERS:
                 checkSourceIdTopologyObject(params, topologyObject);
                 break;
             case ASSOCIATION:
@@ -174,101 +528,197 @@ public class BasePathRefinement {
         }
     }
 
-    private static void checkAssociationTopologyObject(List<String> params, String topologyObject,
+    private void checkAssociationTopologyObject(List<String> params, String topologyObject,
             TopologyObjectType topologyObjectType, List<String> innerContainer) {
         if (innerContainer.isEmpty()) {
             throw TiesPathException.grammarError("Missing association name");
         }
         RelationType relation;
         switch (topologyObjectType) {
-            case ENTITY:
-                relation = SchemaRegistry.getRelationTypes().stream().filter(relationType -> (relationType.getASide()
-                        .getName().equals(topologyObject) && relationType.getBSideAssociation().getName().equals(
-                                innerContainer.get(0))) || (relationType.getBSide().getName().equals(
-                                        topologyObject) && relationType.getASideAssociation().getName().equals(
-                                                innerContainer.get(0)))).findFirst().orElseThrow(() -> TiesPathException
-                                                        .invalidAssociation(topologyObject, innerContainer.get(0)));
-                break;
-            case RELATION:
+            case ENTITY -> relation = SchemaRegistry.getRelationTypes().stream().filter(relationType -> (relationType
+                    .getASide().getName().equals(topologyObject) && relationType.getASideAssociation().getName().equals(
+                            innerContainer.get(0))) || (relationType.getBSide().getName().equals(
+                                    topologyObject) && relationType.getBSideAssociation().getName().equals(innerContainer
+                                            .get(0)))).findFirst().orElseThrow(() -> TiesPathException.invalidAssociation(
+                                                    topologyObject, innerContainer.get(0)));
+            case RELATION -> {
                 relation = SchemaRegistry.getRelationTypeByName(topologyObject);
                 if (!relation.getASideAssociation().getName().equals(innerContainer.get(0)) && !relation
                         .getBSideAssociation().getName().equals(innerContainer.get(0))) {
                     throw TiesPathException.invalidAssociation(topologyObject, innerContainer.get(0));
                 }
-
-                break;
-            default:
-                throw TiesPathException.containerValidationWithUndefinedTopologyObjectType(topologyObject);
+            }
+            default -> throw TiesPathException.containerValidationWithUndefinedTopologyObjectType(topologyObject);
         }
         if (!params.isEmpty() && params.get(0) != null) {
             checkParamsForAssociation(relation, innerContainer.get(0), params);
         }
     }
 
-    private static void checkParamsForAssociation(RelationType relationType, String associationName, List<String> params) {
+    private void checkParamsForAssociation(RelationType relationType, String associationName, List<String> params) {
         if ((relationType.getASideAssociation().getName().equals(associationName) && !params.stream().allMatch(
-                param -> relationType.getASide().getFields().containsKey(param))) || (relationType.getBSideAssociation()
-                        .getName().equals(associationName) && !params.stream().allMatch(param -> relationType.getBSide()
+                param -> relationType.getBSide().getFields().containsKey(param))) || (relationType.getBSideAssociation()
+                        .getName().equals(associationName) && !params.stream().allMatch(param -> relationType.getASide()
                                 .getFields().containsKey(param)))) {
             throw TiesPathException.invalidParamsForAssociation(associationName);
         }
     }
 
-    private static void checkSourceIdTopologyObject(List<String> params, String topologyObject) {
-        if (params.stream().anyMatch(param -> !param.equals(ITEMS))) {
+    private void checkSourceIdTopologyObject(List<String> params, String topologyObject) {
+        if (params.stream().anyMatch(param -> !param.equals(ITEM))) {
             throw TiesPathException.sourceIdNameError(topologyObject);
         }
     }
 
-    private static void checkAttributesOfTopologyObject(List<String> params, String topologyObject,
+    private void checkAttributesOfTopologyObject(List<String> params, String topologyObject,
             TopologyObjectType topologyObjectType) {
         switch (topologyObjectType) {
-            case ENTITY:
+            case ENTITY -> {
                 EntityType entityType = SchemaRegistry.getEntityTypeByName(topologyObject);
                 List<String> notMatchingParams = params.stream().filter(a -> !entityType.getAttributeNames().contains(a))
                         .toList();
                 if (!notMatchingParams.isEmpty()) {
                     throw TiesPathException.columnNamesError(topologyObject, notMatchingParams);
                 }
-                break;
-            case RELATION:
+            }
+            case RELATION -> {
                 RelationType relationType = SchemaRegistry.getRelationTypeByName(topologyObject);
                 List<String> notMatchingParams2 = params.stream().filter(a -> !relationType.getAttributes().containsKey(a))
                         .toList();
                 if (!notMatchingParams2.isEmpty()) {
                     throw TiesPathException.columnNamesError(topologyObject, notMatchingParams2);
                 }
+            }
+        }
+    }
+
+    /**
+     * Validate scope parameters' data type.
+     * If resolverDataType does not match the accepted dataType of the attribute/id/source_id etc., error is thrown.
+     * resolverDataType: INTEGER - accepted dataTypes: INTEGER, BIGINT, DECIMAL
+     * resolverDataType: STRING - accepted dataTypes: all other
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void validateScopeParametersDataType(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> runOnTree(innerFilterCriteria.getScope(),
+                filterCriteria.getDomain(), this::validateParameterOfScopeObject));
+    }
+
+    private void validateParameterOfScopeObject(ScopeLogicalBlock scopeLogicalBlock, String domain) {
+        ScopeObject so = scopeLogicalBlock.getScopeObject();
+        switch (so.getContainer()) {
+            case ATTRIBUTES:
+                validateAttributesParameter(so);
+                break;
+            case ID:
+                validateIdParameter(so);
+                break;
+            case ASSOCIATION, RELATION:
+                validateAssociationAndRelationParameter(so);
+                break;
+            case SOURCE_IDS:
+                validateSourceIdsParameter(so);
+                break;
+            case CLASSIFIERS:
+                validateClassifiersParameter(so);
+                break;
+            case DECORATORS:
+                validateDecoratorsParameter(so);
                 break;
             default:
                 break;
         }
     }
 
-    @SuppressWarnings("squid:S4144")
-    public static void validateScopeParametersDataType(FilterCriteria filterCriteria) {
-        // can parameter parse as the given type, check given data type and stored dataType
-        // throw error
-        log.trace(filterCriteria.toString());
-        throw new NotImplementedException(filterCriteria.toString());
+    private void validateAttributesParameter(final ScopeObject so) {
+        if (so.getInnerContainer().isEmpty()) {
+            so.setDataType(SchemaRegistry.getEntityTypeByName(so.getTopologyObject()).getFields().get(so.getLeaf()));
+            compareResolverDataTypeToDataType(so);
+        } else {
+            setDataTypeForComplexAttribute(so);
+        }
     }
 
-    //// End of syntax check
+    private void validateIdParameter(final ScopeObject so) {
+        if (so.getResolverDataType().equals(ResolverDataType.INTEGER)) {
+            throw TiesPathException.grammarError("Data is given in invalid datatype in scopeFilter");
+        }
+        so.setDataType(DataType.PRIMITIVE);
+    }
+
+    private void validateAssociationAndRelationParameter(final ScopeObject so) {
+        if (so.getLeaf() != null && !ID_COLUMN_NAME.equals(so.getLeaf())) {
+            throw TiesPathException.grammarError("Only id condition can be queried in case of association container");
+        } else if (so.getResolverDataType().equals(ResolverDataType.INTEGER)) {
+            throw TiesPathException.grammarError("Invalid data type provided for scopeFilter");
+        } else if (so.getResolverDataType().equals(ResolverDataType.STRING)) {
+            so.setDataType(DataType.PRIMITIVE);
+        }
+    }
+
+    private void validateSourceIdsParameter(final ScopeObject so) {
+        if (so.getResolverDataType().equals(ResolverDataType.INTEGER)) {
+            throw TiesPathException.grammarError("Invalid data type provided for scopeFilter");
+        }
+        so.setDataType(DataType.PRIMITIVE);
+    }
+
+    private void validateClassifiersParameter(final ScopeObject so) {
+        if (so.getResolverDataType().equals(ResolverDataType.INTEGER)) {
+            throw TiesPathException.grammarError("Invalid data type provided for scopeFilter");
+        }
+        so.setDataType(DataType.PRIMITIVE);
+        Classifiers classifier = Classifiers.builder().data(List.of(so.getParameter())).build();
+        consumerDataValidator.validate(classifier);
+    }
+
+    private void validateDecoratorsParameter(final ScopeObject so) {
+        Object value = null;
+        if (so.getResolverDataType().equals(ResolverDataType.INTEGER)) {
+            so.setDataType(BIGINT);
+            value = Integer.valueOf(so.getParameter());
+        } else {
+            so.setDataType(DataType.PRIMITIVE);
+            value = so.getParameter();
+        }
+        Decorators decorator = Decorators.builder().data(Map.of(so.getLeaf(), value)).build();
+        consumerDataValidator.validate(decorator);
+    }
+
+    private void setDataTypeForComplexAttribute(final ScopeObject scopeObject) {
+        switch (scopeObject.getResolverDataType()) {
+            case INTEGER -> scopeObject.setDataType(INTEGER);
+            case STRING -> scopeObject.setDataType(PRIMITIVE);
+            default -> throw new IllegalStateException("Invalid data type for complex attribute");
+        }
+    }
+
+    private void compareResolverDataTypeToDataType(final ScopeObject scopeObject) {
+        List<DataType> numericDataTypes = List.of(INTEGER, BIGINT, DECIMAL);
+        if ((scopeObject.getResolverDataType().equals(ResolverDataType.INTEGER) && !numericDataTypes.contains(scopeObject
+                .getDataType())) || (scopeObject.getResolverDataType().equals(ResolverDataType.STRING) && numericDataTypes
+                        .contains(scopeObject.getDataType()))) {
+            throw TiesPathException.grammarError("Data is given in invalid datatype in scopeFilter");
+        }
+    }
 
     /**
      * Check if target's topologyObjects match with scope's topologyObjects.
      *
      * @param filterCriteria
+     *     - filter criteria
      *
      */
-    @SuppressWarnings("squid:S4144")
-    public static void checkIfTargetMatchesWithScope(FilterCriteria filterCriteria) {
+    public void checkIfTargetMatchesWithScope(InnerFilterCriteria filterCriteria, String domain) {
         if (filterCriteria.getScope() instanceof EmptyLogicalBlock || filterCriteria.getTargets().isEmpty()) {
             return;
         }
 
         Set<String> scopeTopologyObjects = new HashSet<>();
-        runOnTree(filterCriteria.getScope(), filterCriteria.getDomain(), (ScopeLogicalBlock lb,
-                String domain) -> scopeTopologyObjects.add(lb.getScopeObject().getTopologyObject()));
+        runOnTree(filterCriteria.getScope(), domain, (ScopeLogicalBlock lb, String dom) -> scopeTopologyObjects.add(lb
+                .getScopeObject().getTopologyObject()));
 
         Set<String> targetTopologyObjects = filterCriteria.getTargets().stream().map(TargetObject::getTopologyObject)
                 .collect(Collectors.toSet());
@@ -283,16 +733,123 @@ public class BasePathRefinement {
         }
     }
 
-    @SuppressWarnings("squid:S4144")
-    public static boolean validateQuery(FilterCriteria filterCriteria) {
-        // remove invalid LB, when an AND block has an invalid LB set the AND block to invalid
-        // when an or has an invalid block, replace the OR block with the other child
-        // throw error when the last LB became invalid
-        log.trace(filterCriteria.toString());
-        throw new NotImplementedException(filterCriteria.toString());
+    /**
+     * Split inner filter criteria to multiple inner filter criteria and use union instance of or logical block
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void splitFilterCriteria(FilterCriteria filterCriteria) {
+        Map<String, InnerFilterCriteria> innerFilterCriteriaMap = new HashMap<>();
+
+        for (InnerFilterCriteria base : filterCriteria.getFilterCriteriaList()) {
+            for (TargetObject targetObject : base.getTargets()) {
+                if (!innerFilterCriteriaMap.containsKey(targetObject.getTopologyObject())) {
+                    innerFilterCriteriaMap.put(targetObject.getTopologyObject(), InnerFilterCriteria.builder().targets(
+                            new ArrayList<>()).build());
+                }
+                innerFilterCriteriaMap.get(targetObject.getTopologyObject()).getTargets().add(targetObject);
+            }
+        }
+
+        for (InnerFilterCriteria base : filterCriteria.getFilterCriteriaList()) {
+            List<String> types = base.getTargets().stream().map(TargetObject::getTopologyObject).toList();
+            for (String type : types) {
+                innerFilterCriteriaMap.get(type).setScope(generateCutTree(base.getScope(), type));
+            }
+        }
+
+        filterCriteria.setFilterCriteriaList(new ArrayList<>(innerFilterCriteriaMap.values()));
+    }
+
+    /**
+     * Validates the binary tree of LogicalBlocks (LB) in FilterCriteria based on isValid boolean of the objects. 
+     * Remove invalid LB, when an AND block has an invalid LB set the AND block to invalid
+     * When an OR has an invalid block, replace the OR block with the valid child element.
+     * Throw an error when the last LB became invalid.
+     *
+     * @param filterCriteria
+     *     the filter criteria
+     */
+    public void validateQuery(FilterCriteria filterCriteria) {
+        filterCriteria.getFilterCriteriaList().forEach(innerFilterCriteria -> {
+            innerFilterCriteria.setScope(traverseTree(innerFilterCriteria.getScope()));
+            if (!innerFilterCriteria.getScope().isValid()) {
+                throw TiesPathException.invalidQueryError();
+            }
+        });
+    }
+
+    private LogicalBlock traverseTree(LogicalBlock logicalBlock) {
+        if (logicalBlock instanceof AndOrLogicalBlock andOrLogicalBlock && andOrLogicalBlock.getChildren().size() == 2) {
+            andOrLogicalBlock.getChildren().set(0, traverseTree(andOrLogicalBlock.getChildren().get(0)));
+            andOrLogicalBlock.getChildren().set(1, traverseTree(andOrLogicalBlock.getChildren().get(1)));
+            if (andOrLogicalBlock.getChildren().stream().anyMatch(child -> !child.isValid())) {
+                if (logicalBlock instanceof OrLogicalBlock orLogicalBlock) {
+                    Optional<LogicalBlock> validLogicalBlock = orLogicalBlock.getChildren().stream().filter(
+                            LogicalBlock::isValid).findFirst();
+                    return validLogicalBlock.orElseGet(() -> invalidateLogicalBlock(orLogicalBlock));
+                }
+                if (andOrLogicalBlock.getChildren().stream().anyMatch(child -> !child.isValid())) {
+                    andOrLogicalBlock.getChildren().removeIf(child -> !child.isValid());
+                    return invalidateLogicalBlock(andOrLogicalBlock);
+                }
+            }
+        }
+        return logicalBlock;
+    }
+
+    private LogicalBlock generateCutTree(LogicalBlock logicalBlock, String type) {
+        if (!logicalBlock.isValid() || logicalBlock instanceof EmptyLogicalBlock) {
+            return EmptyLogicalBlock.getInstance();
+        }
+        if (logicalBlock instanceof AndLogicalBlock andLogicalBlock) {
+            return getAndOrLogicalBlock(type, andLogicalBlock, AndLogicalBlock::new);
+        }
+        if (logicalBlock instanceof OrLogicalBlock orLogicalBlock) {
+            return getAndOrLogicalBlock(type, orLogicalBlock, OrLogicalBlock::new);
+        }
+        if (logicalBlock instanceof ScopeLogicalBlock scopeLogicalBlock) {
+            if (!scopeLogicalBlock.getScopeObject().getTopologyObject().equals(type)) {
+                return EmptyLogicalBlock.getInstance();
+            }
+            ScopeObject response = ScopeObject.builder(type).topologyObjectType(scopeLogicalBlock.getScopeObject()
+                    .getTopologyObjectType()).container(scopeLogicalBlock.getScopeObject().getContainer()).innerContainer(
+                            scopeLogicalBlock.getScopeObject().getInnerContainer()).leaf(scopeLogicalBlock.getScopeObject()
+                                    .getLeaf()).queryFunction(scopeLogicalBlock.getScopeObject().getQueryFunction())
+                    .parameter(scopeLogicalBlock.getScopeObject().getParameter()).dataType(scopeLogicalBlock
+                            .getScopeObject().getDataType()).resolverDataType(scopeLogicalBlock.getScopeObject()
+                                    .getResolverDataType()).build();
+
+            return new ScopeLogicalBlock(response);
+        }
+        return EmptyLogicalBlock.getInstance();
     }
 
-    public static void runOnTree(LogicalBlock logicalBlock, String domain, BiConsumer<ScopeLogicalBlock, String> func) {
+    private LogicalBlock getAndOrLogicalBlock(String type, AndOrLogicalBlock andLogicalBlock,
+            Supplier<AndOrLogicalBlock> constructor) {
+        LogicalBlock left = generateCutTree(andLogicalBlock.getChildren().get(0), type);
+        LogicalBlock right = generateCutTree(andLogicalBlock.getChildren().get(1), type);
+
+        if (!left.isValid() || left instanceof EmptyLogicalBlock) {
+            return right;
+        }
+        if (!right.isValid() || right instanceof EmptyLogicalBlock || left.equals(right)) {
+            return left;
+        }
+
+        AndOrLogicalBlock response = constructor.get();
+        response.getChildren().add(left);
+        response.getChildren().add(right);
+        return response;
+    }
+
+    private LogicalBlock invalidateLogicalBlock(LogicalBlock logicalBlock) {
+        logicalBlock.setValid(false);
+        return logicalBlock;
+    }
+
+    public void runOnTree(LogicalBlock logicalBlock, String domain, BiConsumer<ScopeLogicalBlock, String> func) {
         if (!logicalBlock.isValid() || logicalBlock instanceof EmptyLogicalBlock) {
             return;
         }
@@ -303,4 +860,28 @@ public class BasePathRefinement {
         func.accept((ScopeLogicalBlock) logicalBlock, domain);
     }
 
+    private void applyRelationshipCriteria(FilterCriteria filterCriteria) {
+        if (filterCriteria.getResolvingTopologyObjectType().equals(
+                FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP)) {
+            filterCriteria.getFilterCriteriaList().forEach(criteria -> {
+                if (criteria.getScope() instanceof EmptyLogicalBlock) {
+                    criteria.setScope(buildScopeLogicalBlockForRelationship(criteria));
+                } else if (criteria.getScope()instanceof AndOrLogicalBlock andOrLogicalBlock) {
+                    AndOrLogicalBlock aolb = new AndLogicalBlock();
+                    aolb.setChildren(List.of(andOrLogicalBlock, buildScopeLogicalBlockForRelationship(criteria)));
+                    criteria.setScope(aolb);
+                } else if (criteria.getScope()instanceof ScopeLogicalBlock scopeLogicalBlock) {
+                    AndOrLogicalBlock aolb = new AndLogicalBlock();
+                    aolb.setChildren(List.of(scopeLogicalBlock, buildScopeLogicalBlockForRelationship(criteria)));
+                    criteria.setScope(aolb);
+                }
+            });
+        }
+    }
+
+    private ScopeLogicalBlock buildScopeLogicalBlockForRelationship(InnerFilterCriteria criteria) {
+        return new ScopeLogicalBlock(ScopeObject.builder(criteria.getTargets().get(0).getTopologyObject())
+                .topologyObjectType(TopologyObjectType.RELATION).queryFunction(QueryFunction.NOT_NULL).container(
+                        ContainerType.ID).resolverDataType(ResolverDataType.STRING).dataType(PRIMITIVE).build());
+    }
 }
index 19e5ef3..8ac102d 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.refiner;
 
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jooq.Field;
+import org.jooq.JSONB;
+import org.jooq.OrderField;
+import org.jooq.Record;
+import org.jooq.SelectConditionStep;
+import org.jooq.SelectField;
+import org.jooq.SelectOrderByStep;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
-import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
 import lombok.experimental.UtilityClass;
-import org.apache.commons.lang3.NotImplementedException;
-import org.jooq.Condition;
 import org.jooq.SelectJoinStep;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.InnerFilterCriteria;
+import org.oran.smo.teiv.schema.DataType;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.select;
+import static org.jooq.impl.DSL.selectCount;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+
+@Slf4j
 @UtilityClass
+@SuppressWarnings({ "rawtypes", "unchecked" })
 public class PathToJooqRefinement {
 
     /**
@@ -35,21 +57,128 @@ public class PathToJooqRefinement {
      *
      * @param filterCriteria
      *     the InnerLanguageDTO
-     * @return the select join step
+     * @return the query
      */
-    public static SelectJoinStep toJooq(FilterCriteria filterCriteria) {
-        throw new NotImplementedException(filterCriteria.toString());
+    public static SelectOrderByStep<Record> toJooq(FilterCriteria filterCriteria, int offset, int limit) {
+        SelectOrderByStep<Record> basicQuery = createBasicQuery(filterCriteria, false);
+        SelectOrderByStep<Record> countQuery = createBasicQuery(filterCriteria, true);
+
+        List<Map.Entry<SelectField, Map<SelectField, DataType>>> selectList = new ArrayList<>(filterCriteria.getSelects()
+                .entrySet());
+
+        return createQueryWithCount(selectList, basicQuery, countQuery, offset, limit);
     }
 
-    /**
-     * Converts LogicalBlock to JooQ query part
-     *
-     * @param logicalBlock
-     *     the LogicalBlock
-     * @return the condition
-     */
-    public static Condition logicalBlockToJooq(LogicalBlock logicalBlock) {
-        // convert LB to JOOQ condition recursive!
-        throw new NotImplementedException(logicalBlock.toString());
+    private static SelectOrderByStep<Record> createBasicQuery(FilterCriteria filterCriteria, boolean countMode) {
+        Map<SelectField, DataType> fields = new HashMap<>();
+        if (countMode) {
+            for (SelectField id : filterCriteria.getSelects().keySet()) {
+                fields.put(id, DataType.PRIMITIVE);
+            }
+        } else {
+            for (Map<SelectField, DataType> fieldSet : filterCriteria.getSelects().values()) {
+                fields.putAll(fieldSet);
+            }
+        }
+
+        SelectOrderByStep<Record> query = createInnerQuery(filterCriteria.getFilterCriteriaList().get(0), fields,
+                countMode);
+
+        for (int i = 1; i < filterCriteria.getFilterCriteriaList().size(); i++) {
+            query = query.unionAll(createInnerQuery(filterCriteria.getFilterCriteriaList().get(i), fields, countMode));
+        }
+
+        return query;
+    }
+
+    private static SelectOrderByStep<Record> createInnerQuery(InnerFilterCriteria filterCriteria,
+            Map<SelectField, DataType> otherFields, boolean countMode) {
+        Set<SelectField> selfFields = new HashSet<>();
+        List<SelectField> resolvedFields = new ArrayList<>();
+
+        for (Map<SelectField, DataType> fieldSet : filterCriteria.getSelects().values()) {
+            selfFields.addAll(fieldSet.keySet());
+        }
+
+        for (Map.Entry<SelectField, DataType> field : otherFields.entrySet()) {
+            if (selfFields.contains(field.getKey())) {
+                resolvedFields.add(field.getKey());
+            } else if (field.getValue() == DataType.CONTAINER) {
+                resolvedFields.add(field("null::jsonb", JSONB.class).as(field.getKey().getName()));
+            } else if (field.getValue() == DataType.INTEGER) {
+                resolvedFields.add(field("null::integer").as(field.getKey().getName()));
+            } else if (field.getValue() == DataType.BIGINT) {
+                resolvedFields.add(field("null::bigint").as(field.getKey().getName()));
+            } else if (field.getValue() == DataType.DECIMAL) {
+                resolvedFields.add(field("null::numeric").as(field.getKey().getName()));
+            } else {
+                resolvedFields.add(field("null").as(field.getKey().getName()));
+            }
+        }
+
+        SelectJoinStep<Record> query = select(resolvedFields).from(filterCriteria.getTableFromTarget(filterCriteria
+                .getTargets().get(0)));
+
+        List<Pair<String, Field>> joinConditions = new ArrayList<>(filterCriteria.getJoinCondition());
+
+        for (int i = 0; i < joinConditions.size(); i++) {
+            query = query.join(joinConditions.get(i).getLeft()).on(joinConditions.get(i).getRight());
+        }
+
+        SelectConditionStep<Record> conditionStep = query.where(filterCriteria.getCondition());
+        if (countMode) {
+            return conditionStep;
+        } else {
+            return (SelectOrderByStep) conditionStep.orderBy(filterCriteria.getSelects().keySet().stream().map(i -> field(i)
+                    .asc()).toList().toArray(new OrderField[0]));
+        }
+    }
+
+    private static SelectOrderByStep<Record> createQueryWithCount(
+            List<Map.Entry<SelectField, Map<SelectField, DataType>>> selectList, SelectOrderByStep<Record> basicQuery,
+            SelectOrderByStep<Record> countQuery, int offset, int limit) {
+        List<SelectField> fields = new ArrayList<>();
+        for (Map.Entry<SelectField, Map<SelectField, DataType>> fieldSet : selectList) {
+            for (Map.Entry<SelectField, DataType> field : fieldSet.getValue().entrySet()) {
+                if (field.getValue() == DataType.CONTAINER) {
+                    fields.add(field(String.format(QUOTED_STRING, field.getKey().getName()), JSONB.class));
+                } else {
+                    fields.add(field(String.format(QUOTED_STRING, field.getKey().getName())));
+                }
+            }
+        }
+
+        List<SelectField> fieldsWithNullCount = new ArrayList<>(fields);
+        fieldsWithNullCount.add(field("null").as("count"));
+
+        List<SelectField> nullFieldsWithCount = getNulledFields(selectList);
+        nullFieldsWithCount.add(field(selectCount().from(countQuery)).as("count"));
+
+        return select(nullFieldsWithCount).unionAll(select(fieldsWithNullCount).from(basicQuery).limit(offset, limit));
+    }
+
+    private static List<SelectField> getNulledFields(List<Map.Entry<SelectField, Map<SelectField, DataType>>> selectList) {
+        List<SelectField> nulledFields = new ArrayList<>();
+        for (int i = 0; i < selectList.size(); i++) {
+            addNullFields(selectList, nulledFields, i);
+        }
+        return nulledFields;
+    }
+
+    private static void addNullFields(List<Map.Entry<SelectField, Map<SelectField, DataType>>> selectList,
+            List<SelectField> nulledFields, int i) {
+        for (SelectField field : selectList.get(i).getValue().keySet()) {
+            if (selectList.get(i).getValue().get(field) == DataType.CONTAINER) {
+                nulledFields.add(field("null::jsonb", JSONB.class).as(field.getName()));
+            } else if (selectList.get(i).getValue().get(field) == DataType.INTEGER) {
+                nulledFields.add(field("null::integer").as(field.getName()));
+            } else if (selectList.get(i).getValue().get(field) == DataType.BIGINT) {
+                nulledFields.add(field("null::bigint").as(field.getName()));
+            } else if (selectList.get(i).getValue().get(field) == DataType.DECIMAL) {
+                nulledFields.add(field("null::numeric").as(field.getName()));
+            } else {
+                nulledFields.add(field("null").as(field.getName()));
+            }
+        }
     }
 }
index 506656f..62b199c 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.resolver;
 
-import java.util.List;
-
-import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-import jakarta.annotation.Nullable;
-import lombok.NonNull;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.oran.smo.teiv.antlr4.tiesPathParser;
+import org.oran.smo.teiv.utils.path.StrictErrorStrategy;
+import org.oran.smo.teiv.utils.path.TiesPathErrorListener;
+import org.oran.smo.teiv.utils.path.TiesPathLexer;
+import org.oran.smo.teiv.utils.path.TiesPathParser;
 
 public interface PathResolver<T> {
 
-    String NULL_ROOT_OBJECT = "*";
-
-    T resolve(String rootObject, @NonNull String filter);
-
-    default String getTopologyObject(String rootObject, List<String> containerNames) {
-        int noOfContainers = containerNames.size();
-        if (noOfContainers > 2) {
-            throw TiesPathException.grammarError("More than two level deep path is not allowed");
-        } else if (noOfContainers == 2) {
-            return getTopologyObjectWhenTwoContainers(rootObject, containerNames.get(0));
+    /**
+     * Resolves the supplied filter.
+     *
+     * @param rootObject
+     *     - root
+     * @param filter
+     *     - filter for resolving
+     * @return T
+     */
+    default T resolve(String rootObject, String filter) {
+        if (filter == null) {
+            return onEmptyFilter(rootObject);
         }
-        return isRootObjectNullOrEmpty(rootObject) ? NULL_ROOT_OBJECT : rootObject;
+        preCheck(rootObject, filter);
+        return process(rootObject, filter);
     }
 
-    default String getTopologyObjectWhenTwoContainers(String rootObject, String firstContainer) {
-        if (isRootObjectNullOrEmpty(rootObject) || firstContainer.equals(rootObject)) {
-            return firstContainer;
-        } else {
-            throw TiesPathException.grammarError(
-                    "Target filter can only contain Root Object types mentioned in the path parameter");
-        }
-    }
+    T onEmptyFilter(String rootObject);
 
-    default boolean isRootObjectNullOrEmpty(String rootObjectType) {
-        return rootObjectType == null || rootObjectType.isEmpty();
-    }
+    void preCheck(String rootObject, String filter);
+
+    T process(String rootObject, String filter);
+
+    default tiesPathParser getTiesPathParser(String filter) {
+        final CharStream inputStream = CharStreams.fromString(filter);
+        final TiesPathLexer tiesPathLexer = new TiesPathLexer(inputStream);
+        final tiesPathParser tiesPathParser = new TiesPathParser(new CommonTokenStream(tiesPathLexer));
+        tiesPathParser.removeErrorListeners();
+        tiesPathParser.addErrorListener(new TiesPathErrorListener());
+        tiesPathParser.setErrorHandler(new StrictErrorStrategy());
 
-    @Nullable
-    default ContainerType getContainerType(List<String> containerNames) {
-        return ContainerType.fromValue(containerNames.get(containerNames.size() - 1));
+        return tiesPathParser;
     }
 }
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.utils.query;
+package org.oran.smo.teiv.exposure.tiespath.resolver;
 
-enum TokenType {
-    AND,
-    OR,
-    NO_TYPE
+public enum ResolverDataType {
+    INTEGER,
+    STRING,
+    NOT_NULL
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ResolverUtil.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ResolverUtil.java
new file mode 100644 (file)
index 0000000..4e4c841
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  ============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.teiv.exposure.tiespath.resolver;
+
+import java.util.List;
+import java.util.Optional;
+
+import lombok.experimental.UtilityClass;
+
+import jakarta.annotation.Nullable;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
+import static org.oran.smo.teiv.utils.TiesConstants.WILDCARD;
+
+@UtilityClass
+public class ResolverUtil {
+
+    public static String getTopologyObject(final String rootObject, final List<String> containerNames) {
+        final int noOfContainers = containerNames.size();
+        final String firstContainer = containerNames.get(0);
+
+        if (isComplexAttribute(containerNames)) {
+            return getTopologyObjectOnComplexAttributeCondition(rootObject, firstContainer);
+        } else if (noOfContainers > 2) {
+            throw TiesPathException.grammarError("More than two level deep path is not allowed");
+        } else if (noOfContainers == 2) {
+            return getTopologyObjectWhenTwoContainers(rootObject, firstContainer);
+        }
+
+        return Optional.ofNullable(rootObject).orElse(WILDCARD);
+    }
+
+    public static boolean isComplexAttribute(final List<String> containerNames) {
+        int index = containerNames.indexOf(ATTRIBUTES);
+        return index != -1 && containerNames.size() - 1 > index;
+    }
+
+    @Nullable
+    public static ContainerType getContainerType(final List<String> containerNames) {
+        return ContainerType.fromValue(containerNames.get(containerNames.size() - 1));
+    }
+
+    private static String getTopologyObjectWhenTwoContainers(final String rootObject, final String firstContainer) {
+        if (null == rootObject || firstContainer.equals(rootObject)) {
+            return firstContainer;
+        } else {
+            throw TiesPathException.grammarError(
+                    "Target/Scope filter can only contain Root Object types mentioned in the path parameter");
+        }
+    }
+
+    private static String getTopologyObjectOnComplexAttributeCondition(String rootObject, String firstContainer) {
+        final ContainerType containerType = ContainerType.fromValue(firstContainer);
+        if (rootObject == null) {
+            if (containerType != null) {
+                return WILDCARD;
+            }
+            return firstContainer;
+        } else {
+            if (rootObject.equals(firstContainer) || containerType != null) {
+                return rootObject;
+            }
+            throw TiesPathException.grammarError(
+                    "Target/Scope filter can only contain Root Object types mentioned in the path parameter");
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeFilterListener.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeFilterListener.java
new file mode 100644 (file)
index 0000000..7e45e37
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ *  ============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.teiv.exposure.tiespath.resolver;
+
+import org.oran.smo.teiv.antlr4.tiesPathBaseListener;
+import org.oran.smo.teiv.antlr4.tiesPathParser;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndOrLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.QueryFunction;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeObject;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.oran.smo.teiv.exposure.tiespath.resolver.ResolverUtil.getContainerType;
+import static org.oran.smo.teiv.exposure.tiespath.resolver.ResolverUtil.getTopologyObject;
+import static org.oran.smo.teiv.exposure.tiespath.resolver.ResolverUtil.isComplexAttribute;
+import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
+import static org.oran.smo.teiv.utils.TiesConstants.WILDCARD;
+
+public class ScopeFilterListener extends tiesPathBaseListener {
+    private final String rootObject;
+    private final List<String> containerNames = new ArrayList<>();
+
+    public LogicalBlock getLogicalBlock() {
+        return Optional.ofNullable(logicalBlock).orElseGet(this::generateLBWithContainers);
+    }
+
+    private LogicalBlock generateLBWithContainers() {
+        final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = ScopeObject.builder(getTopologyObject(this.rootObject,
+                this.containerNames)).queryFunction(QueryFunction.NOT_NULL).innerContainer(new ArrayList<>(Arrays.asList(
+                        this.containerNames.get(containerNames.size() - 1)))).resolverDataType(ResolverDataType.NOT_NULL);
+        addScopeLogicalBlock(scopeObjectBuilder);
+        return this.logicalBlock;
+    }
+
+    private LogicalBlock logicalBlock;
+
+    public ScopeFilterListener(String rootObject) {
+        this.rootObject = rootObject;
+    }
+
+    @Override
+    public void exitContainerName(final tiesPathParser.ContainerNameContext ctx) {
+        final String containerName = ctx.getText();
+        containerNames.add(containerName);
+    }
+
+    @Override
+    public void exitTextFunctionCondition(tiesPathParser.TextFunctionConditionContext ctx) {
+        if (getContainerType(this.containerNames) == ContainerType.ID) {
+            final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = getScopeObjectBuilder(null, QueryFunction.EQ);
+            scopeObjectBuilder.parameter(removeQuotes(ctx.StringLiteral().getText())).resolverDataType(
+                    ResolverDataType.STRING);
+            addScopeLogicalBlock(scopeObjectBuilder);
+        } else {
+            throw TiesPathException.grammarError("text() is supported for ID only");
+        }
+    }
+
+    @Override
+    public void exitContainsTextFunctionCondition(tiesPathParser.ContainsTextFunctionConditionContext ctx) {
+        if (getContainerType(this.containerNames) == ContainerType.ID) {
+            final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = getScopeObjectBuilder(null, QueryFunction.CONTAINS);
+            scopeObjectBuilder.parameter(removeQuotes(ctx.StringLiteral().getText())).resolverDataType(
+                    ResolverDataType.STRING);
+            addScopeLogicalBlock(scopeObjectBuilder);
+        } else {
+            throw TiesPathException.grammarError("text() is supported for ID only");
+        }
+
+    }
+
+    @Override
+    public void exitContainsFunctionCondition(final tiesPathParser.ContainsFunctionConditionContext ctx) {
+        final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = getScopeObjectBuilder(ctx.leafName().getText(),
+                QueryFunction.CONTAINS);
+        scopeObjectBuilder.parameter(removeQuotes(ctx.StringLiteral().getText())).resolverDataType(ResolverDataType.STRING);
+        addScopeLogicalBlock(scopeObjectBuilder);
+    }
+
+    @Override
+    public void exitLeafCondition(final tiesPathParser.LeafConditionContext ctx) {
+        final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = getScopeObjectBuilder(ctx.leafName().getText(),
+                QueryFunction.fromValue(ctx.comparativeOperators().getText()));
+
+        if (ctx.IntegerLiteral() != null) {
+            scopeObjectBuilder.parameter(ctx.IntegerLiteral().getText()).resolverDataType(ResolverDataType.INTEGER);
+        } else if (ctx.StringLiteral() != null) {
+            scopeObjectBuilder.parameter(removeQuotes(ctx.StringLiteral().getText())).resolverDataType(
+                    ResolverDataType.STRING);
+        } else {
+            throw TiesPathException.grammarError("Unsupported comparison value encountered in expression" + ctx.getText());
+        }
+
+        addScopeLogicalBlock(scopeObjectBuilder);
+    }
+
+    private String removeQuotes(String text) {
+        // Remove first occurrence of single or double quotes at the start and end of the string
+        return text.replaceAll("^['\"]+", "").replaceAll("['\"]+$", "");
+    }
+
+    @Override
+    public void exitBooleanOperators(final tiesPathParser.BooleanOperatorsContext ctx) {
+        final AndOrLogicalBlock andOrLogicalBlock;
+        if (ctx.getText().equals("and")) {
+            andOrLogicalBlock = new AndLogicalBlock();
+            andOrLogicalBlock.addChild(this.logicalBlock);
+        } else {
+            andOrLogicalBlock = new OrLogicalBlock();
+            andOrLogicalBlock.addChild(this.logicalBlock);
+        }
+
+        this.logicalBlock = andOrLogicalBlock;
+    }
+
+    @Override
+    public void exitFieldLeaf(final tiesPathParser.FieldLeafContext ctx) {
+        throw TiesPathException.grammarError("Parameter without any condition is not supported in scope filter");
+    }
+
+    private ScopeObject.ScopeObjectBuilder getScopeObjectBuilder(final String leafName, final QueryFunction queryFunction) {
+        final String topologyObject = getTopologyObject(this.rootObject, this.containerNames);
+        final ScopeObject.ScopeObjectBuilder scopeObjectBuilder = ScopeObject.builder(topologyObject).leaf(leafName)
+                .queryFunction(queryFunction);
+
+        Optional.ofNullable(getContainerType(this.containerNames)).ifPresentOrElse(scopeObjectBuilder::container, () -> {
+            if (!isComplexAttribute(containerNames)) {
+                final String container = this.containerNames.get(containerNames.size() - 1);
+                if (topologyObject.equals(container)) {
+                    Optional.ofNullable(getContainerType(List.of(leafName))).ifPresentOrElse(
+                            containerType -> scopeObjectBuilder.container(containerType).leaf(null), () -> {
+                                throw TiesPathException.grammarError(String.format(
+                                        "%s is not a valid leaf for topology object: %s", leafName, rootObject));
+                            });
+                } else {
+                    scopeObjectBuilder.topologyObject(Objects.equals(topologyObject, WILDCARD) ? null : topologyObject)
+                            .innerContainer(new ArrayList<>(Arrays.asList(container)));
+                }
+            } else {
+                scopeObjectBuilder.topologyObject(topologyObject.equals(WILDCARD) ? null : topologyObject).container(
+                        ContainerType.ATTRIBUTES).innerContainer(Collections.unmodifiableList(containerNames.subList(
+                                containerNames.indexOf(ATTRIBUTES) + 1, containerNames.size())));
+            }
+
+        });
+        return scopeObjectBuilder;
+    }
+
+    private void addScopeLogicalBlock(ScopeObject.ScopeObjectBuilder scopeObjectBuilder) {
+        if (this.logicalBlock == null || this.logicalBlock instanceof ScopeLogicalBlock) {
+            this.logicalBlock = new ScopeLogicalBlock(scopeObjectBuilder.build());
+        } else if (this.logicalBlock instanceof AndOrLogicalBlock andOrLogicalBlock) {
+            andOrLogicalBlock.addChild(new ScopeLogicalBlock(scopeObjectBuilder.build()));
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolver.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolver.java
new file mode 100644 (file)
index 0000000..857289d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  ============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.teiv.exposure.tiespath.resolver;
+
+import java.util.Optional;
+
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.oran.smo.teiv.antlr4.tiesPathParser;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.EmptyLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
+import org.oran.smo.teiv.utils.path.exception.PathParsingException;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+import org.springframework.stereotype.Component;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class ScopeResolver implements PathResolver<LogicalBlock> {
+
+    @Override
+    public LogicalBlock onEmptyFilter(String rootObject) {
+        return EmptyLogicalBlock.getInstance();
+    }
+
+    @Override
+    public void preCheck(String rootObject, String filter) {
+        //DO NOTHING
+    }
+
+    @Override
+    public LogicalBlock process(String rootObject, String filter) {
+        final int lastIndexOf = getLastIndexOf(filter);
+        if (lastIndexOf != -1) {
+            final LogicalBlock logicalBlock = getLogicalBlock(rootObject, filter.substring(lastIndexOf + 1));
+            final char c = filter.charAt(lastIndexOf);
+            if (c == ';') {
+                AndLogicalBlock andLogicalBlock = new AndLogicalBlock();
+                andLogicalBlock.addChild(logicalBlock);
+                andLogicalBlock.addChild(resolve(rootObject, filter.substring(0, lastIndexOf)));
+                return andLogicalBlock;
+            } else if (c == '|') {
+                OrLogicalBlock orLogicalBlock = new OrLogicalBlock();
+                orLogicalBlock.addChild(logicalBlock);
+                orLogicalBlock.addChild(resolve(rootObject, filter.substring(0, lastIndexOf)));
+                return orLogicalBlock;
+            }
+        }
+        return getLogicalBlock(rootObject, filter);
+    }
+
+    private int getLastIndexOf(String string) {
+        final boolean containsAnd = string.contains(";");
+        final boolean containsOr = string.contains("|");
+        if (containsAnd && containsOr) {
+            return Math.max(string.lastIndexOf(";"), string.lastIndexOf("|"));
+        } else if (containsAnd) {
+            return string.lastIndexOf(";");
+        } else {
+            return string.lastIndexOf("|");
+        }
+    }
+
+    private LogicalBlock getLogicalBlock(final String rootObject, final String filter) {
+        try {
+            final tiesPathParser tiesPathParser = getTiesPathParser(filter);
+            final ScopeFilterListener scopeFilterListener = new ScopeFilterListener(rootObject);
+            tiesPathParser.addParseListener(scopeFilterListener);
+            tiesPathParser.tiesPath();
+            LogicalBlock logicalBlock = scopeFilterListener.getLogicalBlock();
+            return Optional.ofNullable(logicalBlock).orElseThrow(() -> TiesPathException.grammarError(String.format(
+                    "Unsupported filter token: %s", filter)));
+        } catch (ParseCancellationException | PathParsingException e) {
+            log.error("Parsing error on target {} :", filter, e);
+            throw TiesPathException.grammarError(e.getMessage());
+        }
+    }
+
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/TargetFilterListener.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/tiespath/resolver/TargetFilterListener.java
new file mode 100644 (file)
index 0000000..08e8bcc
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *  ============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.teiv.exposure.tiespath.resolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.antlr.v4.runtime.RuleContext;
+import org.oran.smo.teiv.antlr4.tiesPathBaseListener;
+import org.oran.smo.teiv.antlr4.tiesPathParser;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TargetObject;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+import static org.oran.smo.teiv.exposure.tiespath.resolver.ResolverUtil.getContainerType;
+import static org.oran.smo.teiv.exposure.tiespath.resolver.ResolverUtil.getTopologyObject;
+
+public class TargetFilterListener extends tiesPathBaseListener {
+    private final String rootObject;
+    private final List<String> containerNames = new ArrayList<>();
+    private List<String> attributeNames = new ArrayList<>();
+
+    public TargetFilterListener(String rootObject) {
+        this.rootObject = rootObject;
+    }
+
+    public TargetObject getTargetObject() {
+        if (containerNames.isEmpty()) {
+            //invalid scenario
+            throw TiesException.serverException("Server unknown exception", "Requested query could not be processed", null);
+        }
+        return Optional.ofNullable(getContainerType(this.containerNames)).map(containerType -> {
+            validateIfParamsApplicable(containerType);
+            return TargetObject.builder(getTopologyObject(rootObject, containerNames)).container(containerType).params(
+                    this.attributeNames).build();
+        }).orElseGet(() -> checkAndProcessIfSingleContainerAndValidTopologyObject(rootObject, this.containerNames,
+                this.attributeNames));
+    }
+
+    private void validateIfParamsApplicable(ContainerType containerType) {
+        if (!containerType.isParamAllowedInTargetFilter() && !this.attributeNames.isEmpty()) {
+            throw TiesPathException.grammarError(String.format("Parameters are not supported for %s in target filter",
+                    containerType.getValue()));
+        }
+    }
+
+    @Override
+    public void exitContainerName(final tiesPathParser.ContainerNameContext ctx) {
+        final String containerName = ctx.getText();
+        containerNames.add(containerName);
+    }
+
+    @Override
+    public void exitContainsFunctionCondition(final tiesPathParser.ContainsFunctionConditionContext ctx) {
+        throw TiesPathException.grammarError("");
+    }
+
+    @Override
+    public void exitLeafCondition(final tiesPathParser.LeafConditionContext ctx) {
+        throw TiesPathException.grammarError("Parameter condition is not supported in target filter");
+    }
+
+    @Override
+    public void exitBooleanOperators(final tiesPathParser.BooleanOperatorsContext ctx) {
+        throw TiesPathException.grammarError("");
+    }
+
+    @Override
+    public void exitFieldLeaf(final tiesPathParser.FieldLeafContext ctx) {
+        attributeNames = ctx.leafName().stream().map(RuleContext::getText).toList();
+    }
+
+    private TargetObject checkAndProcessIfSingleContainerAndValidTopologyObject(String rootObject,
+            List<String> containerNames, List<String> attributeNames) {
+        final int noOfContainers = containerNames.size();
+        if (noOfContainers == 1 && (null == rootObject || rootObject.equals(containerNames.get(0)))) {
+            assertAttributesApplicableForContainer(attributeNames);
+            return TargetObject.builder(containerNames.get(0)).build();
+        }
+        throw TiesPathException.grammarError(
+                "Invalid Container name or Root Object name does not match to the path parameter");
+    }
+
+    private void assertAttributesApplicableForContainer(List<String> attrNames) {
+        if (!attrNames.isEmpty()) {
+            throw TiesPathException.grammarError("Attributes cannot be associated at this level");
+        }
+    }
+}
index 588599a..927e2df 100644 (file)
@@ -22,26 +22,40 @@ package org.oran.smo.teiv.exposure.tiespath.resolver;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
 import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.oran.smo.teiv.antlr4.tiesPathParser;
 import org.springframework.stereotype.Component;
 
-import org.oran.smo.teiv.exception.TiesException;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TargetObject;
-import org.oran.smo.teiv.utils.path.TiesPathQuery;
-import org.oran.smo.teiv.utils.path.TiesPathUtil;
 import org.oran.smo.teiv.utils.path.exception.PathParsingException;
 import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
 
+import static org.oran.smo.teiv.utils.TiesConstants.WILDCARD;
+
 @Slf4j
 @Component
 public class TargetResolver implements PathResolver<List<TargetObject>> {
 
+    @Override
+    public List<TargetObject> onEmptyFilter(String rootObject) {
+        final String topologyObject = Optional.ofNullable(rootObject).orElse(WILDCARD);
+        final TargetObject targetObject = TargetObject.builder(topologyObject).build();
+        final ArrayList<TargetObject> objects = new ArrayList<>();
+        objects.add(targetObject);
+        return objects;
+    }
+
+    @Override
+    public void preCheck(String rootObject, String filter) {
+        if (filter.contains("|")) {
+            throw TiesPathException.grammarError("OR (|) is not supported for target filter");
+        }
+    }
+
     /**
      * Process filter and root objectType . Populates List of Target Object
      *
@@ -51,59 +65,22 @@ public class TargetResolver implements PathResolver<List<TargetObject>> {
      *     filter in the query parameter
      * @return Immutable list of filter objects
      */
-    public List<TargetObject> resolve(String rootObject, @NonNull String filter) {
-        preCheck(filter);
-        if (filter.isEmpty()) {
-            final String topologyObject = isRootObjectNullOrEmpty(rootObject) ? NULL_ROOT_OBJECT : rootObject;
-            return List.of(TargetObject.builder(topologyObject).build());
-        } else {
-            List<TargetObject> targetObjects = new ArrayList<>();
-            Arrays.stream(filter.split(";")).forEach(targetToken -> {
-                final TiesPathQuery tiesPathQuery;
-                try {
-                    tiesPathQuery = TiesPathUtil.getTiesPathQuery(targetToken);
-                } catch (ParseCancellationException | PathParsingException e) {
-                    log.error("Parsing error on target {} :", targetToken, e);
-                    throw TiesPathException.grammarError(e.getMessage());
-                }
-
-                final int noOfContainers = tiesPathQuery.getContainerNames().size();
-                if (noOfContainers == 0) {
-                    //invalid scenario
-                    throw TiesException.serverException("Server unknown exception",
-                            "Requested query could not be processed", null);
-                }
+    @Override
+    public List<TargetObject> process(String rootObject, String filter) {
+        List<TargetObject> targetObjects = new ArrayList<>();
+        Arrays.stream(filter.split(";")).forEach(targetToken -> {
+            try {
+                tiesPathParser pathParser = getTiesPathParser(targetToken);
+                final TargetFilterListener targetFilterListener = new TargetFilterListener(rootObject);
+                pathParser.addParseListener(targetFilterListener);
+                pathParser.tiesPath();
 
-                Optional.ofNullable(getContainerType(tiesPathQuery.getContainerNames())).ifPresentOrElse(
-                        containerType -> targetObjects.add(TargetObject.builder(getTopologyObject(rootObject, tiesPathQuery
-                                .getContainerNames())).container(containerType).params(tiesPathQuery.getAttributeNames())
-                                .build()), () -> targetObjects.add(checkIfSingleContainerAndValidTopologyObject(rootObject,
-                                        tiesPathQuery.getContainerNames(), tiesPathQuery.getAttributeNames())));
-            });
-            return Collections.unmodifiableList(targetObjects);
-        }
-    }
-
-    private void preCheck(String target) {
-        if (target.contains("|")) {
-            throw TiesPathException.grammarError("OR (|) is not supported for target filter");
-        }
-    }
-
-    private TargetObject checkIfSingleContainerAndValidTopologyObject(String rootObject, List<String> containerNames,
-            List<String> attributeNames) {
-        final int noOfContainers = containerNames.size();
-        if (noOfContainers == 1 && (isRootObjectNullOrEmpty(rootObject) || rootObject.equals(containerNames.get(0)))) {
-            assertAttributesApplicableForContainer(attributeNames);
-            return TargetObject.builder(containerNames.get(0)).build();
-        }
-        throw TiesPathException.grammarError(
-                "Invalid Container name or Root Object name does not match to the path parameter");
-    }
-
-    private void assertAttributesApplicableForContainer(List<String> attrNames) {
-        if (!attrNames.isEmpty()) {
-            throw TiesPathException.grammarError("Attributes cannot be associated at this level");
-        }
+                targetObjects.add(targetFilterListener.getTargetObject());
+            } catch (ParseCancellationException | PathParsingException e) {
+                log.error("Parsing error on target {} :", targetToken, e);
+                throw TiesPathException.grammarError(e.getMessage());
+            }
+        });
+        return targetObjects;
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationDTO.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationDTO.java
deleted file mode 100644 (file)
index 22eff16..0000000
+++ /dev/null
@@ -1,89 +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 org.oran.smo.teiv.exposure.utils;
-
-import lombok.Data;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Data
-public class PaginationDTO {
-    private int limit;
-    private int offset;
-    private int totalSize;
-    private Map<String, String> queryParameters = new HashMap<>();
-    private Map<String, String> pathParameters = new HashMap<>();
-    private String basePath;
-
-    private PaginationDTO(int limit, int offset, Map<String, String> queryParameters, Map<String, String> pathParameters,
-            String basePath) {
-        this.limit = limit;
-        this.offset = offset;
-        this.queryParameters.putAll(queryParameters);
-        this.pathParameters.putAll(pathParameters);
-        this.basePath = basePath;
-    }
-
-    public static PaginationDTOBuilder builder() {
-        return new PaginationDTOBuilder();
-    }
-
-    public static class PaginationDTOBuilder {
-        private int limit;
-        private int offset;
-        private final Map<String, String> queryParameters = new HashMap<>();
-        private final Map<String, String> pathParameters = new HashMap<>();
-        private String basePath;
-
-        PaginationDTOBuilder() {
-        }
-
-        public PaginationDTOBuilder limit(int limit) {
-            this.limit = limit;
-            return this;
-        }
-
-        public PaginationDTOBuilder offset(int offset) {
-            this.offset = offset;
-            return this;
-        }
-
-        public PaginationDTOBuilder addQueryParameters(String key, String value) {
-            queryParameters.put(key, value);
-            return this;
-        }
-
-        public PaginationDTOBuilder addPathParameters(String key, String value) {
-            pathParameters.put(key, value);
-            return this;
-        }
-
-        public PaginationDTOBuilder basePath(String basePath) {
-            this.basePath = basePath;
-            return this;
-        }
-
-        public PaginationDTO build() {
-            return new PaginationDTO(limit, offset, queryParameters, pathParameters, basePath);
-        }
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationUtil.java b/teiv/src/main/java/org/oran/smo/teiv/exposure/utils/PaginationUtil.java
new file mode 100644 (file)
index 0000000..150c201
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *  ============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.teiv.exposure.utils;
+
+import lombok.experimental.UtilityClass;
+import org.oran.smo.teiv.api.model.OranTeivHref;
+import org.oran.smo.teiv.exception.TiesException;
+
+/**
+ * Generates the pagination link as href.
+ */
+@UtilityClass
+public class PaginationUtil {
+
+    /**
+     * Validates whether the offset is greater than the totalCount and throws exception.
+     */
+    public static void validateOffset(int offset, int totalCount) {
+        if (totalCount > 0 && totalCount <= offset) {
+            throw TiesException.invalidValueException("Offset", totalCount - 1, true);
+        }
+    }
+
+    /**
+     * Gets the viable offset based on given offset, limit and totalCount.
+     *
+     * @param offset
+     *     - offset from the request
+     * @param totalCount
+     *     - total count of the records
+     * @throws TiesException
+     *     - if offset is greater than totalCount
+     */
+    public static int getViableLimit(final int offset, final int limit, final int totalCount) {
+        validateOffset(offset, totalCount);
+
+        return (totalCount == 0) ? totalCount : Math.min(limit, totalCount - offset);
+    }
+
+    /**
+     * Gets the first page href.
+     *
+     * @param requestDetails
+     *     - request details
+     * @return first page href as {@link OranTeivHref}
+     */
+    public static OranTeivHref firstHref(RequestDetails requestDetails) {
+        return getHref(requestDetails, 0);
+    }
+
+    /**
+     * Gets the prev page href.
+     *
+     * @param requestDetails
+     *     - request details
+     * @param totalCount
+     *     - total items count
+     * @return prev page href as {@link OranTeivHref}
+     */
+    public static OranTeivHref prevHref(RequestDetails requestDetails, int totalCount) {
+        if (requestDetails.getOffset() > 0 && totalCount > 0) {
+            final int prevOffset = Math.max(requestDetails.getOffset() - requestDetails.getLimit(), 0);
+            return getHref(requestDetails, prevOffset);
+        }
+        return selfHref(requestDetails);
+    }
+
+    /**
+     * Gets the self page href.
+     *
+     * @param requestDetails
+     *     - request details
+     * @return self page href as {@link OranTeivHref}
+     */
+    public static OranTeivHref selfHref(RequestDetails requestDetails) {
+        return getHref(requestDetails, requestDetails.getOffset());
+    }
+
+    /**
+     * Gets the next page href.
+     *
+     * @param requestDetails
+     *     - request details
+     * @param totalCount
+     *     - total items count
+     * @return next page href as {@link OranTeivHref}
+     */
+    public static OranTeivHref nextHref(RequestDetails requestDetails, int totalCount) {
+        if (hasNextPage(requestDetails, totalCount)) {
+            final int nextOffset = Math.min(requestDetails.getOffset() + requestDetails.getLimit(), totalCount);
+            return getHref(requestDetails, nextOffset);
+        }
+
+        return selfHref(requestDetails);
+    }
+
+    /**
+     * Gets the last page href.
+     *
+     * @param requestDetails
+     *     - request details
+     * @param totalCount
+     *     - total items count
+     * @return last page href as {@link OranTeivHref}
+     */
+    public static OranTeivHref lastHref(RequestDetails requestDetails, int totalCount) {
+        if (hasNextPage(requestDetails, totalCount)) {
+            final int diff = totalCount - requestDetails.getOffset();
+            final int lastOffset;
+            if (diff % requestDetails.getLimit() == 0) {
+                lastOffset = (diff / requestDetails.getLimit() - 1) * requestDetails.getLimit() + requestDetails
+                        .getOffset();
+            } else {
+                lastOffset = (diff / requestDetails.getLimit()) * requestDetails.getLimit() + requestDetails.getOffset();
+            }
+            return getHref(requestDetails, lastOffset);
+        }
+
+        return selfHref(requestDetails);
+    }
+
+    private static OranTeivHref getHref(RequestDetails requestDetails, int pageOffset) {
+        StringBuilder hrefString = new StringBuilder(requestDetails.getBasePath()).append(String.format(
+                "?offset=%s&limit=%s", pageOffset, requestDetails.getLimit()));
+
+        requestDetails.getQueryParams().forEach((key, value) -> {
+            if (value != null) {
+                hrefString.append("&").append(key).append("=").append(value);
+            }
+        });
+        return OranTeivHref.builder().href(hrefString.toString()).build();
+    }
+
+    private static boolean hasNextPage(final RequestDetails requestDetails, int totalCount) {
+        if (totalCount > 0) {
+            return (requestDetails.getOffset() + requestDetails.getLimit()) < totalCount;
+        }
+
+        return false;
+    }
+}
  *  SPDX-License-Identifier: Apache-2.0
  *  ============LICENSE_END=========================================================
  */
-package org.oran.smo.teiv.exposure.collection.rest.controller;
+package org.oran.smo.teiv.exposure.utils;
 
-import org.oran.smo.teiv.api.TopologyGroupsApi;
-import org.oran.smo.teiv.utils.TiesConstants;
+import java.util.Map;
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import lombok.Builder;
+import lombok.NonNull;
+import lombok.Singular;
+import lombok.Value;
 
-@RestController
-@RequestMapping(TiesConstants.REQUEST_MAPPING)
-public class TopologyGroupsRestController implements TopologyGroupsApi {
+@Value
+@Builder
+public class RequestDetails {
+
+    @Builder.Default
+    int offset = 0;
+
+    @Builder.Default
+    int limit = 500;
+
+    @NonNull
+    String basePath;
+
+    @Singular
+    Map<String, String> queryParams;
 
 }
index 37f496b..6f87682 100644 (file)
  */
 package org.oran.smo.teiv.exposure.utils;
 
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import org.oran.smo.teiv.exception.TiesException;
 import org.oran.smo.teiv.schema.SchemaRegistry;
 import lombok.RequiredArgsConstructor;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Objects;
 
 @Service
 @RequiredArgsConstructor
+@Slf4j
 public class RequestValidator {
 
     public void validateDomain(String domain) {
@@ -62,13 +67,11 @@ public class RequestValidator {
         }
     }
 
-    public void validateFiltersForRelationships(String targetFilter, String scopeFilter) {
-        if (targetFilter != null) {
-            throw TiesException.notImplementedException("Using targetFilter for this endpoint is not implemented.", null);
-        }
-        if (scopeFilter != null && scopeFilter.startsWith("/attributes")) {
-            throw TiesException.notImplementedException(
-                    "Using scopeFilter for filtering relationship attributes is not implemented.", null);
+    public void validateYangFile(MultipartFile file) {
+
+        if (!Objects.equals(file.getContentType(), "application/yang")) {
+            throw TiesException.invalidFileInput("Invalid file");
         }
+
     }
 }
index 27a6010..bf508e4 100644 (file)
@@ -52,6 +52,7 @@ public class CreateTopologyProcessor implements TopologyProcessor {
             customMetrics.incrementNumUnsuccessfullyParsedCreateCloudEvents();
             return;
         }
+        parsedCloudEventData.sort();
         stopWatch.stop();
         customMetrics.recordCloudEventCreateParseTime(stopWatch.lastTaskInfo().getTimeNanos());
         customMetrics.incrementNumSuccessfullyParsedCreateCloudEvents();
index fc401ae..59c9395 100644 (file)
@@ -24,7 +24,6 @@ import io.cloudevents.CloudEvent;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.function.Consumer;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -32,6 +31,7 @@ import org.jooq.DSLContext;
 import org.oran.smo.teiv.CustomMetrics;
 import org.oran.smo.teiv.schema.EntityType;
 import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.RelationshipDataLocation;
 import org.oran.smo.teiv.schema.SchemaRegistry;
 import org.oran.smo.teiv.service.TiesDbOperations;
 import org.oran.smo.teiv.service.TiesDbService;
@@ -64,6 +64,7 @@ public class DeleteTopologyProcessor implements TopologyProcessor {
             customMetrics.incrementNumUnsuccessfullyParsedDeleteCloudEvents();
             return;
         }
+        parsedCloudEventData.sort();
         stopWatch.stop();
         customMetrics.recordCloudEventDeleteParseTime(stopWatch.lastTaskInfo().getTimeNanos());
         customMetrics.incrementNumSuccessfullyParsedDeleteCloudEvents();
@@ -75,23 +76,20 @@ public class DeleteTopologyProcessor implements TopologyProcessor {
 
         parsedCloudEventData.getEntities().forEach(entity -> {
             EntityType entityType = SchemaRegistry.getEntityTypeByName(entity.getType());
-            dbOperations.add(dslContext -> operationResults.addAll(
-                    tiesDbOperations.deleteEntity(dslContext, entityType, entity.getId())));
+            dbOperations.add(dslContext -> operationResults
+                .addAll(tiesDbOperations.deleteEntity(dslContext, entityType, entity.getId())));
         });
 
         parsedCloudEventData.getRelationships().forEach(relationship -> {
             RelationType relationType = SchemaRegistry.getRelationTypeByName(relationship.getType());
-            switch (Objects.requireNonNull(relationType).getRelationshipStorageLocation()) {
-                case RELATION -> dbOperations.add(dslContext -> {
-                    Optional<OperationResult> operationResult = tiesDbOperations.deleteManyToManyRelationByRelationId(
-                            dslContext, relationType.getTableName(), relationship.getId());
-                    operationResult.ifPresent(operationResults::add);
-                });
-                case A_SIDE, B_SIDE -> dbOperations.add(dslContext -> {
-                    Optional<OperationResult> operationResult = tiesDbOperations.deleteRelationFromEntityTableByRelationId(
-                            dslContext, relationship.getId(), relationType);
-                    operationResult.ifPresent(operationResults::add);
-                });
+            if (Objects.requireNonNull(relationType)
+                .getRelationshipStorageLocation() == RelationshipDataLocation.RELATION) {
+                dbOperations.add(dslContext -> tiesDbOperations.deleteManyToManyRelationByRelationId(dslContext,
+                    relationType, relationship.getId()).ifPresent(operationResults::add));
+            } else {
+                dbOperations
+                    .add(dslContext -> tiesDbOperations.deleteRelationFromEntityTableByRelationId(dslContext,
+                        relationship.getId(), relationType).ifPresent(operationResults::add));
             }
         });
 
@@ -99,7 +97,7 @@ public class DeleteTopologyProcessor implements TopologyProcessor {
             tiesDbService.execute(dbOperations);
         } catch (RuntimeException e) {
             log.error("Failed to process a CloudEvent. Discarded CloudEvent: {}. Used kafka message key: {}. Reason: {}",
-                    CloudEventUtil.cloudEventToPrettyString(cloudEvent), messageKey, e.getMessage());
+                CloudEventUtil.cloudEventToPrettyString(cloudEvent), messageKey, e.getMessage());
             customMetrics.incrementNumUnsuccessfullyPersistedDeleteCloudEvents();
             return;
         }
index 095c599..e2e0ea8 100644 (file)
@@ -60,6 +60,7 @@ public class MergeTopologyProcessor implements TopologyProcessor {
             customMetrics.incrementNumUnsuccessfullyParsedMergeCloudEvents();
             return;
         }
+        parsedCloudEventData.sort();
         stopWatch.stop();
         customMetrics.recordCloudEventMergeParseTime(stopWatch.lastTaskInfo().getTimeNanos());
         customMetrics.incrementNumSuccessfullyParsedMergeCloudEvents();
index 91171bf..bb3f915 100644 (file)
@@ -48,9 +48,7 @@ import org.oran.smo.teiv.service.TiesDbService;
 @Slf4j
 @AllArgsConstructor
 @Profile("ingestion")
-
 public class SourceEntityDeleteTopologyProcessor implements TopologyProcessor {
-
     private final TiesDbService tiesDbService;
     private final ObjectMapper objectMapper;
     private final CustomMetrics customMetrics;
@@ -86,8 +84,8 @@ public class SourceEntityDeleteTopologyProcessor implements TopologyProcessor {
         List<OperationResult> operationResults = new ArrayList<>();
         try {
             List<Consumer<DSLContext>> dbOperations = new ArrayList<>();
-            SchemaRegistry.getEntityTypesWithCmId().forEach(entityType -> dbOperations.add(dslContext -> {
-                List<String> results = tiesDbOperations.selectByCmHandle(dslContext, entityType.getTableName(),
+            SchemaRegistry.getEntityTypes().forEach(entityType -> dbOperations.add(dslContext -> {
+                List<String> results = tiesDbOperations.selectByCmHandleFormSourceIds(dslContext, entityType.getTableName(),
                         sourceEntityDelete.value);
                 if (!results.isEmpty()) {
                     for (String result : results) {
diff --git a/teiv/src/main/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1.java b/teiv/src/main/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1.java
deleted file mode 100644 (file)
index f3fb9fc..0000000
+++ /dev/null
@@ -1,112 +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 org.oran.smo.teiv.listener;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-
-import org.oran.smo.teiv.service.models.OperationResult;
-import org.oran.smo.teiv.utils.CloudEventUtil;
-import org.jooq.DSLContext;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StopWatch;
-
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.service.TiesDbOperations;
-import org.oran.smo.teiv.service.TiesDbService;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.cloudevents.CloudEvent;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-@Component
-@Slf4j
-@AllArgsConstructor
-@Profile("ingestion")
-public class SourceEntityDeleteTopologyProcessorV1 implements TopologyProcessor {
-    private final TiesDbService tiesDbService;
-    private final ObjectMapper objectMapper;
-    private final CustomMetrics customMetrics;
-    private final TiesDbOperations tiesDbOperations;
-
-    @Override
-    public void process(CloudEvent cloudEvent, String messageKey) {
-        StopWatch stopWatch = new StopWatch();
-        stopWatch.start();
-
-        SourceEntityDeleteV1 sourceEntityDelete;
-        try {
-            sourceEntityDelete = objectMapper.readValue(cloudEvent.getData().toBytes(), SourceEntityDeleteV1.class);
-        } catch (IOException e) {
-            log.error("Error while parsing the {} event.", e.getMessage());
-            customMetrics.incrementNumUnsuccessfullyParsedSourceEntityDeleteCloudEvents();
-            return;
-        }
-
-        //currently only cmHandle delete supported
-        if (!"cmHandle".equalsIgnoreCase(sourceEntityDelete.type)) {
-            log.error("Unsupported type: {} for source-entity-delete event. Event: {}", sourceEntityDelete.type,
-                    cloudEvent);
-            customMetrics.incrementNumReceivedCloudEventNotSupported();
-            return;
-        }
-
-        stopWatch.stop();
-        customMetrics.recordCloudEventSourceEntityDeleteParseTime(stopWatch.lastTaskInfo().getTimeNanos());
-        customMetrics.incrementNumSuccessfullyParsedSourceEntityDeleteCloudEvents();
-
-        stopWatch.start();
-        List<OperationResult> operationResults = new ArrayList<>();
-        try {
-            List<Consumer<DSLContext>> dbOperations = new ArrayList<>();
-            SchemaRegistry.getEntityTypes().forEach(entityType -> dbOperations.add(dslContext -> {
-                List<String> results = tiesDbOperations.selectByCmHandleFormSourceIds(dslContext, entityType.getTableName(),
-                        sourceEntityDelete.value);
-                if (!results.isEmpty()) {
-                    for (String result : results) {
-                        operationResults.addAll(tiesDbOperations.deleteEntity(dslContext, entityType, result));
-                    }
-                }
-            }));
-            tiesDbService.execute(dbOperations);
-        } catch (RuntimeException e) {
-            log.error("Failed to process a CloudEvent. Discarded CloudEvent: {}. Used kafka message key: {}. Reason: {}",
-                    CloudEventUtil.cloudEventToPrettyString(cloudEvent), messageKey, e.getMessage());
-            customMetrics.incrementNumUnsuccessfullyPersistedSourceEntityDeleteCloudEvents();
-            return;
-        }
-
-        stopWatch.stop();
-        customMetrics.recordCloudEventSourceEntityDeletePersistTime(stopWatch.lastTaskInfo().getTimeNanos());
-        customMetrics.incrementNumSuccessfullyPersistedSourceEntityDeleteCloudEvents();
-    }
-
-    @JsonIgnoreProperties(ignoreUnknown = true)
-    record SourceEntityDeleteV1(@JsonProperty(value = "type", required = true) String type,
-                                @JsonProperty(value = "value", required = true) String value) {
-    }
-}
index 3cc7530..236adc3 100644 (file)
@@ -45,7 +45,7 @@ public class TopologyListener {
     private final TopologyProcessorRegistry topologyProcessorRegistry;
     private final LogAccessor logger = new LogAccessor(TopologyListener.class);
 
-    @KafkaListener(id = "${kafka.topology-ingestion.consumer.group-id}", topics = "${kafka.topology-ingestion.consumer.topic.name}", containerFactory = "topologyListenerContainerFactory", autoStartup = "false")
+    @KafkaListener(id = "${kafka.topology-ingestion.consumer.group-id}", topics = "${kafka.topology-ingestion.topic.name}", containerFactory = "topologyListenerContainerFactory", autoStartup = "false")
     public void processEvents(List<ConsumerRecord<String, CloudEvent>> events) {
         log.info("Processing events: {}", events.size());
         for (ConsumerRecord<String, CloudEvent> rec : events) {
index fe8dfde..9e83acd 100644 (file)
@@ -20,7 +20,6 @@
  */
 package org.oran.smo.teiv.listener;
 
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
 import io.cloudevents.CloudEvent;
@@ -41,12 +40,8 @@ public class TopologyProcessorRegistry {
     private final MergeTopologyProcessor mergeTopologyProcessor;
     private final DeleteTopologyProcessor deleteTopologyProcessor;
     private final SourceEntityDeleteTopologyProcessor sourceEntityDeleteTopologyProcessor;
-    private final SourceEntityDeleteTopologyProcessorV1 sourceEntityDeleteTopologyProcessorV1;
     private final UnsupportedTopologyEventProcessor unsupportedTopologyEventProcessor;
 
-    @Value("${feature_flags.use_alternate_delete_logic}")
-    private boolean useAlternateDeleteLogic;
-
     public TopologyProcessor getProcessor(CloudEvent event) {
         String cloudEventType = getCloudEventType(event);
         switch (cloudEventType) {
@@ -68,9 +63,7 @@ public class TopologyProcessorRegistry {
             case TiesConstants.CLOUD_EVENT_WITH_TYPE_SOURCE_ENTITY_DELETE -> {
                 log.debug("Source Entity Delete CloudEvent received with id: {}", event.getId());
                 metrics.incrementNumReceivedCloudEventSourceEntityDelete();
-                return useAlternateDeleteLogic ?
-                        sourceEntityDeleteTopologyProcessorV1 :
-                        sourceEntityDeleteTopologyProcessor;
+                return sourceEntityDeleteTopologyProcessor;
             }
             default -> {
                 metrics.incrementNumReceivedCloudEventNotSupported();
index e2b6827..5cacbb2 100644 (file)
@@ -42,6 +42,9 @@ public class BidiDbNameMapper {
      * @return the mapped DB name
      */
     public static String getDbName(String name) {
+        if (!nameMap.containsKey(name)) {
+            return name;
+        }
         return nameMap.get(name);
     }
 
index 102ca05..4ef6125 100644 (file)
@@ -20,9 +20,9 @@
  */
 package org.oran.smo.teiv.schema;
 
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataRepository;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -38,20 +38,20 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public class ConsumerDataCache {
 
-    private final DataPersistanceService dataPersistanceService;
+    private final ConsumerDataRepository consumerDataRepository;
 
     @Cacheable("classifiers")
     public Set<String> getClassifiers() {
-        return Collections.unmodifiableSet(dataPersistanceService.loadClassifiers());
+        return Collections.unmodifiableSet(consumerDataRepository.loadClassifiers());
     }
 
     @Cacheable("decorators")
-    public Map<String, DataType> getDecorators() {
-        return Collections.unmodifiableMap(dataPersistanceService.loadDecorators());
+    public Map<String, YangDataTypes> getDecorators() {
+        return Collections.unmodifiableMap(consumerDataRepository.loadDecorators());
     }
 
     @Cacheable("validClassifiers")
-    public Set<String> getValidClassifiers(String partialClassifier) {
+    public Set<String> getValidClassifiers(final String partialClassifier) {
         return getClassifiers().stream().filter(c -> c.contains(partialClassifier)).collect(Collectors.toSet());
     }
 
index 449a696..155eb9a 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Locale;
 public enum DataType {
     PRIMITIVE,
     DECIMAL,
+    INTEGER,
     BIGINT,
     CONTAINER,
     GEOGRAPHIC;
@@ -33,6 +34,7 @@ public enum DataType {
         return switch (dbDatatype.toUpperCase(Locale.US)) {
             case "TEXT", "VARCHAR" -> PRIMITIVE;
             case "NUMERIC", "DECIMAL" -> DECIMAL;
+            case "INT4" -> INTEGER;
             case "BIGINT", "INT8" -> BIGINT;
             case "JSONB" -> CONTAINER;
             case "GEOGRAPHY" -> GEOGRAPHIC;
index 9211d1a..654f10e 100644 (file)
 package org.oran.smo.teiv.schema;
 
 import static org.jooq.impl.DSL.field;
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
 import static org.oran.smo.teiv.schema.BidiDbNameMapper.getDbName;
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
-import static org.oran.smo.teiv.schema.DataType.BIGINT;
 import static org.oran.smo.teiv.schema.DataType.CONTAINER;
-import static org.oran.smo.teiv.schema.DataType.DECIMAL;
 import static org.oran.smo.teiv.schema.DataType.GEOGRAPHIC;
+import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES_ABBREVIATION;
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
 import static org.oran.smo.teiv.utils.TiesConstants.CONSUMER_DATA_PREFIX;
+import static org.oran.smo.teiv.utils.TiesConstants.DECORATORS;
 import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
 import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
 import static org.oran.smo.teiv.utils.TiesConstants.REL_PREFIX;
 import static org.oran.smo.teiv.utils.TiesConstants.ST_TO_STRING;
-import static org.oran.smo.teiv.utils.TiesConstants.ST_TO_STRING_COLUMN_WITH_TABLE_NAME;
 import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
 import static org.oran.smo.teiv.utils.TiesConstants.SOURCE_IDS;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import lombok.Value;
 import org.jooq.Field;
 import org.jooq.JSONB;
 
 import lombok.Builder;
 import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.ToString;
 
-@Getter
+import org.oran.smo.teiv.exposure.spi.Module;
+
+@Value
 @Builder
-@ToString
 public class EntityType implements Persistable {
     @EqualsAndHashCode.Include
-    private final String name;
-    private final Map<String, DataType> fields;
-    private final Module module;
+    String name;
+    Map<String, DataType> fields;
+    String tableName;
+    Module module;
 
     @Override
     public String getTableName() {
-        return String.format(TIES_DATA, getDbName(this.name));
+        return String.format(TIES_DATA, getDbName(this.tableName));
     }
 
     @Override
     public String getIdColumnName() {
-        return getTableName() + "." + ID_COLUMN_NAME;
+        return ID_COLUMN_NAME;
     }
 
     @Override
-    public List<String> getAttributeColumnsWithId() {
-        final List<String> columnList = new ArrayList<>();
-        this.fields.forEach((fieldName, dataType) -> {
-            if ((fieldName.startsWith(REL_PREFIX)) || fieldName.startsWith(CONSUMER_DATA_PREFIX)) {
-                return;
-            }
-            final String tableString = getTableName() + ".";
-            columnList.add(tableString + String.format(QUOTED_STRING, getDbName(fieldName)));
-        });
-        return columnList;
+    public String getIdColumnNameWithTableName() {
+        return getTableName() + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME);
     }
 
     @Override
-    public List<Field> getAllFieldsWithId() {
-        final List<Field> fieldList = new ArrayList<>();
+    @SuppressWarnings("java:S5738")
+    public Map<Field, DataType> getSpecificAttributeColumns(List<String> attributes) {
+        final Map<Field, DataType> fieldList = new HashMap<>();
         this.fields.forEach((fieldName, dataType) -> {
-            if (fieldName.startsWith(REL_PREFIX)) {
+            if (!attributes.contains(fieldName) && !attributes.isEmpty()) {
+                return;
+            }
+            if (fieldName.startsWith(REL_PREFIX) || fieldName.startsWith(CONSUMER_DATA_PREFIX) || fieldName.equals(
+                    ID_COLUMN_NAME)) {
                 return;
             }
             if (GEOGRAPHIC.equals(dataType)) {
-                fieldList.add(field(String.format(ST_TO_STRING, getDbName(fieldName))).as(getDbName(fieldName)));
+                fieldList.put(field(String.format(ST_TO_STRING, getTableName() + "." + String.format(QUOTED_STRING,
+                        getDbName(fieldName)))).as(hashAlias(
+                                getFullyQualifiedName() + ATTRIBUTES_ABBREVIATION + fieldName)), dataType);
             } else if (CONTAINER.equals(dataType)) {
-                fieldList.add(field(String.format(QUOTED_STRING, getDbName(fieldName)), JSONB.class).as(getDbName(
-                        fieldName)));
+                fieldList.put(field(getTableName() + "." + String.format(QUOTED_STRING, getDbName(fieldName)), JSONB.class)
+                        .as(hashAlias(getFullyQualifiedName() + ATTRIBUTES_ABBREVIATION + fieldName)), dataType);
             } else {
-                fieldList.add(field(String.format(QUOTED_STRING, getDbName(fieldName))).as(getDbName(fieldName)));
+                fieldList.put(field(getTableName() + "." + String.format(QUOTED_STRING, getDbName(fieldName))).as(hashAlias(
+                        getFullyQualifiedName() + ATTRIBUTES_ABBREVIATION + fieldName)), dataType);
             }
         });
         return fieldList;
     }
 
     public List<String> getAttributeNames() {
-        return this.fields.keySet().stream().filter(field -> (!field.startsWith(REL_PREFIX) || !field.startsWith(
-                CONSUMER_DATA_PREFIX))).toList();
+        return this.fields.keySet().stream().filter(field -> (!field.startsWith(REL_PREFIX) && !field.startsWith(
+                CONSUMER_DATA_PREFIX) && !field.equals(ID_COLUMN_NAME))).toList();
     }
 
     /**
@@ -111,38 +110,28 @@ public class EntityType implements Persistable {
      *
      * @return the fully qualified name
      */
+    @Override
     public String getFullyQualifiedName() {
         return String.format("%s:%s", module.getName(), name);
     }
 
-    public Field getField(String column, String prefix, String tableName) {
-        final String columnName = column.contains(".") ? column.split("\\.")[2].replace("\"", "") : column;
-        final String alias = (prefix != null ? (prefix + ".") : "") + column;
-        final String tableString = tableName != null ? (String.format(TIES_DATA, tableName) + ".") : "";
-
-        if (!this.fields.containsKey(getModelledName(columnName))) {
-            return null;
-        }
-
-        DataType type = this.fields.get(getModelledName(columnName));
-
-        if (type.equals(GEOGRAPHIC) && column.contains(TIES_DATA_SCHEMA)) {
-            return field(String.format(ST_TO_STRING_COLUMN_WITH_TABLE_NAME, column), String.class).as(alias);
-        } else if (type.equals(GEOGRAPHIC)) {
-            return field(tableString + String.format(ST_TO_STRING, column), String.class).as(alias);
-        } else if (type.equals(CONTAINER)) {
-            return field(tableString + column, JSONB.class).as(alias);
-        } else if (type.equals(DECIMAL)) {
-            return field(tableString + column, BigDecimal.class).as(alias);
-        } else if (type.equals(BIGINT)) {
-            return field(tableString + column, Long.class).as(alias);
-        } else {
-            return field(tableString + column, String.class).as(alias);
-        }
-    }
-
     @Override
     public String getSourceIdsColumnName() {
         return getDbName(CONSUMER_DATA_PREFIX + SOURCE_IDS);
     }
+
+    @Override
+    public String getClassifiersColumnName() {
+        return getDbName(CONSUMER_DATA_PREFIX + CLASSIFIERS);
+    }
+
+    @Override
+    public String getDecoratorsColumnName() {
+        return getDbName(CONSUMER_DATA_PREFIX + DECORATORS);
+    }
+
+    @Override
+    public String getCategory() {
+        return "entity";
+    }
 }
index 0448a15..d9c6575 100644 (file)
  */
 package org.oran.smo.teiv.schema;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.jooq.Field;
+import org.jooq.JSONB;
+
+import static org.jooq.impl.DSL.field;
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
+import static org.oran.smo.teiv.utils.PersistableUtil.getFullyQualifiedNameWithColumnName;
+import static org.oran.smo.teiv.utils.TiesConstants.*;
 
 public interface Persistable {
 
@@ -42,18 +50,43 @@ public interface Persistable {
     String getIdColumnName();
 
     /**
-     * Gets all the column names.
+     * Gets the column name used for storing the unique identifier.
+     *
+     * @return the id column name with table name
+     */
+    String getIdColumnNameWithTableName();
+
+    /**
+     * Gets specific columns.
+     *
+     * @param attributes
+     *     specific attributes names
      *
-     * @return the list of column names
+     * @return the list of columns
      */
-    List<String> getAttributeColumnsWithId();
+    Map<Field, DataType> getSpecificAttributeColumns(List<String> attributes);
 
     /**
      * Gets all the columns names as list of {@link Field}
      *
+     *
      * @return the list of {@link Field}
      */
-    List<Field> getAllFieldsWithId();
+    default List<Field> getAllFieldsWithId() {
+        List<Field> result = new ArrayList<>(getSpecificAttributeColumns(List.of()).keySet());
+        String fullyQuelifiedName = getFullyQualifiedName();
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, getIdColumnName())).as(hashAlias(
+                getFullyQualifiedNameWithColumnName(fullyQuelifiedName, ID_COLUMN_NAME))));
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, getSourceIdsColumnName()), JSONB.class).as(
+                hashAlias(getFullyQualifiedNameWithColumnName(fullyQuelifiedName, SOURCE_IDS))));
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, getClassifiersColumnName()), JSONB.class).as(
+                hashAlias(getFullyQualifiedNameWithColumnName(fullyQuelifiedName, CLASSIFIERS))));
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, getDecoratorsColumnName()), JSONB.class).as(
+                hashAlias(getFullyQualifiedNameWithColumnName(fullyQuelifiedName, DECORATORS))));
+        return result;
+    }
+
+    List<String> getAttributeNames();
 
     /**
      * Gets sourceIds column name as String
@@ -61,4 +94,34 @@ public interface Persistable {
      * @return the String value of sourceIds column
      */
     String getSourceIdsColumnName();
+
+    /**
+     * Gets classifiers column name as String
+     *
+     * @return the String value of classifiers column
+     */
+    String getClassifiersColumnName();
+
+    /**
+     * Gets decorators column name as String
+     *
+     * @return the String value of decorators column
+     */
+    String getDecoratorsColumnName();
+
+    String getName();
+
+    /**
+     * Gets the fully qualified name of the entity. Format - <moduleNameReference>:<entityName>
+     *
+     * @return the fully qualified name
+     */
+    String getFullyQualifiedName();
+
+    /**
+     * Gets the category of the persistable. e.g.: "relationship", "entity"
+     *
+     * @return category as a String
+     */
+    String getCategory();
 }
index 207a32c..a393a05 100644 (file)
@@ -27,7 +27,7 @@ import static org.oran.smo.teiv.utils.TiesConstants.TIES_MODEL;
 import static org.jooq.impl.DSL.field;
 
 import java.io.IOException;
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -40,31 +40,32 @@ import org.jooq.Record3;
 import org.jooq.SelectConditionStep;
 import org.jooq.SelectJoinStep;
 import org.springframework.stereotype.Component;
+import lombok.extern.slf4j.Slf4j;
 
-import org.oran.smo.teiv.exception.TiesException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.Module;
 
 @Slf4j
 @Component
 public class PostgresSchemaLoader extends SchemaLoader {
-    private final DSLContext readDataDslContext;
+    private final DSLContext readWriteDataDslContext;
     private final ObjectMapper objectMapper;
 
-    public PostgresSchemaLoader(DSLContext readDataDslContext, ObjectMapper objectMapper) {
-        this.readDataDslContext = readDataDslContext;
+    public PostgresSchemaLoader(DSLContext readWriteDataDslContext, ObjectMapper objectMapper) {
+        this.readWriteDataDslContext = readWriteDataDslContext;
         this.objectMapper = objectMapper;
     }
 
     @Override
     protected void loadBidiDbNameMapper() {
         log.debug("Start loading bidirectional DB name mapper");
-        SelectJoinStep<Record> records = readDataDslContext.select().from(String.format(TIES_MODEL, "hash_info"));
+        SelectJoinStep<Record> records = readWriteDataDslContext.select().from(String.format(TIES_MODEL, "hash_info"));
         Map<String, String> hash = new HashMap<>();
         Map<String, String> reverseHash = new HashMap<>();
-        records.forEach(record -> {
-            hash.put((String) record.get("name"), (String) record.get("hashedValue"));
-            reverseHash.put((String) record.get("hashedValue"), (String) record.get("name"));
+        records.forEach(entry -> {
+            hash.put((String) entry.get("name"), (String) entry.get("hashedValue"));
+            reverseHash.put((String) entry.get("hashedValue"), (String) entry.get("name"));
         });
         BidiDbNameMapper.initialize(hash, reverseHash);
         log.debug("BidiDBNameMapper initialized successfully");
@@ -73,15 +74,16 @@ public class PostgresSchemaLoader extends SchemaLoader {
     @Override
     public void loadModules() throws SchemaLoaderException {
         log.debug("Start loading modules");
-        SelectConditionStep<Record> moduleRecords = runMethodSafe(() -> readDataDslContext.select().from(String.format(
-                TIES_MODEL, "module_reference")).where(field("domain").isNotNull()));
+        SelectConditionStep<Record> moduleRecords = runMethodSafe(() -> readWriteDataDslContext.select().from(String.format(
+                TIES_MODEL, "module_reference")).where(field("name").isNotNull()));
         Map<String, Module> moduleMap = new HashMap<>();
         for (Record moduleRecord : moduleRecords) {
             JSONB includedModules = (JSONB) moduleRecord.get("includedModules");
             try {
                 List<String> modules = objectMapper.readValue(includedModules.data(), List.class);
                 Module module = Module.builder().name((String) moduleRecord.get("name")).namespace((String) moduleRecord
-                        .get("namespace")).domain((String) moduleRecord.get("domain")).includedModuleNames(modules).build();
+                        .get("namespace")).domain((String) moduleRecord.get("domain")).includedModuleNames(modules).content(
+                                (String) moduleRecord.get("content")).build();
                 moduleMap.put(module.getName(), module);
             } catch (IOException e) {
                 log.error("Exception occurred while retrieving included modules.", e);
@@ -98,67 +100,75 @@ public class PostgresSchemaLoader extends SchemaLoader {
     @Override
     public void loadEntityTypes() {
         log.debug("Start loading entities");
-        Map<String, EntityType> entityTypeMap = new HashMap<>();
-        Map<String, EntityType.EntityTypeBuilder> entityTypeBuilderMap = new HashMap<>();
-        SelectJoinStep<Record> entityInfoRecords = runMethodSafe(() -> readDataDslContext.select().from(String.format(
+        List<EntityType> entityTypes = new ArrayList<>();
+        final String tableName = "table_name";
+        final String columnName = "column_name";
+        SelectConditionStep<Record3<Object, Object, Object>> tableDetails = runMethodSafe(() -> readWriteDataDslContext
+                .select(field(tableName), field(columnName), field("udt_name")).from("information_schema.columns").where(
+                        field("table_schema").equal(TIES_DATA_SCHEMA)));
+
+        SelectJoinStep<Record> entityInfoRecords = runMethodSafe(() -> readWriteDataDslContext.select().from(String.format(
                 TIES_MODEL, "entity_info")));
+
         entityInfoRecords.forEach(entityInfoRecord -> {
             String name = (String) entityInfoRecord.get("name");
-            EntityType.EntityTypeBuilder entityTypeBuilder = EntityType.builder().name(name).module(SchemaRegistry
-                    .getModuleByName((String) entityInfoRecord.get("moduleReferenceName")));
-            entityTypeBuilderMap.put(name, entityTypeBuilder);
-        });
-        //load attributes
-        String tableName = "table_name";
-        String columnName = "column_name";
-        SelectConditionStep<Record3<Object, Object, Object>> record3s = runMethodSafe(() -> readDataDslContext.select(field(
-                tableName), field(columnName), field("udt_name")).from("information_schema.columns").where(field(
-                        "table_schema").equal(TIES_DATA_SCHEMA)));
-        entityTypeBuilderMap.keySet().forEach(entityName -> {
+            final String storedAt = (String) entityInfoRecord.get("storedAt");
+
+            //load attributes
             Map<String, DataType> fields = new HashMap<>();
-            record3s.stream().filter(record3 -> entityName.equals(getModelledName((String) record3.get(tableName))))
+            tableDetails.stream().filter(record3 -> storedAt.equals(getModelledName((String) record3.get(tableName))))
                     .forEach(record3 -> {
                         String colName = getModelledName((String) record3.get(columnName));
                         fields.put(colName, DataType.fromDbDataType((String) record3.get("udt_name")));
                     });
-            entityTypeBuilderMap.get(entityName).fields(Collections.unmodifiableMap(fields));
-        });
 
-        for (var entityTypeBuilder : entityTypeBuilderMap.entrySet()) {
-            entityTypeMap.put(entityTypeBuilder.getKey(), entityTypeBuilder.getValue().build());
-        }
+            final EntityType entityType = EntityType.builder().name(name).tableName(storedAt).fields(fields).module(
+                    SchemaRegistry.getModuleByName((String) entityInfoRecord.get("moduleReferenceName"))).build();
+            entityTypes.add(entityType);
+        });
 
-        SchemaRegistry.initializeEntityTypes(entityTypeMap);
+        SchemaRegistry.initializeEntityTypes(entityTypes);
         log.debug("Entities initialized successfully");
     }
 
     @Override
-    public void loadRelationTypes() {
+    public void loadRelationTypes() throws SchemaLoaderException {
         log.debug("Start loading relations");
-        Map<String, RelationType> relationTypeMap = new HashMap<>();
-        SelectJoinStep<Record> relationInfoResult = runMethodSafe(() -> readDataDslContext.select().from(String.format(
+        List<RelationType> relationTypes = new ArrayList<>();
+        SelectJoinStep<Record> relationInfoResult = runMethodSafe(() -> readWriteDataDslContext.select().from(String.format(
                 TIES_MODEL, "relationship_info")));
-        relationInfoResult.forEach(result -> {
+        for (Record entry : relationInfoResult) {
             //build associations
-            Association aSideAssociation = Association.builder().name(((String) result.get("aSideAssociationName")))
-                    .minCardinality((long) (result.get("aSideMinCardinality"))).maxCardinality((long) (result.get(
+            Association aSideAssociation = Association.builder().name(((String) entry.get("aSideAssociationName")))
+                    .minCardinality((long) (entry.get("aSideMinCardinality"))).maxCardinality((long) (entry.get(
                             "aSideMaxCardinality"))).build();
-            Association bSideAssociation = Association.builder().name(((String) result.get("bSideAssociationName")))
-                    .minCardinality((long) (result.get("bSideMinCardinality"))).maxCardinality((long) (result.get(
+            Association bSideAssociation = Association.builder().name(((String) entry.get("bSideAssociationName")))
+                    .minCardinality((long) (entry.get("bSideMinCardinality"))).maxCardinality((long) (entry.get(
                             "bSideMaxCardinality"))).build();
 
-            RelationType relationType = RelationType.builder().name((String) result.get("name")).aSideAssociation(
-                    aSideAssociation).aSide(SchemaRegistry.getEntityTypeByName((String) result.get("aSideMOType")))
-                    .bSideAssociation(bSideAssociation).bSide(SchemaRegistry.getEntityTypeByName((String) result.get(
-                            "bSideMOType"))).relationshipStorageLocation(RelationshipDataLocation.valueOf((String) result
-                                    .get("relationshipDataLocation"))).connectsSameEntity((Boolean) (result.get(
-                                            "connectSameEntity"))).module(SchemaRegistry.getModuleByName((String) result
-                                                    .get("moduleReferenceName"))).build();
-            relationTypeMap.put(relationType.getName(), relationType);
-        });
+            final EntityType aSide;
+            final EntityType bSide;
+            try {
+                aSide = SchemaRegistry.getEntityTypeByModuleAndName((String) entry.get("aSideModule"), (String) entry.get(
+                        "aSideMOType"));
+                bSide = SchemaRegistry.getEntityTypeByModuleAndName((String) entry.get("bSideModule"), (String) entry.get(
+                        "bSideMOType"));
+            } catch (SchemaRegistryException e) {
+                log.error("Error while getting aside / bSide entity type.", e);
+                throw new SchemaLoaderException(e.getMessage(), e.getCause());
+            }
+
+            RelationType relationType = RelationType.builder().name((String) entry.get("name")).aSideAssociation(
+                    aSideAssociation).aSide(aSide).bSideAssociation(bSideAssociation).bSide(bSide)
+                    .relationshipStorageLocation(RelationshipDataLocation.valueOf((String) entry.get(
+                            "relationshipDataLocation"))).connectsSameEntity((Boolean) (entry.get("connectSameEntity")))
+                    .tableName((String) entry.get("storedAt")).module(SchemaRegistry.getModuleByName((String) entry.get(
+                            "moduleReferenceName"))).build();
+            relationTypes.add(relationType);
+        }
 
         //load registry
-        SchemaRegistry.initializeRelationTypes(relationTypeMap);
+        SchemaRegistry.initializeRelationTypes(relationTypes);
         log.debug("Relations initialized successfully");
     }
 
index 6f64579..546bffe 100644 (file)
  */
 package org.oran.smo.teiv.schema;
 
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
 import static org.oran.smo.teiv.schema.BidiDbNameMapper.getDbName;
 import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
+import static org.jooq.impl.DSL.field;
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
 import static org.oran.smo.teiv.utils.TiesConstants.CONSUMER_DATA_PREFIX;
+import static org.oran.smo.teiv.utils.TiesConstants.DECORATORS;
 import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
 import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
-import static org.oran.smo.teiv.utils.TiesConstants.REL_FK;
 import static org.oran.smo.teiv.utils.TiesConstants.SOURCE_IDS;
 import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.jooq.impl.DSL.field;
+import org.oran.smo.teiv.exposure.spi.Module;
 
 import java.util.List;
 import java.util.Map;
 
-import org.jooq.Field;
-import org.jooq.JSONB;
-
 import lombok.Builder;
-import lombok.Getter;
 import lombok.Singular;
-import lombok.ToString;
+import lombok.Value;
+import org.jooq.Field;
 
-@Getter
+@Value
 @Builder
-@ToString
 public class RelationType implements Persistable {
     private static final String REL_ID_COL_PREFIX = "REL_ID_%s";
     private static final String REL_FK_COL_PREFIX = "REL_FK_%s";
     private static final String A_SIDE_PREFIX = "aSide_%s";
     private static final String B_SIDE_PREFIX = "bSide_%s";
     private static final String REL_SOURCE_IDS_COL_PREFIX = "REL_CD_sourceIds_%s";
-
-    private String name;
-    private Association aSideAssociation;
-    private EntityType aSide;
-    private Association bSideAssociation;
-    private EntityType bSide;
+    private static final String REL_CLASSIFIERS_COL_PREFIX = "REL_CD_classifiers_%s";
+    private static final String REL_DECORATORS_COL_PREFIX = "REL_CD_decorators_%s";
+
+    String name;
+    Association aSideAssociation;
+    EntityType aSide;
+    Association bSideAssociation;
+    EntityType bSide;
     @Singular
-    private Map<String, DataType> attributes;
-    private boolean connectsSameEntity;
-    private RelationshipDataLocation relationshipStorageLocation;
-    private Module module;
+    Map<String, DataType> attributes;
+    boolean connectsSameEntity;
+    RelationshipDataLocation relationshipStorageLocation;
+    String tableName;
+    Module module;
 
     @Override
     public String getTableName() {
-        return switch (relationshipStorageLocation) {
-            case RELATION -> String.format(TIES_DATA, getDbName(name));
-            case A_SIDE -> aSide.getTableName();
-            case B_SIDE -> bSide.getTableName();
-        };
+        return String.format(TIES_DATA, getDbName(this.tableName));
     }
 
     @Override
@@ -81,17 +79,28 @@ public class RelationType implements Persistable {
     }
 
     @Override
-    public List<String> getAttributeColumnsWithId() {
+    public String getIdColumnNameWithTableName() {
+        if (relationshipStorageLocation.equals(RELATION)) {
+            return getTableName() + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME);
+        } else {
+            return getTableName() + "." + String.format(QUOTED_STRING, getDbName(String.format(REL_ID_COL_PREFIX, name)));
+        }
+    }
+
+    @Override
+    public Map<Field, DataType> getSpecificAttributeColumns(List<String> attributes) {
         // attributes are yet to be supported for relations
-        return List.of();
+        return Map.of();
     }
 
     @Override
     public List<Field> getAllFieldsWithId() {
-        return List.of(field(getTableName() + "." + String.format(QUOTED_STRING, aSideColumnName())), field(
-                getTableName() + "." + String.format(QUOTED_STRING, bSideColumnName())), field(getTableName() + "." + String
-                        .format(QUOTED_STRING, getIdColumnName())), field(getTableName() + "." + String.format(
-                                QUOTED_STRING, getSourceIdsColumnName()), JSONB.class));
+        List<Field> result = Persistable.super.getAllFieldsWithId();
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, aSideColumnName())).as(hashAlias(
+                getFullyQualifiedName() + ".aSide")));
+        result.add(field(getTableName() + "." + String.format(QUOTED_STRING, bSideColumnName())).as(hashAlias(
+                getFullyQualifiedName() + ".bSide")));
+        return result;
     }
 
     /**
@@ -114,6 +123,24 @@ public class RelationType implements Persistable {
         }
     }
 
+    @Override
+    public String getClassifiersColumnName() {
+        if (relationshipStorageLocation.equals(RELATION)) {
+            return getDbName(CONSUMER_DATA_PREFIX + CLASSIFIERS);
+        } else {
+            return getDbName(String.format(REL_CLASSIFIERS_COL_PREFIX, name));
+        }
+    }
+
+    @Override
+    public String getDecoratorsColumnName() {
+        if (relationshipStorageLocation.equals(RELATION)) {
+            return getDbName(CONSUMER_DATA_PREFIX + DECORATORS);
+        } else {
+            return getDbName(String.format(REL_DECORATORS_COL_PREFIX, name));
+        }
+    }
+
     /**
      * Gets the aSide column name of the relation.
      *
@@ -140,31 +167,9 @@ public class RelationType implements Persistable {
         };
     }
 
-    /**
-     * Gets the fully qualified name of the entity.
-     * Format - <moduleNameReference>:<relationName>
-     *
-     * @return the fully qualified name
-     */
+    @Override
     public String getFullyQualifiedName() {
-        return String.format("%s:%s", this.getModule().getName(), this.getName());
-    }
-
-    public String getTableNameWithoutSchema() {
-        return switch (relationshipStorageLocation) {
-            case RELATION -> name;
-            case A_SIDE -> aSide.getName();
-            case B_SIDE -> bSide.getName();
-        };
-    }
-
-    /**
-     * Gets the bSide relationship foreign key column name for the entity.
-     *
-     * @return the bSide foreign key column name, or null if not found.
-     */
-    public String getReferenceColumnOnBSide() {
-        return getDbName(REL_FK + this.getBSideAssociation().getName());
+        return String.format("%s:%s", module.getName(), name);
     }
 
     public String getNotStoringSideTableName() {
@@ -199,4 +204,13 @@ public class RelationType implements Persistable {
         };
     }
 
+    public List<String> getAttributeNames() {
+        // attributes are yet to be supported for relations
+        return List.of();
+    }
+
+    @Override
+    public String getCategory() {
+        return "relationship";
+    }
 }
index 0b387d8..19a3532 100644 (file)
  */
 package org.oran.smo.teiv.schema;
 
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.ENTITY_NOT_FOUND_IN_DOMAIN;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.ENTITY_NOT_FOUND_IN_MODULE;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.RELATIONSHIP_NOT_FOUND_IN_DOMAIN;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.RELATIONSHIP_NOT_FOUND_IN_MODULE;
+
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 import org.springframework.cache.annotation.Cacheable;
-
-import jakarta.annotation.Nullable;
 import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
 import lombok.experimental.UtilityClass;
 
+import jakarta.annotation.Nullable;
+
+import org.oran.smo.teiv.utils.TiesConstants;
 import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.Module;
 
+@Slf4j
 @UtilityClass
 public class SchemaRegistry {
     @Getter
     private static Map<String, Module> moduleRegistry;
-    private static Map<String, EntityType> entityTypeRegistry;
-    private static Map<String, RelationType> relationTypeRegistry;
+    @Getter
+    private static List<EntityType> entityTypes;
+    @Getter
+    private static List<RelationType> relationTypes;
 
     //Modules section
-
     /**
      * Initializes the modules. Once set cannot be overridden.
      *
@@ -74,8 +86,8 @@ public class SchemaRegistry {
      * @return the {@link Module}
      */
     public static Module getModuleByDomain(String domain) {
-        return moduleRegistry.values().stream().filter(module -> module.getDomain().equals(domain)).findFirst().orElseThrow(
-                () -> TiesException.unknownDomain(domain, getDomains()));
+        return moduleRegistry.values().stream().filter(module -> module.getDomain() != null && module.getDomain().equals(
+                domain)).findFirst().orElseThrow(() -> TiesException.unknownDomain(domain, getDomains()));
     }
 
     /**
@@ -87,7 +99,7 @@ public class SchemaRegistry {
      */
     public static List<String> getIncludedDomains(String domain) {
         return getModuleByDomain(domain).getIncludedModuleNames().stream().map(moduleName -> getModuleByName(moduleName)
-                .getDomain()).toList();
+                .getDomain()).filter(Objects::nonNull).toList();
     }
 
     /**
@@ -97,47 +109,95 @@ public class SchemaRegistry {
      */
     @Cacheable("availableDomains")
     public static Set<String> getDomains() {
-        return moduleRegistry.values().stream().map(Module::getDomain).collect(Collectors.toCollection(TreeSet::new));
+        return moduleRegistry.values().stream().map(Module::getDomain).filter(Objects::nonNull).collect(Collectors
+                .toCollection(TreeSet::new));
     }
 
     //Entities section
+
     /**
      * Initializes the entity types. Once set cannot be overridden.
      *
      * @param entityTypes
      *     - entity types
      */
-    static void initializeEntityTypes(Map<String, EntityType> entityTypes) {
-        entityTypeRegistry = Collections.unmodifiableMap(entityTypes);
+    static void initializeEntityTypes(final List<EntityType> entityTypes) {
+        entityTypes.sort(Comparator.comparing(EntityType::getName));
+        SchemaRegistry.entityTypes = Collections.unmodifiableList(entityTypes);
     }
 
     /**
-     * Gets the list of supported {@link EntityType} from the entity type registry.
+     * Gets all the supported entity names.
      *
-     * @return the list of {@link EntityType}
+     * @return the list of entity names
      */
-    public static List<EntityType> getEntityTypes() {
-        return entityTypeRegistry.values().stream().toList();
+    public static List<String> getEntityNames() {
+        return entityTypes.stream().map(EntityType::getName).toList();
     }
 
     /**
-     * Gets all the supported entity names from the entity type registry.
+     * Deprecated: Gets the {@link EntityType} by the given name.
      *
-     * @return the set of entity names
+     * @param name
+     *     - entity name
+     * @return the {@link EntityType}
+     * @deprecated Use {@link #getEntityTypeByDomainAndName(String, String)} or
+     *     {@link #getEntityTypeByModuleAndName(String, String)} instead.
      */
-    public static Set<String> getEntityNames() {
-        return entityTypeRegistry.keySet();
+    @Nullable
+    @Deprecated(since = "Entity type should be retrieved by supplying the domain or module name")
+    public static EntityType getEntityTypeByName(String name) {
+        return entityTypes.stream().filter(entityType -> entityType.getName().equals(name)).findFirst().orElseGet(() -> {
+            log.warn("Unknown entity name: {}", name);
+            return null;
+        });
     }
 
     /**
-     * Gets the {@link EntityType} by the given name.
+     * Gets the {@link EntityType} by the given module name and the entity type name.
+     * Since TIES supports TEIV as top level domain on the exposure side, there is possibility to return more than one
+     * EntityType for a given name
+     * with domain as TIEV.
      *
-     * @param name
-     *     - entity name
-     * @return the {@link EntityType}
+     * @param domain
+     *     - name of the domain
+     * @param entityTypeName
+     *     - name of the entityType
+     * @return the list of {@link EntityType}
+     * @throws SchemaRegistryException
+     *     if entity type is not found in the domain
      */
-    public static EntityType getEntityTypeByName(String name) {
-        return entityTypeRegistry.get(name);
+    public static List<EntityType> getEntityTypeByDomainAndName(final String domain, final String entityTypeName)
+            throws SchemaRegistryException {
+        final List<EntityType> matchedEntityTypes = entityTypes.stream().filter(entityType -> entityType.getModule()
+                .getDomain().equals(domain) && entityType.getName().equals(entityTypeName)).toList();
+        if (matchedEntityTypes.isEmpty()) {
+            log.warn("Domain: {} does not contain the entity type: {}", domain, entityTypeName);
+            throw new SchemaRegistryException(ENTITY_NOT_FOUND_IN_DOMAIN, String.format(
+                    "Entity type: %s not found in domain: %s", entityTypeName, domain));
+        }
+        return matchedEntityTypes;
+    }
+
+    /**
+     * Gets the {@link EntityType} by the given module name and the entity type name.
+     *
+     * @param moduleName
+     *     - name of the module
+     * @param entityTypeName
+     *     - name of the entityType
+     * @return the list of {@link EntityType}
+     * @throws SchemaRegistryException
+     *     if entity type is not found in the module
+     */
+    public static EntityType getEntityTypeByModuleAndName(final String moduleName, final String entityTypeName)
+            throws SchemaRegistryException {
+        return entityTypes.stream().filter(entityType -> entityType.getModule().getName().equals(moduleName) && entityType
+                .getName().equals(entityTypeName)).findFirst().orElseThrow(() -> {
+                    log.warn("Module: {} does not contain the entity type: {}", moduleName, entityTypeName);
+                    return new SchemaRegistryException(ENTITY_NOT_FOUND_IN_MODULE, String.format(
+                            "Entity type: %s not found in module: %s", entityTypeName, moduleName));
+                });
     }
 
     /**
@@ -149,7 +209,7 @@ public class SchemaRegistry {
      */
     public static List<EntityType> getEntityTypesByDomain(String domain) {
         List<String> domains = getIncludedDomains(domain);
-        return entityTypeRegistry.values().stream().filter(entityType -> {
+        return entityTypes.stream().filter(entityType -> {
             String entityDomain = entityType.getModule().getDomain();
             return domains.contains(entityDomain) || entityDomain.equals(domain);
         }).toList();
@@ -167,70 +227,90 @@ public class SchemaRegistry {
         return getEntityTypesByDomain(domain).stream().map(EntityType::getName).sorted().toList();
     }
 
-    public static boolean isValidEntityName(String entityName) {
-        return entityTypeRegistry.containsKey(entityName);
-    }
-
-    public static boolean hasDirectHopBetween(String entityName1, String entityName2) {
-        return hasDirectHopBetween(entityName1, entityName2, null);
-    }
-
-    public static boolean hasDirectHopBetween(String entity1, String entity2, List<String> relationships) {
-        return getRelationTypes().stream().anyMatch(relationType -> (relationships == null || relationships
-                .isEmpty() || relationships.contains(relationType.getName())) && ((relationType.getASide().getName().equals(
-                        entity1) && relationType.getBSide().getName().equals(entity2)) || (relationType.getASide().getName()
-                                .equals(entity2) && relationType.getBSide().getName().equals(entity1))));
-    }
+    //Relations section
 
     /**
-     * Gets all managed objects with cmId attribute
+     * Initializes the relation types. Once set cannot be overridden.
      *
-     * @return a list of managed objects
+     * @param relationTypes
+     *     - relation types
      */
-    public static List<EntityType> getEntityTypesWithCmId() {
-        return entityTypeRegistry.values().stream().filter(entityType -> entityType.getFields().containsKey("cmId"))
-                .toList();
+    static void initializeRelationTypes(final List<RelationType> relationTypes) {
+        relationTypes.sort(Comparator.comparing(RelationType::getName));
+        SchemaRegistry.relationTypes = Collections.unmodifiableList(relationTypes);
     }
 
-    //Relations section
     /**
-     * Initializes the relation types. Once set cannot be overridden.
+     * Gets all the supported relation names.
      *
-     * @param relationTypes
-     *     - relation types
+     * @return the list of relation names.
      */
-    static void initializeRelationTypes(Map<String, RelationType> relationTypes) {
-        relationTypeRegistry = Collections.unmodifiableMap(relationTypes);
+    public static List<String> getRelationNames() {
+        return relationTypes.stream().map(RelationType::getName).toList();
     }
 
     /**
-     * Gets all the supported {@link RelationType} from the relation type registry.
+     * Deprecated: Gets the relation type by the given name.
      *
-     * @return the list of {@link RelationType}
+     * @param name
+     *     - relation name
+     * @return the {@link RelationType}
+     * @deprecated Use {@link #getRelationTypeByDomainAndName(String, String)} or
+     *     {@link #getRelationTypeByModuleAndName(String, String)} instead.
      */
-    public static List<RelationType> getRelationTypes() {
-        return relationTypeRegistry.values().stream().toList();
+    @Nullable
+    @Deprecated(since = "Relation type should be retrieved by supplying the domain or module name")
+    public static RelationType getRelationTypeByName(String name) {
+        return relationTypes.stream().filter(entityType -> entityType.getName().equals(name)).findFirst().orElseGet(() -> {
+            log.warn("Unknown relationship name: {}", name);
+            return null;
+        });
     }
 
     /**
-     * Gets all the supported relation names from the relation type registry.
+     * Gets the {@link RelationType} (could be more than one when domain is TEIV) by the given module name and the relation
+     * type
+     * name.
      *
-     * @return the set of relation names.
+     * @param domain
+     *     - name of the domain
+     * @param relationTypeName
+     *     - name of the relation type
+     * @return the list of {@link RelationType}
+     * @throws SchemaRegistryException
+     *     if relation type is not found in the domain
      */
-    public static Set<String> getRelationNames() {
-        return relationTypeRegistry.keySet();
+    public static List<RelationType> getRelationTypeByDomainAndName(final String domain, final String relationTypeName)
+            throws SchemaRegistryException {
+        final List<RelationType> matchedRelationTypes = relationTypes.stream().filter(relationType -> relationType
+                .getModule().getDomain().equals(domain) && relationType.getName().equals(relationTypeName)).toList();
+        if (matchedRelationTypes.isEmpty()) {
+            log.warn("Domain: {} does not contain the relation type: {}", domain, relationTypeName);
+            throw new SchemaRegistryException(RELATIONSHIP_NOT_FOUND_IN_DOMAIN, String.format(
+                    "Relation type: %s not found in domain: %s", relationTypeName, domain));
+        }
+        return matchedRelationTypes;
     }
 
     /**
-     * Gets the relation type by the given name.
+     * Gets the {@link RelationType} by the given module name and the relation type name.
      *
-     * @param relationName
-     *     - relation relationName
+     * @param moduleName
+     *     - name of the module
+     * @param relationTypeName
+     *     - name of the relation type
      * @return the {@link RelationType}
+     * @throws SchemaRegistryException
+     *     if relation type is not found in the module
      */
-    @Nullable
-    public static RelationType getRelationTypeByName(String relationName) {
-        return relationTypeRegistry.get(relationName);
+    public static RelationType getRelationTypeByModuleAndName(final String moduleName, final String relationTypeName)
+            throws SchemaRegistryException {
+        return relationTypes.stream().filter(relationType -> relationType.getModule().getName().equals(
+                moduleName) && relationType.getName().equals(relationTypeName)).findFirst().orElseThrow(() -> {
+                    log.warn("Module: {} does not contain the relation type: {}", moduleName, relationTypeName);
+                    return new SchemaRegistryException(RELATIONSHIP_NOT_FOUND_IN_MODULE, String.format(
+                            "Relation type: %s not found in module: %s", relationTypeName, moduleName));
+                });
     }
 
     /**
@@ -241,7 +321,7 @@ public class SchemaRegistry {
      * @return the list of the {@link RelationType}
      */
     public static List<RelationType> getRelationTypesByEntityName(final String entityName) {
-        return relationTypeRegistry.values().stream().filter(relationType -> relationType.getASide().getName().equals(
+        return relationTypes.stream().filter(relationType -> relationType.getASide().getName().equals(
                 entityName) || relationType.getBSide().getName().equals(entityName)).toList();
     }
 
@@ -251,8 +331,7 @@ public class SchemaRegistry {
 
     public static List<String> getAssociationNamesByEntityName(final String entityName) {
         return getRelationTypesByEntityName(entityName).stream().map(relationType -> {
-            RelationshipDataLocation relDataLocation = relationType.getRelationshipStorageLocation();
-            if (relDataLocation.equals(RelationshipDataLocation.A_SIDE)) {
+            if (relationType.getASide().getName().equals(entityName)) {
                 return relationType.getASideAssociation().getName();
             } else {
                 return relationType.getBSideAssociation().getName();
@@ -269,7 +348,7 @@ public class SchemaRegistry {
      */
     public static List<RelationType> getRelationTypesByDomain(String domain) {
         List<String> includedDomains = getIncludedDomains(domain);
-        return relationTypeRegistry.values().stream().filter(relationType -> {
+        return relationTypes.stream().filter(relationType -> {
             String relDomain = relationType.getModule().getDomain();
             return includedDomains.contains(relDomain) || relDomain.equals(domain);
         }).toList();
@@ -287,34 +366,42 @@ public class SchemaRegistry {
         return getRelationTypesByDomain(domain).stream().map(RelationType::getName).sorted().toList();
     }
 
-    public static boolean doesEntityContainsAttribute(String entityName, String attributeName) {
-        if (entityName == null) {
-            return false;
-        }
-        EntityType entityType = getEntityTypeByName(entityName);
-        if (entityType == null) {
-            return false;
-        }
-        return entityType.getAttributeNames().contains(attributeName);
+    /**
+     * Gets the relation names for a given entity by the given domain.
+     *
+     * @param entityName
+     *     - entity name
+     * @param domain
+     *     - name of the domain
+     * @return the list of relation names
+     */
+    @Cacheable("relationTypesByDomain")
+    public static List<RelationType> getRelationNamesForEntityByDomain(final String entityName, final String domain) {
+        return getRelationTypesByDomain(domain).stream().filter(relationType -> relationType.getASide().getName().equals(
+                entityName) || relationType.getBSide().getName().equals(entityName)).toList();
     }
 
-    public static List<RelationType> getRelationTypesBetweenEntities(String entity1, String entity2,
-            List<String> relationships) {
-        return getRelationTypes().stream().filter(relationType -> (relationships == null || relationships
-                .isEmpty() || relationships.contains(relationType.getName())) && ((relationType.getASide().getName().equals(
-                        entity1) && relationType.getBSide().getName().equals(entity2)) || (relationType.getBSide().getName()
-                                .equals(entity1) && relationType.getASide().getName().equals(entity2)))).toList();
+    public static List<RelationType> getAllRelationNamesByAssociationName(String associationName) {
+        return relationTypes.stream().filter(relationType -> relationType.getASideAssociation().getName().equals(
+                associationName) || relationType.getBSideAssociation().getName().equals(associationName)).toList();
     }
 
-    public static Boolean isEntityPartOfRelationships(String entity, List<String> relationships) {
-        return getRelationTypes().stream().anyMatch(relationType -> relationships.isEmpty() || (relationships.contains(
-                relationType.getName()) && (relationType.getASide().getName().equals(entity) || relationType.getBSide()
-                        .getName().equals(entity))));
+    public static String getReferenceColumnName(RelationType relationType) {
+        if (relationType.getRelationshipStorageLocation().equals(RelationshipDataLocation.A_SIDE)) {
+            return Objects.requireNonNull(relationType).getTableName() + "." + String.format(TiesConstants.QUOTED_STRING,
+                    relationType.bSideColumnName());
+        } else if (relationType.getRelationshipStorageLocation().equals(RelationshipDataLocation.B_SIDE)) {
+            return Objects.requireNonNull(relationType).getTableName() + "." + String.format(TiesConstants.QUOTED_STRING,
+                    relationType.aSideColumnName());
+        }
+        return Objects.requireNonNull(relationType).getTableName() + "." + relationType.getIdColumnName();
     }
 
-    public static String getRelationNameByAssociationName(String associationName) {
-        return getRelationTypes().stream().filter(relationType -> relationType.getASideAssociation().getName().equals(
-                associationName) || relationType.getBSideAssociation().getName().equals(associationName)).map(
-                        RelationType::getName).findFirst().get();
+    public static EntityType getEntityTypeOnAssociationSide(RelationType relationType, String associationName) {
+        boolean isAssociationASide = relationType.getASideAssociation().getName().equals(associationName);
+        if (isAssociationASide) {
+            return relationType.getASide();
+        }
+        return relationType.getBSide();
     }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryErrorCode.java b/teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryErrorCode.java
new file mode 100644 (file)
index 0000000..384b693
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  ============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.teiv.schema;
+
+/**
+ * Enum representing error codes for the Schema Registry.
+ */
+public enum SchemaRegistryErrorCode {
+    ENTITY_NOT_FOUND_IN_DOMAIN,
+    ENTITY_NOT_FOUND_IN_MODULE,
+    RELATIONSHIP_NOT_FOUND_IN_DOMAIN,
+    RELATIONSHIP_NOT_FOUND_IN_MODULE
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryException.java b/teiv/src/main/java/org/oran/smo/teiv/schema/SchemaRegistryException.java
new file mode 100644 (file)
index 0000000..bd4f4d8
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  ============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.teiv.schema;
+
+import lombok.Getter;
+
+/**
+ * Custom exception class for schema registry errors.
+ */
+@Getter
+public class SchemaRegistryException extends Exception {
+    private final SchemaRegistryErrorCode errorCode;
+
+    public SchemaRegistryException(final SchemaRegistryErrorCode errorCode, final String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/schema/YangDataTypes.java b/teiv/src/main/java/org/oran/smo/teiv/schema/YangDataTypes.java
new file mode 100644 (file)
index 0000000..df7e0dd
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  ============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.teiv.schema;
+
+import java.util.Locale;
+
+public enum YangDataTypes {
+    STRING,
+    BOOLEAN,
+    NUMERIC;
+
+    public static YangDataTypes fromYangDataType(final String yangDatatype) {
+        return switch (yangDatatype.toUpperCase(Locale.US)) {
+            case "TEXT" -> STRING;
+            case "BOOLEAN" -> BOOLEAN;
+            case "INT", "DOUBLE" -> NUMERIC;
+            default -> throw new IllegalStateException("Unexpected value: " + yangDatatype.toUpperCase(Locale.US));
+        };
+    }
+
+    public static YangDataTypes fromRequestDataType(final Class<?> requestDatatype) {
+        return switch (requestDatatype.getSimpleName()) {
+            case "String" -> STRING;
+            case "Integer", "Double" -> NUMERIC;
+            case "Boolean" -> BOOLEAN;
+            default -> throw new IllegalStateException("Unexpected value: " + requestDatatype);
+        };
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/service/SchemaCleanUpService.java b/teiv/src/main/java/org/oran/smo/teiv/service/SchemaCleanUpService.java
new file mode 100644 (file)
index 0000000..3396dc8
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ *  ============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.teiv.service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exposure.consumerdata.model.Classifiers;
+import org.oran.smo.teiv.exposure.consumerdata.model.Decorators;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteDecoratorsOperation;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.exposure.spi.DataRepository;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataOperationRegistry;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.service.models.OperationResult;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class SchemaCleanUpService {
+    private final ModelRepository modelRepository;
+    private final DataRepository dataRepository;
+    private final ConsumerDataOperationRegistry consumerDataOperationRegistry;
+    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+    @Value("${spring.caching.consumer-data-ttl-ms}")
+    private long timeToLeave;
+
+    @Async
+    public void cleanUpModule(final String name) {
+
+        boolean cleanUpInProgress = true;
+        long waitInLoop = timeToLeave;
+
+        while (cleanUpInProgress) {
+            try {
+                waitInLoop = (long) (1.2 * waitInLoop);
+                ScheduledFuture<Boolean> resp = executor.schedule(() -> innerCleanUp(name), waitInLoop,
+                        TimeUnit.MILLISECONDS);
+                cleanUpInProgress = resp.get();
+            } catch (InterruptedException ex) {
+                log.error("InterruptedException during [{}] schema deletion: {}", name, ex.getMessage());
+                Thread.currentThread().interrupt();
+            } catch (Exception ex) {
+                log.error("Exception during [{}] schema deletion: {}", name, ex.getMessage(), ex);
+            }
+        }
+
+        modelRepository.deleteModuleByName(name);
+    }
+
+    private boolean innerCleanUp(final String schemaName) {
+        log.info("Start cleanup for {} schema", schemaName);
+
+        boolean shouldRerun = false;
+
+        final Set<String> decorators = dataRepository.getDecoratorsForSchema(schemaName);
+        final Set<String> classifiers = dataRepository.getClassifiersForSchema(schemaName);
+
+        final List<EntityType> entityTypes = new ArrayList<>(SchemaRegistry.getEntityTypes());
+        final List<RelationType> relationTypes = new ArrayList<>(SchemaRegistry.getRelationTypes());
+
+        Collections.shuffle(entityTypes);
+        Collections.shuffle(relationTypes);
+
+        for (EntityType e : entityTypes) {
+            try {
+                deleteClassifiersFromEntity(e, classifiers);
+            } catch (Exception ex) {
+                shouldRerun = true;
+                log.error("Exception during [{}] schema deletion from entity type: {} : {}", schemaName, e, ex.getMessage(),
+                        ex);
+            }
+            try {
+                deleteDecoratorsFromEntity(e, decorators);
+            } catch (Exception ex) {
+                shouldRerun = true;
+                log.error("Exception during [{}] schema deletion from entity type: {} : {}", schemaName, e, ex.getMessage(),
+                        ex);
+            }
+        }
+        for (RelationType r : relationTypes) {
+            try {
+                deleteClassifiersFromRelationship(r, classifiers);
+            } catch (Exception ex) {
+                shouldRerun = true;
+                log.error("Exception during [{}] schema deletion from relationship type: {} : {}", schemaName, r, ex
+                        .getMessage(), ex);
+            }
+            try {
+                deleteDecoratorsFromRelationship(r, decorators);
+            } catch (Exception ex) {
+                shouldRerun = true;
+                log.error("Exception during [{}] schema deletion from relationship type: {} : {}", schemaName, r, ex
+                        .getMessage(), ex);
+            }
+        }
+
+        log.info("Cleanup for {} schema has been finished", schemaName);
+
+        return shouldRerun;
+    }
+
+    private void deleteClassifiersFromEntity(final EntityType entityType, final Set<String> classifiers) {
+        Set<String> idsForDeletion;
+        do {
+            idsForDeletion = new LinkedHashSet<>(dataRepository.getEntityIdsForClassifierDeletion(entityType, classifiers));
+
+            final DeleteClassifiersOperation deleteClassifiersOperation = (DeleteClassifiersOperation) consumerDataOperationRegistry
+                    .getClassifiersOperation(OranTeivClassifier.OperationEnum.DELETE);
+
+            List<OperationResult> results = deleteClassifiersOperation.delete(new Classifiers(new ArrayList<>(classifiers),
+                    new ArrayList<>(idsForDeletion), new ArrayList<>()), entityType);
+        } while (!idsForDeletion.isEmpty());
+    }
+
+    private void deleteDecoratorsFromEntity(final EntityType entityType, final Set<String> decorators) {
+        Set<String> idsForDeletion;
+        do {
+            idsForDeletion = new LinkedHashSet<>(dataRepository.getEntityIdsForDecoratorDeletion(entityType, decorators));
+
+            final Map<String, Object> decoratorsMap = new HashMap<>();
+            for (String decorator : decorators) {
+                decoratorsMap.put(decorator, "");
+            }
+
+            final DeleteDecoratorsOperation deleteDecoratorsOperation = (DeleteDecoratorsOperation) consumerDataOperationRegistry
+                    .getDecoratorsOperation(OranTeivDecorator.OperationEnum.DELETE);
+
+            List<OperationResult> results = deleteDecoratorsOperation.delete(new Decorators(decoratorsMap, new ArrayList<>(
+                    idsForDeletion), new ArrayList<>()), entityType);
+        } while (!idsForDeletion.isEmpty());
+    }
+
+    private void deleteClassifiersFromRelationship(final RelationType relationType, final Set<String> classifiers) {
+        Set<String> idsForDeletion;
+        do {
+            idsForDeletion = new LinkedHashSet<>(dataRepository.getRelationshipIdsForClassifierDeletion(relationType,
+                    classifiers));
+
+            final DeleteClassifiersOperation deleteClassifiersOperation = (DeleteClassifiersOperation) consumerDataOperationRegistry
+                    .getClassifiersOperation(OranTeivClassifier.OperationEnum.DELETE);
+
+            List<OperationResult> results = deleteClassifiersOperation.delete(new Classifiers(new ArrayList<>(classifiers),
+                    new ArrayList<>(), new ArrayList<>(idsForDeletion)), relationType);
+        } while (!idsForDeletion.isEmpty());
+    }
+
+    private void deleteDecoratorsFromRelationship(final RelationType relationType, final Set<String> decorators) {
+        Set<String> idsForDeletion;
+        do {
+            idsForDeletion = new LinkedHashSet<>(dataRepository.getRelationshipIdsForDecoratorDeletion(relationType,
+                    decorators));
+
+            final Map<String, Object> decoratorsMap = new HashMap<>();
+            for (String decorator : decorators) {
+                decoratorsMap.put(decorator, "");
+            }
+
+            final DeleteDecoratorsOperation deleteDecoratorsOperation = (DeleteDecoratorsOperation) consumerDataOperationRegistry
+                    .getDecoratorsOperation(OranTeivDecorator.OperationEnum.DELETE);
+
+            List<OperationResult> results = deleteDecoratorsOperation.delete(new Decorators(decoratorsMap,
+                    new ArrayList<>(), new ArrayList<>(idsForDeletion)), relationType);
+        } while (!idsForDeletion.isEmpty());
+    }
+}
index bb636ae..2e94883 100644 (file)
@@ -21,7 +21,6 @@
 package org.oran.smo.teiv.service;
 
 import static org.oran.smo.teiv.schema.BidiDbNameMapper.getDbName;
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
 import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
 import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
 import static org.oran.smo.teiv.utils.TiesConstants.FOREIGN_KEY_VIOLATION_ERROR_CODE;
@@ -44,6 +43,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
+import org.jooq.Field;
 import org.oran.smo.teiv.exception.IllegalManyToManyRelationshipUpdateException;
 import org.oran.smo.teiv.exception.IllegalOneToManyRelationshipUpdateException;
 import org.jooq.Configuration;
@@ -51,6 +51,7 @@ import org.jooq.Condition;
 import org.jooq.DSLContext;
 import org.jooq.JSON;
 import org.jooq.exception.DataAccessException;
+import org.oran.smo.teiv.utils.JooqTypeConverter;
 import org.springframework.stereotype.Component;
 
 import lombok.AllArgsConstructor;
@@ -72,7 +73,6 @@ import org.oran.smo.teiv.service.cloudevent.data.Entity;
 import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
 import org.oran.smo.teiv.service.cloudevent.data.Relationship;
 
-import org.oran.smo.teiv.utils.ConvertToJooqTypeUtil;
 import org.oran.smo.teiv.utils.TiesConstants;
 import org.oran.smo.teiv.utils.schema.Geography;
 
@@ -89,8 +89,7 @@ public class TiesDbOperations {
     /**
      * Insert or update a row in the given table.
      * <p>
-     * Note: Free version of Jooq doesn't support spatial types like Geography. Instead of that the OTHER type is used.
-     * Instead of that the OTHER type is used.
+     * Note: Free version of Jooq doesn't support spatial types like Geography. Instead of that the OTHER type is used
      * </p>
      *
      * @param context
@@ -98,26 +97,30 @@ public class TiesDbOperations {
      * @param tableName
      *     Name of the database table to use.
      * @param values
-     *     A map of column name and value pairs. The value is converted
-     *     to the corresponding Postgres type based on the
+     *     A map of column name and value pairs. The value is converted to the corresponding Postgres type based on the
      *     dynamic type of the value. For
-     *     example: <"column1", 5L> means that the value 5 should be
-     *     inserted to the column1 as a BIGINT.
+     *     example: <"column1", 5L> means that the value 5 should be inserted to the column1 as a BIGINT.
      * @return The number of modified rows.
      */
 
     public int merge(DSLContext context, String tableName, Map<String, Object> values) {
-        Map<String, Object> valuesToMerge = new HashMap<>(values.size());
+        Map<String, Object> valuesToInsert = new HashMap<>(values.size());
         values.forEach((key, value) -> {
             if (value instanceof Geography geographyValue) {
-                valuesToMerge.put(key, field("'" + geographyValue + "'", OTHER));
+                valuesToInsert.put(key, field("'" + geographyValue + "'", OTHER));
             } else {
-                valuesToMerge.put(key, value);
+                valuesToInsert.put(key, value);
             }
         });
-
-        return context.insertInto(table(tableName)).set(valuesToMerge).onConflict(field(ID_COLUMN_NAME)).doUpdate().set(
-                valuesToMerge).execute();
+        Map<String, Object> valuesToUpdate = new HashMap<>(valuesToInsert);
+        valuesToUpdate.remove(ID_COLUMN_NAME);
+        if (valuesToUpdate.isEmpty()) {
+            return context.insertInto(table(tableName)).set(valuesToInsert).onConflict(field(ID_COLUMN_NAME)).doNothing()
+                    .execute();
+        } else {
+            return context.insertInto(table(tableName)).set(valuesToInsert).onConflict(field(ID_COLUMN_NAME)).doUpdate()
+                    .set(valuesToUpdate).execute();
+        }
     }
 
     public List<OperationResult> deleteEntity(DSLContext context, EntityType entityType, String entityId) {
@@ -127,7 +130,7 @@ public class TiesDbOperations {
         int affectedRows = context.delete(table(entityType.getTableName())).where(field(ID_COLUMN_NAME).eq(entityId))
                 .execute();
         if (affectedRows > 0) {
-            result.add(new OperationResult(entityId, entityType.getName(), null));
+            result.add(OperationResult.createEntityOperationResult(entityId, entityType.getName()));
         }
         return result;
     }
@@ -141,14 +144,14 @@ public class TiesDbOperations {
         List<OperationResult> relationshipList = context.select(field(String.format(QUOTED_STRING, relationType
                 .getIdColumnName()), String.class)).from(table(relationType.getTableName())).where(field(String.format(
                         QUOTED_STRING, manySideEntityIdColumn)).eq(manySideEntityId)).forUpdate().fetchInto(String.class)
-                .stream().filter(Objects::nonNull).map(id -> new OperationResult(id, extractTypeFromColumn(
-                        oneSideEntityIdColumn), null)).collect(Collectors.toList());
+                .stream().filter(Objects::nonNull).map(id -> OperationResult.createRelationshipOperationResult(id,
+                        relationType.getName())).collect(Collectors.toList());
         if (relationshipList.isEmpty()) {
             return relationshipList;
         } else {
             int updateResult = context.update(table(relationType.getTableName())).setNull(field(String.format(QUOTED_STRING,
                     relationType.getIdColumnName()))).setNull(field(String.format(QUOTED_STRING, oneSideEntityIdColumn)))
-                    .set(field(String.format(QUOTED_STRING, relationType.getSourceIdsColumnName())), ConvertToJooqTypeUtil
+                    .set(field(String.format(QUOTED_STRING, relationType.getSourceIdsColumnName())), JooqTypeConverter
                             .toJsonb(List.of())).where(field(String.format(QUOTED_STRING, manySideEntityIdColumn)).eq(
                                     manySideEntityId)).execute();
             return updateResult > 0 ? relationshipList : List.of();
@@ -164,31 +167,31 @@ public class TiesDbOperations {
 
         int affectedRows = context.update(table(relationType.getTableName())).setNull(field(String.format(QUOTED_STRING,
                 relationType.getIdColumnName()))).setNull(field(String.format(QUOTED_STRING, oneSideEntityIdColumn))).set(
-                        field(String.format(QUOTED_STRING, relationType.getSourceIdsColumnName())), ConvertToJooqTypeUtil
+                        field(String.format(QUOTED_STRING, relationType.getSourceIdsColumnName())), JooqTypeConverter
                                 .toJsonb(List.of())).where(field(String.format(QUOTED_STRING, relationType
                                         .getIdColumnName())).eq(relationshipId)).execute();
         return affectedRows > 0 ?
-                Optional.of(new OperationResult(relationshipId, extractTypeFromColumn(oneSideEntityIdColumn), null)) :
+                Optional.of(OperationResult.createRelationshipOperationResult(relationshipId, relationType.getName())) :
                 Optional.empty();
     }
 
-    public List<OperationResult> deleteManyToManyRelationByEntityId(DSLContext context, String tableName, String entityId,
-            String aSideColumnName, String bSideColumnName) {
-        List<String> deletedIds = context.delete(table(tableName)).where(field(String.format(QUOTED_STRING,
-                aSideColumnName)).eq(entityId).or(field(String.format(QUOTED_STRING, bSideColumnName)).eq(entityId)))
-                .returning(field(TiesConstants.ID_COLUMN_NAME)).fetch().getValues(field(TiesConstants.ID_COLUMN_NAME),
-                        String.class);
+    public List<OperationResult> deleteManyToManyRelationByEntityId(DSLContext context, RelationType relationType,
+            String entityId, String aSideColumnName, String bSideColumnName) {
+        List<String> deletedIds = context.delete(table((relationType.getTableName()))).where(field(String.format(
+                QUOTED_STRING, aSideColumnName)).eq(entityId).or(field(String.format(QUOTED_STRING, bSideColumnName)).eq(
+                        entityId))).returning(field(TiesConstants.ID_COLUMN_NAME)).fetch().getValues(field(
+                                TiesConstants.ID_COLUMN_NAME), String.class);
 
-        return deletedIds.stream().map(id -> new OperationResult(id, extractTypeFromTable(tableName), null)).collect(
-                Collectors.toList());
+        return deletedIds.stream().map(id -> OperationResult.createRelationshipOperationResult(id, relationType.getName()))
+                .collect(Collectors.toList());
     }
 
-    public Optional<OperationResult> deleteManyToManyRelationByRelationId(DSLContext context, String tableName,
+    public Optional<OperationResult> deleteManyToManyRelationByRelationId(DSLContext context, RelationType relationType,
             String relationshipId) {
-
-        int affectedRows = context.delete(table(tableName)).where(field(ID_COLUMN_NAME).eq(relationshipId)).execute();
+        int affectedRows = context.delete(table(relationType.getTableName())).where(field(ID_COLUMN_NAME).eq(
+                relationshipId)).execute();
         return affectedRows > 0 ?
-                Optional.of(new OperationResult(relationshipId, extractTypeFromTable(tableName), null)) :
+                Optional.of(OperationResult.createRelationshipOperationResult(relationshipId, relationType.getName())) :
                 Optional.empty();
     }
 
@@ -209,18 +212,11 @@ public class TiesDbOperations {
         return results;
     }
 
-    public List<String> selectByCmHandle(DSLContext context, String tableName, String cmHandle) {
-        String path = "$.** ? (@.cmHandle == \"" + cmHandle + "\")";
-        return context.select(field(String.format(QUOTED_STRING, "id"), String.class)).from(tableName).where(jsonExists(
-                field(String.format(QUOTED_STRING, "cmId"), JSON.class), path)).fetch().getValues(field(String.format(
-                        QUOTED_STRING, "id"), String.class));
-    }
-
     public List<String> selectByCmHandleFormSourceIds(DSLContext context, String tableName, String cmHandle) {
-        String path = String.format("$[*] ? (@ == \"urn:cmHandle:/%s\")", cmHandle);
+        String path = String.format("$[*] ? (@ == \"urn:cmHandle:%s\")", cmHandle);
         return context.select(field(String.format(QUOTED_STRING, "id"), String.class)).from(tableName).where(jsonExists(
-                field(String.format(QUOTED_STRING, "CD_sourceIds"), JSON.class), path)).fetch().getValues(field(String
-                        .format(QUOTED_STRING, "id"), String.class));
+                field(String.format(QUOTED_STRING, "CD_sourceIds"), JSON.class), path)).orderBy(field(String.format(
+                        QUOTED_STRING, "id"))).fetch().getValues(field(String.format(QUOTED_STRING, "id"), String.class));
     }
 
     private Consumer<DSLContext> getEntityOperation(Entity entity, List<OperationResult> results)
@@ -235,22 +231,22 @@ public class TiesDbOperations {
                         "Received field: %s isn't a valid field of entity type: %s", entry.getKey(), entity.getType()));
             }
             switch (dataType) {
-                case GEOGRAPHIC -> dbMap.put(getDbName(entry.getKey()), ConvertToJooqTypeUtil.toGeography(entry
-                        .getValue()));
-                case CONTAINER -> dbMap.put(getDbName(entry.getKey()), ConvertToJooqTypeUtil.toJsonb(entry.getValue()));
-                case PRIMITIVE, DECIMAL, BIGINT -> dbMap.put(getDbName(entry.getKey()), entry.getValue());
+                case GEOGRAPHIC -> dbMap.put(getDbName(entry.getKey()), JooqTypeConverter.toGeography(entry.getValue()));
+                case CONTAINER -> dbMap.put(getDbName(entry.getKey()), JooqTypeConverter.toJsonb(entry.getValue()));
+                case PRIMITIVE, DECIMAL, INTEGER, BIGINT -> dbMap.put(getDbName(entry.getKey()), entry.getValue());
             }
         }
         dbMap.put(ID_COLUMN_NAME, entity.getId());
         if (entity.getSourceIds() != null) {
-            dbMap.put(entityType.getSourceIdsColumnName(), ConvertToJooqTypeUtil.toJsonb(entity.getSourceIds()));
+            dbMap.put(entityType.getSourceIdsColumnName(), JooqTypeConverter.toJsonb(entity.getSourceIds()));
         }
         return dslContext -> {
             int affectedRows = merge(dslContext, entityType.getTableName(), dbMap);
             if (affectedRows > 0) {
                 dbMap.remove(ID_COLUMN_NAME);
                 dbMap.remove(entityType.getSourceIdsColumnName());
-                results.add(new OperationResult(entity.getId(), entity.getType(), dbMap));
+                results.add(OperationResult.createEntityOperationResult(entity.getId(), entity.getType(), dbMap, entity
+                        .getSourceIds()));
             }
         };
     }
@@ -265,7 +261,7 @@ public class TiesDbOperations {
         dbMap.put(relationType.aSideColumnName(), relationship.getASide());
         dbMap.put(relationType.bSideColumnName(), relationship.getBSide());
         if (relationship.getSourceIds() != null) {
-            dbMap.put(relationType.getSourceIdsColumnName(), ConvertToJooqTypeUtil.toJsonb(relationship.getSourceIds()));
+            dbMap.put(relationType.getSourceIdsColumnName(), JooqTypeConverter.toJsonb(relationship.getSourceIds()));
         }
 
         if (relationshipDataLocation == RELATION) {
@@ -294,16 +290,17 @@ public class TiesDbOperations {
             List<OperationResult> results, RelationType relationType, Map<String, Object> dbMap) {
         AtomicBoolean isManySideEntityMissingAtTheBeginning = new AtomicBoolean(false);
         try {
-            dslContext.dsl().transaction((Configuration nested) -> updateOneToManyRelationship(nested.dsl(), relationship,
-                    relationType, dbMap).ifPresentOrElse(results::add, () -> {
-                        Record manySideRow = selectByIdForUpdate(relationType.getTableName(), ID_COLUMN_NAME, relationship
-                                .getStoringSideEntityId(), dslContext);
+            dslContext.dsl().transaction((Configuration nested) -> updateRelationshipInEntityTable(nested.dsl(),
+                    relationship, relationType, dbMap).ifPresentOrElse(results::add, () -> {
+                        Record manySideRow = selectColumnsByIdForUpdate(List.of(relationType.aSideColumnName(), relationType
+                                .bSideColumnName(), relationType.getIdColumnName()), relationType.getTableName(),
+                                ID_COLUMN_NAME, relationship.getStoringSideEntityId(), dslContext);
                         if (manySideRow == null) {
                             isManySideEntityMissingAtTheBeginning.set(true);
                             createMissingStoringSideEntity(dslContext, relationship, relationType);
                             addEntityToOperationResults(results, relationship.getStoringSideEntityId(), relationType
                                     .getStoringSideEntityType());
-                            updateOneToManyRelationship(dslContext, relationship, relationType, dbMap).ifPresentOrElse(
+                            updateRelationshipInEntityTable(dslContext, relationship, relationType, dbMap).ifPresentOrElse(
                                     results::add, () -> {
                                         throw new IllegalOneToManyRelationshipUpdateException(relationship, true);
                                     });
@@ -323,7 +320,7 @@ public class TiesDbOperations {
                 createMissingNotStoringSideEntity(dslContext, relationship, relationType);
                 addEntityToOperationResults(results, relationship.getNotStoringSideEntityId(), relationType
                         .getNotStoringSideEntityType());
-                updateOneToManyRelationship(dslContext, relationship, relationType, dbMap).ifPresentOrElse(results::add,
+                updateRelationshipInEntityTable(dslContext, relationship, relationType, dbMap).ifPresentOrElse(results::add,
                         () -> {
                             throw new IllegalOneToManyRelationshipUpdateException(relationship, false);
                         });
@@ -333,18 +330,19 @@ public class TiesDbOperations {
         }
     }
 
-    private Optional<OperationResult> updateOneToManyRelationship(DSLContext dslContext, Relationship relationship,
+    private Optional<OperationResult> updateRelationshipInEntityTable(DSLContext dslContext, Relationship relationship,
             RelationType relationType, Map<String, Object> values) {
         Condition condition = field(ID_COLUMN_NAME).eq(relationship.getStoringSideEntityId()).and(field(name(relationType
                 .getIdColumnName())).isNull().or(field(name(relationType.getIdColumnName())).eq(relationship.getId()).and(
                         field(name(relationType.getNotStoringSideEntityIdColumnNameInStoringSideTable())).eq(relationship
                                 .getNotStoringSideEntityId()))));
-
-        int numberOfUpdatedRows = dslContext.update(table(relationType.getTableName())).set(values).where(condition)
+        Map<String, Object> valuesToUpdate = new HashMap<>(values);
+        valuesToUpdate.remove(ID_COLUMN_NAME);
+        int numberOfUpdatedRows = dslContext.update(table(relationType.getTableName())).set(valuesToUpdate).where(condition)
                 .execute();
 
         return numberOfUpdatedRows != 0 ?
-                Optional.of(OperationResult.createFromRelationship(relationship)) :
+                Optional.of(OperationResult.createRelationshipOperationResult(relationship)) :
                 Optional.empty();
 
     }
@@ -366,14 +364,17 @@ public class TiesDbOperations {
     }
 
     private void mergeManyToManyRelationship(DSLContext dslContext, Relationship relationship,
-            List<OperationResult> results, RelationType relationType, Map<String, Object> dbMap) {
-        int affectedRows = dslContext.insertInto(table(relationType.getTableName())).set(dbMap).onConflict(field(
-                relationType.getIdColumnName())).doUpdate().set(dbMap).where(field(relationType.getTableName() + "." + name(
+            List<OperationResult> results, RelationType relationType, Map<String, Object> valuesToInsert) {
+        String primaryKeyColumn = relationType.getIdColumnName();
+        Map<String, Object> valuesToUpdate = new HashMap<>(valuesToInsert);
+        valuesToUpdate.remove(primaryKeyColumn);
+        int affectedRows = dslContext.insertInto(table(relationType.getTableName())).set(valuesToInsert).onConflict(field(
+                primaryKeyColumn)).doUpdate().set(valuesToUpdate).where(field(relationType.getTableName() + "." + name(
                         relationType.aSideColumnName())).eq(relationship.getASide()).and(field(relationType
                                 .getTableName() + "." + name(relationType.bSideColumnName())).eq(relationship.getBSide())))
                 .execute();
         if (affectedRows > 0) {
-            results.add(OperationResult.createFromRelationship(relationship));
+            results.add(OperationResult.createRelationshipOperationResult(relationship));
         } else {
             throw new IllegalManyToManyRelationshipUpdateException(relationship);
         }
@@ -387,10 +388,10 @@ public class TiesDbOperations {
         String bSideId = relationship.getBSide();
 
         if (createMissingEntity(aSideTableName, ID_COLUMN_NAME, aSideId, dslContext) == 1) {
-            results.add(new OperationResult(aSideId, relationType.getASide().getName(), new HashMap<>()));
+            results.add(OperationResult.createEntityOperationResult(aSideId, relationType.getASide().getName()));
         }
         if (createMissingEntity(bSideTableName, ID_COLUMN_NAME, bSideId, dslContext) == 1) {
-            results.add(new OperationResult(bSideId, relationType.getBSide().getName(), new HashMap<>()));
+            results.add(OperationResult.createEntityOperationResult(bSideId, relationType.getBSide().getName()));
         }
     }
 
@@ -404,8 +405,8 @@ public class TiesDbOperations {
                     relationType.aSideColumnName() :
                     relationType.bSideColumnName();
             if (relationType.getRelationshipStorageLocation() == RELATION) {
-                deletedIds.addAll(deleteManyToManyRelationByEntityId(dslContext, relationType.getTableName(), entityId,
-                        relationType.aSideColumnName(), relationType.bSideColumnName()));
+                deletedIds.addAll(deleteManyToManyRelationByEntityId(dslContext, relationType, entityId, relationType
+                        .aSideColumnName(), relationType.bSideColumnName()));
 
             } else {
                 deletedIds.addAll(deleteRelationshipByManySideEntityId(dslContext, entityId, columnNameForWhereCondition,
@@ -432,25 +433,18 @@ public class TiesDbOperations {
         createMissingEntity(relationType.getTableName(), ID_COLUMN_NAME, relationship.getStoringSideEntityId(), dslContext);
     }
 
-    private Record selectByIdForUpdate(String tableName, String idFieldName, String manySideEntityId,
-            DSLContext dslContext) {
-        return dslContext.selectFrom(table(tableName)).where(field(idFieldName).eq(manySideEntityId)).forUpdate()
+    private Record selectColumnsByIdForUpdate(List<String> columnNames, String tableName, String idFieldName,
+            String manySideEntityId, DSLContext dslContext) {
+        List<Field<Object>> fields = columnNames.stream().map(n -> field(name(n))).toList();
+        return dslContext.select(fields).from(table(tableName)).where(field(idFieldName).eq(manySideEntityId)).forUpdate()
                 .fetchOne();
     }
 
     private void addEntityToOperationResults(List<OperationResult> results, String entityId, String entityType) {
-        OperationResult result = new OperationResult(entityId, entityType, Map.of());
+        OperationResult result = OperationResult.createEntityOperationResult(entityId, entityType);
         if (!results.contains(result)) {
             results.add(result);
         }
     }
 
-    private String extractTypeFromTable(String tableName) {
-        return tableName.split("\\\"")[1];
-    }
-
-    private String extractTypeFromColumn(String oneSideEntityIdColumn) {
-        String associationName = getModelledName(oneSideEntityIdColumn).replace("REL_FK_", "");
-        return SchemaRegistry.getRelationNameByAssociationName(associationName);
-    }
 }
index ebc4750..82e9c82 100644 (file)
  */
 package org.oran.smo.teiv.service;
 
-import static org.jooq.impl.DSL.table;
-
 import java.util.List;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import org.jooq.DSLContext;
-import org.jooq.Record;
-import org.jooq.Result;
 import org.jooq.impl.DSL;
 import org.springframework.retry.support.RetryTemplate;
 import org.springframework.stereotype.Service;
@@ -67,10 +63,6 @@ public class TiesDbService {
         });
     }
 
-    protected Result<Record> selectAllRowsFromTable(final String tableName) {
-        return runMethodSafe(() -> readDataDslContext.selectFrom(table(tableName)).fetch());
-    }
-
     private <T> T runMethodSafe(Supplier<T> supp) {
         try {
             return supp.get();
index 45ce58e..97fcfbe 100644 (file)
@@ -31,6 +31,11 @@ import io.cloudevents.CloudEvent;
 import io.cloudevents.CloudEventData;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.exception.InvalidRelationshipException;
+import org.oran.smo.teiv.exception.YangModelException;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.utils.TiesConstants;
+import org.oran.smo.yangtools.parser.data.dom.YangDataDomNode;
 import org.springframework.stereotype.Component;
 import org.oran.smo.yangtools.parser.data.dom.YangDataDomDocumentRoot;
 import org.oran.smo.teiv.service.cloudevent.data.Entity;
@@ -38,12 +43,15 @@ import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
 import org.oran.smo.teiv.service.cloudevent.data.Relationship;
 import org.oran.smo.teiv.utils.YangParser;
 
+import static org.oran.smo.teiv.utils.CloudEventUtil.hasInvalidCharacter;
+
 @Slf4j
 @Component
 @RequiredArgsConstructor
 public class CloudEventParser {
     private static final String ENTITIES = "entities";
     private static final String RELATIONSHIPS = "relationships";
+    private static final String ILLEGAL_CHARACTER_FOUND = "Illegal character found in relationship %s: %s";
     private final ObjectMapper objectMapper;
 
     public ParsedCloudEventData getCloudEventData(CloudEvent cloudEvent) {
@@ -55,6 +63,10 @@ public class CloudEventParser {
             log.error("Cannot parse CloudEvent data: ", e);
             return null;
         }
+
+        boolean areSidesMandatory = !cloudEvent.getType().split("\\.")[1].equals(
+                TiesConstants.CLOUD_EVENT_WITH_TYPE_DELETE);
+
         final List<Entity> entities = new ArrayList<>();
         Boolean parsedEntities = processEntities(eventPayload, entities);
         if (parsedEntities.equals(Boolean.FALSE)) {
@@ -62,7 +74,7 @@ public class CloudEventParser {
         }
 
         final List<Relationship> relationships = new ArrayList<>();
-        Boolean parsedRelationship = processRelationships(eventPayload, relationships);
+        Boolean parsedRelationship = processRelationships(eventPayload, relationships, areSidesMandatory);
         if (parsedRelationship.equals(Boolean.FALSE)) {
             return null;
         }
@@ -74,51 +86,64 @@ public class CloudEventParser {
         JsonNode entitiesJsonNode = eventPayload.get(ENTITIES);
         if (entitiesJsonNode != null && (entitiesJsonNode.getNodeType() == JsonNodeType.ARRAY)) {
             for (JsonNode entityNode : entitiesJsonNode) {
-                try {
-                    parseEntities(entityNode, entities);
-                } catch (IOException e) {
-                    log.error("Cannot parse entity: " + entitiesJsonNode, e);
+                if (!parseEntities(entities, entitiesJsonNode, entityNode)) {
                     return false;
                 }
             }
         }
-        //TODO: Remove support for old format DnR events when RTA has been updated.
-        if (entitiesJsonNode != null && (entitiesJsonNode.getNodeType() == JsonNodeType.OBJECT)) {
-            try {
-                parseEntities(entitiesJsonNode, entities);
-            } catch (IOException e) {
-                log.error("Cannot parse entity: " + entitiesJsonNode, e);
-                return false;
-            }
+        return true;
+    }
+
+    private boolean parseEntities(List<Entity> entities, JsonNode entitiesJsonNode, JsonNode entityNode) {
+        try {
+            parseEntities(entityNode, entities);
+        } catch (IOException | YangModelException e) {
+            log.error("Cannot parse entity: " + entitiesJsonNode, e);
+            return false;
         }
         return true;
     }
 
-    private Boolean processRelationships(JsonNode eventPayload, List<Relationship> relationships) {
+    private Boolean processRelationships(JsonNode eventPayload, List<Relationship> relationships,
+            boolean areSidesMandatory) {
         JsonNode relationshipJsonNode = eventPayload.get(RELATIONSHIPS);
         if (relationshipJsonNode != null && (relationshipJsonNode.getNodeType() == JsonNodeType.ARRAY)) {
-            for (JsonNode relationshipNode : relationshipJsonNode) {
-                try {
-                    parseRelationships(relationshipNode, relationships);
-                } catch (IOException e) {
-                    log.error("Cannot parse relationship: " + relationshipNode, e);
-                    return false;
-                }
-            }
+            return processRelationshipsArray(relationshipJsonNode, relationships, areSidesMandatory);
         }
-        //TODO: Remove support for old format DnR events when RTA has been updated.
-        if (relationshipJsonNode != null && (relationshipJsonNode.getNodeType() == JsonNodeType.OBJECT)) {
+        return true;
+    }
+
+    private boolean processRelationshipsArray(JsonNode relationshipJsonNode, List<Relationship> relationships,
+            boolean areSidesMandatory) {
+        for (JsonNode relationshipNode : relationshipJsonNode) {
             try {
-                parseRelationships(relationshipJsonNode, relationships);
+                parseRelationships(relationshipNode, relationships, areSidesMandatory);
             } catch (IOException e) {
                 log.error("Cannot parse relationship: " + relationshipJsonNode, e);
                 return false;
+            } catch (InvalidRelationshipException e) {
+                log.error("Invalid relationship: " + e);
+                return false;
             }
         }
         return true;
     }
 
-    public void parseEntities(JsonNode entitiesJsonNode, List<Entity> entities) throws IOException {
+    private boolean processRelationshipsObject(JsonNode relationshipJsonNode, List<Relationship> relationships,
+            boolean areSidesMandatory) {
+        try {
+            parseRelationships(relationshipJsonNode, relationships, areSidesMandatory);
+        } catch (IOException e) {
+            log.error("Cannot parse relationship: " + relationshipJsonNode, e);
+            return false;
+        } catch (InvalidRelationshipException e) {
+            log.error("Invalid relationship: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    public void parseEntities(JsonNode entitiesJsonNode, List<Entity> entities) throws IOException, YangModelException {
         YangDataDomDocumentRoot entityDom = YangParser.getYangDataDomDocumentRoot(entitiesJsonNode);
         entityDom.getChildren().forEach(child -> {
             Entity entity = new Entity();
@@ -127,12 +152,51 @@ public class CloudEventParser {
         });
     }
 
-    private void parseRelationships(JsonNode relationshipNode, List<Relationship> relationships) throws IOException {
+    private static void validateCharactersInId(Entity entity) throws IOException {
+        if (hasInvalidCharacter(entity.getId())) {
+            throw new IOException("Illegal character found in entity id:" + entity.getId());
+        }
+    }
+
+    private void parseRelationships(JsonNode relationshipNode, List<Relationship> relationships, boolean areSidesMandatory)
+            throws IOException, InvalidRelationshipException {
         YangDataDomDocumentRoot relDom = YangParser.getYangDataDomDocumentRoot(relationshipNode);
-        relDom.getChildren().forEach(child -> {
+
+        for (YangDataDomNode child : relDom.getChildren()) {
             Relationship relationship = new Relationship();
             relationship.parseObject(child);
+            if (relationship.getId() == null) {
+                throw new InvalidRelationshipException("Relationship is missing id! " + objectMapper.writeValueAsString(
+                        relationship));
+            }
+            if (areSidesMandatory && (relationship.getASide() == null || relationship.getBSide() == null)) {
+                throw new InvalidRelationshipException("Relationship is missing a side! " + relationship.getId());
+            }
+            if (SchemaRegistry.getRelationTypeByName(relationship.getType()) == null) {
+                throw new InvalidRelationshipException("Invalid relationship type! " + relationship.getId());
+            }
+            if (!SchemaRegistry.getModuleRegistry().containsKey(relationship.getModule())) {
+                throw new InvalidRelationshipException("Invalid relationship module! " + relationship.getId());
+            }
+            String moduleName = SchemaRegistry.getRelationTypeByName(relationship.getType()).getModule().getName();
+            if (!moduleName.equals(relationship.getModule())) {
+                log.error("Type: {} corresponding module: {}", relationship.getType(), moduleName);
+                throw new InvalidRelationshipException("Invalid relationship module-type pair! " + relationship.getId());
+            }
+            validateCharactersInId(relationship);
             relationships.add(relationship);
-        });
+        }
+    }
+
+    private static void validateCharactersInId(Relationship relationship) throws IOException {
+        if (hasInvalidCharacter(relationship.getId())) {
+            throw new IOException(String.format(ILLEGAL_CHARACTER_FOUND, "id", relationship.getId()));
+        }
+        if (hasInvalidCharacter(relationship.getASide())) {
+            throw new IOException(String.format(ILLEGAL_CHARACTER_FOUND, "aSide", relationship.getASide()));
+        }
+        if (hasInvalidCharacter(relationship.getBSide())) {
+            throw new IOException(String.format(ILLEGAL_CHARACTER_FOUND, "bSide", relationship.getBSide()));
+        }
     }
 }
index d8de9ce..6528c06 100644 (file)
@@ -39,7 +39,11 @@ public class Entity extends ModuleObject {
 
     public Entity(String module, String type, String id, Map<String, Object> attributes, List<String> sourceIds) {
         super(module, type, id, sourceIds);
-        this.attributes = new HashMap<>(attributes);
+        if (attributes == null) {
+            this.attributes = new HashMap<>();
+        } else {
+            this.attributes = new HashMap<>(attributes);
+        }
     }
 
     public Entity() {
index 87f351d..a6b89bb 100644 (file)
@@ -36,9 +36,9 @@ import static org.oran.smo.teiv.utils.TiesConstants.SOURCE_IDS;
 @Getter
 public class ModuleObject {
 
-    private String module;
-    private String type;
-    private String id;
+    protected String module;
+    protected String type;
+    protected String id;
     private List<String> sourceIds;
 
     public void parseObject(final YangDataDomNode node) {
index 96527bb..46dd2f6 100644 (file)
@@ -23,6 +23,7 @@ package org.oran.smo.teiv.service.cloudevent.data;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 
+import java.util.Comparator;
 import java.util.List;
 
 @Data
@@ -31,4 +32,25 @@ public class ParsedCloudEventData {
 
     private List<Entity> entities;
     private List<Relationship> relationships;
+
+    /**
+     * Sorts the entity and relationship list by type and id.
+     * The goal is to decrease the possibility of deadlocks in the database by executing the database operations in the same
+     * order in every pod's every consumer.
+     * For example: 2 transactions are trying to update both entity1 and entity2. If
+     * they both start with entity1, then one transaction gets the row level lock on entity1 and can go ahead while the
+     * other is blocked.
+     * If it's not sorted, then the first transaction can get the lock for entity1, the other gets the lock for entity2, and
+     * it's a deadlock.
+     */
+    public void sort() {
+        if (entities != null) {
+            entities = getEntities().stream().sorted(Comparator.comparing(Entity::getType).thenComparing(Entity::getId))
+                    .toList();
+        }
+        if (relationships != null) {
+            relationships = getRelationships().stream().sorted(Comparator.comparing(Relationship::getType).thenComparing(
+                    Relationship::getStoringTablePrimaryKey)).toList();
+        }
+    }
 }
index 47a3c8d..ed821b9 100644 (file)
@@ -74,4 +74,12 @@ public class Relationship extends ModuleObject {
         };
     }
 
+    public String getStoringTablePrimaryKey() {
+        RelationType relationType = SchemaRegistry.getRelationTypeByName(getType());
+        return switch (relationType.getRelationshipStorageLocation()) {
+            case RELATION -> getId();
+            case A_SIDE -> getASide();
+            case B_SIDE -> getBSide();
+        };
+    }
 }
index 1ca66e8..919ff67 100644 (file)
 package org.oran.smo.teiv.service.kafka;
 
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Service;
 
 @Service
-@Profile("ingestion")
 public class KafkaAddressSupplierConfig implements KafkaAddressSupplier {
 
     @Value("${kafka.server.bootstrap-server-host}")
index 67dedfc..6c49d7a 100644 (file)
@@ -25,14 +25,13 @@ import io.cloudevents.kafka.CloudEventDeserializer;
 import java.time.Duration;
 import java.util.HashMap;
 import java.util.Map;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import org.apache.kafka.clients.admin.AdminClientConfig;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.oran.smo.teiv.config.KafkaAdminConfig;
 import org.oran.smo.teiv.config.KafkaConfig;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Profile;
 import org.springframework.kafka.annotation.EnableKafka;
 import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
 import org.springframework.kafka.core.ConsumerFactory;
@@ -46,8 +45,7 @@ import org.springframework.util.backoff.FixedBackOff;
 
 @Component
 @EnableKafka
-@AllArgsConstructor
-@Profile("ingestion")
+@RequiredArgsConstructor
 public class KafkaFactory {
 
     private final KafkaConfig kafkaConfig;
index ef1757e..0e73c4c 100644 (file)
  */
 package org.oran.smo.teiv.service.models;
 
-import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.oran.smo.teiv.service.cloudevent.data.Entity;
 import org.oran.smo.teiv.service.cloudevent.data.Relationship;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_A_SIDE;
-import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_B_SIDE;
 
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class OperationResult {
     private String id;
-    private String entryType;
-    private Map<String, Object> content;
-
-    public static OperationResult createFromRelationship(Relationship relationship) {
-        Map<String, Object> relationshipSides = new HashMap<>();
-        relationshipSides.put(PROPERTY_A_SIDE, relationship.getASide());
-        relationshipSides.put(PROPERTY_B_SIDE, relationship.getBSide());
-        return new OperationResult(relationship.getId(), relationship.getType(), relationshipSides);
+    private String type; // e.g.: NRCellDU, Site, CloudNativeApplication
+    private String category; // "entity" or "relationship"
+    private Map<String, Object> attributes;
+    private String aSide;
+    private String bSide;
+    private List<String> classifiers;
+    private Map<String, Object> decorators;
+    private List<String> sourceIds;
+
+    public static OperationResult createEntityOperationResult(String id, String type, Map<String, Object> attributes,
+            List<String> sourceIds) {
+        return new OperationResult(id, type, "entity", attributes, null, null, null, null, sourceIds);
+    }
+
+    public static OperationResult createEntityOperationResult(String id, String type, Map<String, Object> attributes) {
+        return createEntityOperationResult(id, type, attributes, null);
+    }
+
+    public static OperationResult createEntityOperationResult(String id, String type) {
+        return OperationResult.createEntityOperationResult(id, type, null, null);
+    }
+
+    public static OperationResult createEntityOperationResult(Entity entity) {
+        return OperationResult.createEntityOperationResult(entity.getId(), entity.getType(), entity.getAttributes(), entity
+                .getSourceIds());
+    }
+
+    public static OperationResult createRelationshipOperationResult(String id, String type, String aSide, String bSide,
+            List<String> sourceIds) {
+        return new OperationResult(id, type, "relationship", null, aSide, bSide, null, null, sourceIds);
+    }
+
+    public static OperationResult createRelationshipOperationResult(String id, String type, String aSide, String bSide) {
+        return createRelationshipOperationResult(id, type, aSide, bSide, null);
+    }
+
+    public static OperationResult createRelationshipOperationResult(String id, String type) {
+        return OperationResult.createRelationshipOperationResult(id, type, null, null, null);
+    }
+
+    public static OperationResult createRelationshipOperationResult(Relationship relationship) {
+        return OperationResult.createRelationshipOperationResult(relationship.getId(), relationship.getType(), relationship
+                .getASide(), relationship.getBSide(), relationship.getSourceIds());
+    }
+
+    public static OperationResult createClassifierOperationResult(String id, String type, String category,
+            List<String> classifiers) {
+        return new OperationResult(id, type, category, null, null, null, classifiers, null, null);
+    }
+
+    public static OperationResult createDecoratorOperationResult(String id, String type, String category,
+            Map<String, Object> decorators) {
+        return new OperationResult(id, type, category, null, null, null, null, decorators, null);
+    }
+
+    @JsonIgnore
+    public boolean isRelationship() {
+        return getCategory().equals("relationship");
+    }
+
+    @JsonIgnore
+    public boolean isEntity() {
+        return getCategory().equals("entity");
     }
 }
index a95bd9c..d88f90f 100644 (file)
@@ -20,6 +20,8 @@
  */
 package org.oran.smo.teiv.startup;
 
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.service.SchemaCleanUpService;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
 import org.springframework.context.event.EventListener;
 import org.springframework.core.annotation.Order;
@@ -37,6 +39,8 @@ import lombok.extern.slf4j.Slf4j;
 public class SchemaHandler {
     private final SchemaLoader postgresSchemaLoader;
     private final HealthStatus healthStatus;
+    private final ModelRepository modelRepository;
+    private final SchemaCleanUpService schemaCleanUpService;
 
     /**
      * Loads the schema registry at application startup.
@@ -50,4 +54,15 @@ public class SchemaHandler {
         log.info("Schema initialized successfully...");
         healthStatus.setSchemaInitialized(true);
     }
+
+    /**
+     * Continue schema clean up at application startup.
+     */
+    @Order(value = 15)
+    @EventListener(value = ApplicationReadyEvent.class)
+    public void cleanUpSchema() {
+        log.debug("Start schema clean up");
+        modelRepository.getDeletingModulesOnStartup().forEach(module -> schemaCleanUpService.cleanUpModule(module
+                .getName()));
+    }
 }
index d511c38..162b7f9 100644 (file)
@@ -38,4 +38,16 @@ public class CloudEventUtil {
         return String.format("CloudEvent{id=%s, source=%s, type=%s, dataschema=%s, data=%s}", cloudEvent.getId(), cloudEvent
                 .getSource(), cloudEvent.getType(), cloudEvent.getDataSchema(), cloudEventData);
     }
+
+    public static boolean hasInvalidCharacter(String id) {
+        if (id == null || id.isEmpty()) {
+            return false;
+        }
+        // Characters that are permitted in URL components according to RFC3986, https://datatracker.ietf.org/doc/html/rfc3986,
+        // as well as the ':' character which is used in IDs
+        final String permittedCharactersPattern = "[-!$&'()*+,:;=._~0-9a-zA-Z]+";
+        // General delimiters meant for delimiting URL components - these are not expected to be part of an id (: excluded)
+        final String forbiddenCharactersPattern = "[\\[\\]/?#@]+";
+        return (!id.matches(permittedCharactersPattern) || id.matches(forbiddenCharactersPattern));
+    }
 }
diff --git a/teiv/src/main/java/org/oran/smo/teiv/utils/JooqTypeConverter.java b/teiv/src/main/java/org/oran/smo/teiv/utils/JooqTypeConverter.java
new file mode 100644 (file)
index 0000000..d4ae088
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  ============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.teiv.utils;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.jooq.JSONB;
+import org.jooq.tools.json.JSONArray;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import lombok.experimental.UtilityClass;
+
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.exception.InvalidFieldInYangDataException;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.utils.schema.Geography;
+
+@UtilityClass
+@Slf4j
+public class JooqTypeConverter {
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    public static List<String> jsonbToList(final JSONB jsonb) {
+        try {
+            return objectMapper.readValue(jsonb.data(), List.class);
+        } catch (JsonProcessingException e) {
+            String message = "Exception during converting jsonb to list";
+            log.error(message, e);
+            throw TiesException.serverException(message, null, e);
+        }
+    }
+
+    public static Map<String, Object> jsonbToMap(final JSONB jsonb) {
+        try {
+            return objectMapper.readValue(jsonb.data(), Map.class);
+        } catch (JsonProcessingException e) {
+            String message = "Exception during converting jsonb to map";
+            log.error(message, e);
+            throw TiesException.serverException(message, null, e);
+        }
+    }
+
+    /**
+     * Creates a jooq.JSONB object from a json formatted String.
+     *
+     * The Yang Parser library parses the single element arrays as a JSON primitive.
+     * The use of yang models will solve this problem. As a temporary workaround,
+     * if one of the following is true, then the @param value is transformed into
+     * a single element json array before creating the JSONB object:
+     * - @param value is not a String, or
+     * - @param value is a String, but does not contain a JSON.
+     *
+     * @param value
+     * @return The jooq.JSONB object created from the value.
+     */
+    public static JSONB toJsonb(Object value) {
+        if (value == null) {
+            return null;
+        } else if (value instanceof String str && isJsonObjectOrArray(str)) {
+            return JSONB.jsonb(str);
+        } else {
+            return JSONB.jsonb(makeSingleElementJsonArray(value));
+        }
+    }
+
+    /**
+     * Creates a jooq.JSONB object from a List of strings.
+     *
+     * @param stringList
+     * @return The jooq.JSONB object created from the value.
+     */
+    public static JSONB toJsonb(List<String> stringList) {
+        return JSONB.jsonb(JSONArray.toJSONString(stringList));
+    }
+
+    private static boolean isJsonObjectOrArray(String str) {
+        String trimmedStr = str.stripLeading();
+        return trimmedStr.startsWith("{") || trimmedStr.startsWith("[");
+    }
+
+    private static String makeSingleElementJsonArray(Object obj) {
+        return JSONArray.toJSONString(List.of(obj));
+    }
+
+    public static Geography toGeography(Object value) throws InvalidFieldInYangDataException {
+        try {
+            if (value == null) {
+                return null;
+            }
+            return new Geography((String) value);
+        } catch (ClassCastException | IOException e) {
+            throw new InvalidFieldInYangDataException(String.format("Can't create a Geography object from: %s", value), e);
+        }
+    }
+}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/utils/PersistableUtil.java b/teiv/src/main/java/org/oran/smo/teiv/utils/PersistableUtil.java
new file mode 100644 (file)
index 0000000..427982c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  ============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.teiv.utils;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class PersistableUtil {
+    public static String getFullyQualifiedNameWithColumnName(String fullyQualifiedName, String columnName) {
+        return fullyQualifiedName + "." + columnName;
+    }
+
+    public static String getTableNameWithColumnName(String tableName, String columnName) {
+        return tableName + ".\"" + columnName + "\"";
+    }
+}
index c057c15..99c3d8b 100644 (file)
@@ -31,17 +31,21 @@ public class TiesConstants {
     public static final String TIES_DATA_SCHEMA = "ties_data";
     public static final String TIES_DATA = TIES_DATA_SCHEMA + ".\"%s\"";
     public static final String TIES_MODEL = "ties_model.%s";
-    public static final String ST_TO_STRING = "ST_AsText(\"%s\")";
+    public static final String TIES_CONSUMER_DATA = "ties_consumer_data.%s";
+    public static final String ST_TO_STRING = "ST_AsText(%s)";
     public static final String ST_TO_STRING_COLUMN_WITH_TABLE_NAME = "ST_AsText(%s)";
     public static final String QUOTED_STRING = "\"%s\"";
     public static final String ID_COLUMN_NAME = "id";
     public static final String CONSUMER_DATA_PREFIX = "CD_";
     public static final String SOURCE_IDS = "sourceIds";
+    public static final String CLASSIFIERS = "classifiers";
+    public static final String DECORATORS = "decorators";
     public static final String REL_PREFIX = "REL_";
     public static final String PROPERTY_A_SIDE = "aSide";
     public static final String PROPERTY_B_SIDE = "bSide";
-    public static final String ITEMS = "items";
+    public static final String ITEM = "item";
     public static final String ATTRIBUTES = "attributes";
+    public static final String ATTRIBUTES_ABBREVIATION = ".attr.";
     public static final String TARGET_FILTER = "targetFilter";
     public static final String SCOPE_FILTER = "scopeFilter";
     public static final String QUERY = "query";
@@ -52,7 +56,15 @@ public class TiesConstants {
     public static final long INFINITE_MAXIMUM_CARDINALITY = 9223372036854775807L;
     public static final String FOREIGN_KEY_VIOLATION_ERROR_CODE = "23503";
     public static final String UNIQUE_CONSTRAINT_VIOLATION_CODE = "23505";
+    public static final String MODULE_REFERENCE = "module_reference";
 
     public static final String REL_FK = "REL_FK_";
     public static final String IN_USAGE = "IN_USAGE";
+    public static final String MODULE_REFERENCE_NAME = "moduleReferenceName";
+    public static final String NAME = "name";
+    public static final String SCHEMA_ALREADY_EXISTS = "Schema already exists";
+    public static final String SEMICOLON_SEPARATION = "%s:%s";
+    public static final String DOT_SEPARATION = "%s.%s";
+    public static final String WILDCARD = "*";
+    public static final String INVALID_SCHEMA = "Invalid schema";
 }
index af20fbb..762d349 100644 (file)
@@ -28,7 +28,10 @@ import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exception.YangModelException;
 import org.oran.smo.yangtools.parser.data.YangData;
+import org.oran.smo.yangtools.parser.findings.FindingSeverity;
 import org.oran.smo.yangtools.parser.findings.ModuleAndFindingTypeAndSchemaNodePathFilterPredicate;
 import org.oran.smo.yangtools.parser.input.BufferedStreamYangInput;
 import org.oran.smo.yangtools.parser.input.ByteArrayYangInput;
@@ -37,6 +40,7 @@ import org.oran.smo.yangtools.parser.model.YangModel;
 import org.oran.smo.yangtools.parser.model.statements.StatementModuleAndName;
 import com.fasterxml.jackson.databind.JsonNode;
 import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.yangtools.parser.model.yangdom.YangDomElement;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 import org.springframework.core.io.support.ResourcePatternResolver;
@@ -51,6 +55,11 @@ import org.oran.smo.yangtools.parser.model.ConformanceType;
 import org.oran.smo.yangtools.parser.model.statements.AbstractStatement;
 import org.oran.smo.teiv.api.model.OranTeivSchema;
 import org.oran.smo.teiv.api.model.OranTeivHref;
+import org.springframework.web.multipart.MultipartFile;
+
+import static org.oran.smo.teiv.utils.TiesConstants.CLASSIFIERS;
+import static org.oran.smo.teiv.utils.TiesConstants.INVALID_SCHEMA;
+import static org.oran.smo.teiv.utils.TiesConstants.SEMICOLON_SEPARATION;
 
 @Service
 @Slf4j
@@ -84,6 +93,67 @@ public class YangParser {
         return yangDeviceModel;
     }
 
+    /**
+     * Validating yang file from /schemas POST request
+     *
+     * @return map of validated and parsed yang
+     */
+    public Map<String, Object> validateSchemasYang(MultipartFile file) throws YangModelException {
+
+        Map<String, Object> result = new HashMap<>();
+
+        YangDeviceModel yangDeviceModel = new YangDeviceModel("r1");
+        YangModel inputYangModel = null;
+        final List<YangModel> yangModels = new ArrayList<>();
+        try {
+            inputYangModel = new YangModel(new ByteArrayYangInput(file.getBytes(), "requestYang"), ConformanceType.IMPORT);
+            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(this.getClass().getClassLoader());
+            Resource[] yangResourcesImplement = resolver.getResources("classpath:models/*.yang");
+            Resource[] yangResourcesImport = resolver.getResources("classpath:models/import/*.yang");
+
+            for (Resource yangResource : yangResourcesImplement) {
+                yangModels.add(new YangModel(new ByteArrayYangInput(yangResource.getContentAsByteArray(), Objects
+                        .requireNonNull(yangResource.getFilename())), ConformanceType.IMPLEMENT));
+            }
+
+            for (Resource yangResource : yangResourcesImport) {
+                yangModels.add(new YangModel(new ByteArrayYangInput(yangResource.getContentAsByteArray(), Objects
+                        .requireNonNull(yangResource.getFilename())), ConformanceType.IMPORT));
+            }
+
+            yangModels.add(inputYangModel);
+        } catch (final IOException ex) {
+            log.error("Unable to load schema", ex);
+        }
+
+        final ModifyableFindingSeverityCalculator severityCalculator = new ModifyableFindingSeverityCalculator();
+        final FindingsManager findingsManager = new FindingsManager(severityCalculator);
+        findingsManager.addFilterPredicate(ModuleAndFindingTypeAndSchemaNodePathFilterPredicate.fromString("ietf-*;*;*"));
+        findingsManager.addFilterPredicate(ModuleAndFindingTypeAndSchemaNodePathFilterPredicate.fromString("_3gpp*;*;*"));
+        final ParserExecutionContext context = new ParserExecutionContext(findingsManager);
+        context.setIgnoreImportedProtocolAccessibleObjects(true);
+        context.setFailFast(false);
+        yangDeviceModel.parseIntoYangModels(context, yangModels);
+        checkFindings(context.getFindingsManager(), severityCalculator);
+
+        assert inputYangModel != null;
+        String prefixName = null;
+
+        for (YangDomElement children : inputYangModel.getYangDomDocumentRoot().getChildren().get(0).getChildren()) {
+            if (children.getValue().contains("common-yang-types")) {
+                prefixName = children.getChildren().get(0).getValue();
+                break;
+            }
+        }
+
+        result.put("classifiers", getClassifiers(inputYangModel.getYangDomDocumentRoot().getChildren().get(0).getChildren(),
+                prefixName));
+        result.put("decorators", getDecorators(inputYangModel.getYangDomDocumentRoot().getChildren().get(0).getChildren()));
+        result.put("moduleName", inputYangModel.getModuleIdentity().getModuleName());
+        result.put("revision", inputYangModel.getModuleIdentity().getRevision());
+        return result;
+    }
+
     /**
      * Store domains and revision by schema name, return object of all schemas
      *
@@ -160,6 +230,63 @@ public class YangParser {
         return yangDataDomDocument;
     }
 
+    private List<String> getClassifiers(List<YangDomElement> elements, String prefixName) {
+
+        List<String> result = new ArrayList<>();
+        String formattedName = String.format(SEMICOLON_SEPARATION, prefixName, CLASSIFIERS);
+
+        elements.stream().filter(element -> element.getName().contains("identity")).forEach(element -> {
+            String childValue = element.getChildren().get(0).getValue();
+
+            if (!childValue.equals(formattedName)) {
+                List<YangDomElement> domElement = element.getParentElement().getChildren().stream().filter(parent -> parent
+                        .getName().contains("identity")).filter(parent -> parent.getValue().equals(childValue) && parent
+                                .getChildren().get(0).getValue().equals(formattedName)).toList();
+
+                if (domElement.isEmpty()) {
+                    throw TiesException.invalidSchema("Invalid classifier " + element.getValue());
+                } else {
+                    result.add(element.getValue());
+                }
+            } else {
+                result.add(element.getValue());
+            }
+        });
+
+        return result;
+    }
+
+    private Map<String, String> getDecorators(List<YangDomElement> elements) {
+        Map<String, String> result = new HashMap<>();
+
+        elements.forEach(keys -> {
+            if (keys.getValue().contains("decorators")) {
+                keys.getChildren().forEach(values -> result.put(values.getValue(), switch (values.getChildren().get(0)
+                        .getValue()) {
+                    case "string" -> "TEXT";
+                    case "boolean" -> "BOOLEAN";
+                    case "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64" -> "INT";
+                    default -> throw TiesException.invalidFileInput("Invalid data type");
+                }));
+            }
+        });
+
+        return result;
+    }
+
+    private static void checkFindings(FindingsManager findingsManager,
+            ModifyableFindingSeverityCalculator severityCalculator) {
+        for (Finding finding : findingsManager.getAllFindings()) {
+            if (severityCalculator.calculateSeverity(finding.getFindingType()).equals(FindingSeverity.ERROR)) {
+                if (finding.getMessage().contains("exception") || finding.getFindingType().contains("UNSPECIFIED_ERROR")) {
+                    throw TiesException.invalidFileInput(INVALID_SCHEMA);
+                } else {
+                    throw TiesException.invalidFileInput(finding.getMessage());
+                }
+            }
+        }
+    }
+
     private static YangDataDomDocumentRoot parse(final String yangTopology) throws IOException {
 
         final ModifyableFindingSeverityCalculator severityCalculator = new ModifyableFindingSeverityCalculator();
diff --git a/teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryElement.java b/teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryElement.java
deleted file mode 100644 (file)
index c389b03..0000000
+++ /dev/null
@@ -1,126 +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 org.oran.smo.teiv.utils.query;
-
-import org.oran.smo.teiv.utils.path.TiesPathQuery;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-@Getter
-@NoArgsConstructor
-class QueryElement {
-    private String objectType;
-    private List<String> attributes = null;
-    private Map<TokenType, List<TiesPathQuery>> filters = null;
-    private List<QueryElement> children = new ArrayList<>();
-    private boolean isIncluded = false;
-    private boolean isManyToMany = false;
-    private boolean isRelConnectingSameEntity = false;
-
-    public QueryElement(String objectType) {
-        this.objectType = objectType;
-    }
-
-    public QueryElement(String objectType, boolean isIncluded) {
-        this.objectType = objectType;
-        this.isIncluded = isIncluded;
-    }
-
-    public void addAttribute(String attribute) {
-        attributes.add(attribute);
-    }
-
-    public void setAttributes(List<String> attributes) {
-        this.attributes = attributes;
-    }
-
-    public void addFilter(TokenType type, TiesPathQuery filter) {
-        filters.putIfAbsent(type, new ArrayList<>());
-        filters.get(type).add(filter);
-
-    }
-
-    public boolean hasFilters() {
-        return filters != null;
-    }
-
-    public void setFilters(Map<TokenType, List<TiesPathQuery>> filters) {
-        this.filters = filters;
-    }
-
-    public void addChild(QueryElement child) {
-        addChild(child, true);
-    }
-
-    public void addChild(QueryElement child, boolean safeAdd) {
-        if (safeAdd && this.hasChild(child.objectType)) {
-            return;
-        }
-        children.add(child);
-    }
-
-    public void removeChild(QueryElement child) {
-        children.remove(child);
-    }
-
-    public boolean hasAttributes() {
-        return attributes != null;
-    }
-
-    public List<TiesPathQuery> getFiltersOfTypes(List<TokenType> types) {
-        return types.stream().flatMap(type -> filters.containsKey(type) ? filters.get(type).stream() : null).toList();
-    }
-
-    public boolean hasFilterOfType(TokenType type) {
-        return filters.containsKey(type);
-    }
-
-    public boolean hasChild(String child) {
-        return children.stream().anyMatch(c -> c.getObjectType().equals(child));
-    }
-
-    public QueryElement getChild(String objectType) {
-        Optional<QueryElement> result = children.stream().filter(child -> child.getObjectType().equals(objectType))
-                .findFirst();
-        return result.orElse(null);
-    }
-
-    public boolean hasChildren() {
-        return !children.isEmpty();
-    }
-
-    public void include() {
-        isIncluded = true;
-    }
-
-    public void setManyToMany() {
-        isManyToMany = true;
-    }
-
-    public void setRelConnectingSameEntity() {
-        isRelConnectingSameEntity = true;
-    }
-}
diff --git a/teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryMonad.java b/teiv/src/main/java/org/oran/smo/teiv/utils/query/QueryMonad.java
deleted file mode 100644 (file)
index 086a236..0000000
+++ /dev/null
@@ -1,989 +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 org.oran.smo.teiv.utils.query;
-
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getDbName;
-import static org.oran.smo.teiv.schema.BidiDbNameMapper.getModelledName;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
-import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.oran.smo.teiv.utils.path.TiesPathUtil.getTiesPathQuery;
-import static org.jooq.impl.DSL.asterisk;
-import static org.jooq.impl.DSL.condition;
-import static org.jooq.impl.DSL.field;
-import static org.jooq.impl.DSL.not;
-import static org.jooq.impl.DSL.one;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.oran.smo.teiv.schema.RelationshipDataLocation;
-import org.antlr.v4.runtime.misc.ParseCancellationException;
-import org.jooq.Condition;
-import org.jooq.DSLContext;
-import org.jooq.Field;
-import org.jooq.Record;
-import org.jooq.Record1;
-import org.jooq.ResultQuery;
-import org.jooq.Select;
-import org.jooq.SelectConditionStep;
-import org.jooq.SelectJoinStep;
-import org.jooq.SelectSelectStep;
-import org.jooq.impl.DSL;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.utils.path.TiesPathQuery;
-import org.oran.smo.teiv.utils.path.exception.PathParsingException;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-
-@Builder
-public class QueryMonad {
-
-    private static final String SEMICOLON = ";";
-    private static final String BAR = "|";
-    private String managedObject;
-    private String targets;
-    private String scope;
-    private String relationships;
-    private String domain;
-
-    /**
-     * Builds a jooq query using the SchemaRegistry, based on the filters.
-     *
-     * @return the prepared jooq query
-     */
-    public Function<DSLContext, ResultQuery<Record>> withSchema(final PaginationDTO paginationDTO) {
-        return context -> buildQuery(context, paginationDTO);
-    }
-
-    public Function<DSLContext, ResultQuery<Record1<Integer>>> countWithSchema() {
-        return this::buildQueryCount;
-    }
-
-    private QueryElement constructRoot() {
-        List<PathToken> targetTokens = targets != null ? processPath(targets, true) : new ArrayList<>();
-        List<PathToken> scopeTokens = scope != null ? processPath(scope, false) : new ArrayList<>();
-
-        return buildQueryTree(managedObject, targetTokens, scopeTokens, domain);
-    }
-
-    private ResultQuery<Record> buildQuery(DSLContext context, final PaginationDTO paginationDTO) {
-        List<String> relationshipTypes = parseRelationships(relationships);
-
-        return buildJooqQuery(context, constructRoot(), relationshipTypes, paginationDTO);
-    }
-
-    private SelectConditionStep<Record1<Integer>> buildQueryCount(DSLContext context) {
-        List<String> relationshipTypes = parseRelationships(relationships);
-
-        return buildJooqQueryCount(context, constructRoot(), relationshipTypes);
-    }
-
-    private static Select<Record> buildInnerQuery(DSLContext context, QueryElement root, List<String> relationships) {
-        SelectSelectStep<Record> selectStep = buildSelectStep(context, root, root.getObjectType());
-
-        boolean[] isValidHop = { false };
-        Select<Record> query = buildFromStep(selectStep, root, relationships, isValidHop, root.getObjectType());
-        Condition joinFilter = null;
-
-        for (QueryElement child : root.getChildren()) {
-            if (root.getObjectType() != null && !SchemaRegistry.hasDirectHopBetween(root.getObjectType(), child
-                    .getObjectType(), relationships)) {
-                continue;
-            }
-
-            joinFilter = setJoinFilter(root, joinFilter, child);
-        }
-
-        for (QueryElement child : root.getChildren()) {
-            if (root.getObjectType() == null || SchemaRegistry.hasDirectHopBetween(root.getObjectType(), child
-                    .getObjectType())) {
-                query = query.union(buildUnionBody(context, root, child.getObjectType(), relationships, joinFilter,
-                        isValidHop));
-            }
-        }
-
-        buildJooqQueryCheckIfRootHasConnections(root, isValidHop[0]);
-
-        query = buildWhereStep(query, root, joinFilter, relationships);
-
-        return query;
-    }
-
-    private static SelectConditionStep<Record1<Integer>> buildJooqQueryCount(DSLContext context, QueryElement root,
-            List<String> relationships) {
-
-        Select<Record> query = buildInnerQuery(context, root, relationships);
-
-        return context.selectCount().from(query.asTable("TiesPathQuery")).where(not(field("\"TiesPathQuery\"").isNull()));
-    }
-
-    private static SelectJoinStep<Record> buildJooqQuery(DSLContext context, QueryElement root, List<String> relationships,
-            final PaginationDTO paginationDTO) {
-
-        Select<Record> query = buildInnerQuery(context, root, relationships);
-
-        return (SelectJoinStep<Record>) context.selectDistinct(asterisk()).from(query.asTable("TiesPathQuery")).orderBy(
-                one().asc()).limit(paginationDTO.getOffset(), paginationDTO.getLimit());
-    }
-
-    private static Condition setJoinFilter(QueryElement root, Condition joinFilter, QueryElement child) {
-        if (root.getObjectType() != null || child.getFilters() == null) {
-            Field<Boolean> condition = field(String.format(TIES_DATA, getDbName(child.getObjectType())) + "." + String
-                    .format(QUOTED_STRING, ID_COLUMN_NAME)).isNotNull();
-            if (joinFilter != null && root.getObjectType() != null) {
-                joinFilter = joinFilter.and(condition);
-            } else if (joinFilter != null) {
-                joinFilter = joinFilter.or(condition);
-            } else {
-                joinFilter = DSL.condition(condition);
-            }
-        }
-        return joinFilter;
-    }
-
-    private static void buildJooqQueryCheckIfRootHasConnections(QueryElement root, Boolean isValidHop) {
-        if ((root.hasChildren() && !isValidHop && root.getObjectType() != null) || (!root.hasChildren() && !root
-                .isIncluded())) {
-            throw TiesPathException.noConnectionFound(root.getObjectType());
-        } else if ((root.hasChildren() && !isValidHop) || (!root.hasChildren() && !root.isIncluded())) {
-            throw TiesPathException.noConnectionFoundWhenRootIsNull();
-        }
-    }
-
-    private static SelectSelectStep<Record> buildSelectStep(DSLContext context, QueryElement root, String returnObject) {
-        List<String> columnNames = getColumnList(root);
-        if (returnObject == null) {
-            return context.select(columnNames.stream().map(column -> field("null").cast(SchemaRegistry.getEntityTypeByName(
-                    getModelledName(column.split("\\.")[1].replaceAll("\"", ""))).getField(column, null, returnObject)
-                    .getType()).as(column)).collect(Collectors.toList()));
-        }
-        if (root.isManyToMany()) {
-            return context.select(columnNames.stream().map(DSL::field).toList());
-        } else if (root.isRelConnectingSameEntity()) {
-            return context.selectDistinct(columnNames.stream().map(DSL::field).toList());
-        } else {
-            return context.select(columnNames.stream().map(column -> column.split("\\.")[1].replaceAll("\"", "").equals(
-                    getDbName(returnObject)) ?
-                            SchemaRegistry.getEntityTypeByName(returnObject).getField(column, null, null) :
-                            field("null").cast(SchemaRegistry.getEntityTypeByName(getModelledName(column.split("\\.")[1]
-                                    .replaceAll("\"", ""))).getField(column, null, returnObject).getType()).as(column))
-                    .collect(Collectors.toList()));
-        }
-    }
-
-    private static SelectSelectStep<Record> buildSelectStepForUnion(DSLContext context, QueryElement root,
-            String returnObject) {
-        List<String> columnNames = getColumnList(root);
-        if (root.getObjectType() != null && root.getObjectType().equals(returnObject)) {
-            return context.select(columnNames.stream().map(column -> field("null").cast(SchemaRegistry.getEntityTypeByName(
-                    column.split("\\.")[1].replaceAll("\"", "")).getField(column, null, returnObject).getType()).as(column))
-                    .collect(Collectors.toList()));
-        } else {
-            return buildSelectStep(context, root, returnObject);
-        }
-    }
-
-    private static SelectJoinStep<Record> buildFromStep(SelectSelectStep<Record> selectStep, QueryElement root,
-            List<String> relationships, boolean[] isValidHop, String returnObject) {
-        if (root.getObjectType() == null) {
-            SelectJoinStep<Record> fromStep = selectStep.from("(SELECT '') as dual_table");
-
-            for (QueryElement child : root.getChildren()) {
-                if (SchemaRegistry.isEntityPartOfRelationships(child.getObjectType(), relationships)) {
-                    TableJoinConnection connection = new TableJoinConnection(B_SIDE, null, List.of(condition(field(String
-                            .format(TIES_DATA, getDbName(child.getObjectType())) + "." + ID_COLUMN_NAME).eq(field(
-                                    "(SELECT '')")))), false);
-
-                    fromStep = buildFromStepSetJoin(child, returnObject, fromStep, connection);
-
-                    isValidHop[0] = true;
-                }
-            }
-            return fromStep;
-        }
-        SelectJoinStep<Record> fromStep = selectStep.from(String.format(TIES_DATA, getDbName(root.getObjectType())));
-        for (QueryElement child : root.getChildren()) {
-            for (TableJoinConnection connection : findJoinConnections(root, child, relationships)) {
-                fromStep = getRecords(root, fromStep, child, connection);
-                isValidHop[0] = true;
-            }
-        }
-        return fromStep;
-    }
-
-    private static SelectJoinStep<Record> getRecords(QueryElement root, SelectJoinStep<Record> fromStep, QueryElement child,
-            TableJoinConnection connection) {
-        if (connection.relConnectingSameEntity) {
-            fromStep = fromStep.join(connection.getTableName()).on(connection.getConditions().get(0)).or(connection
-                    .getConditions().get(1));
-        } else {
-            if (!root.isManyToMany() && connection.getRelationshipDataLocation().equals(RELATION)) {
-                fromStep = fromStep.join(connection.getTableName()).on(connection.getConditions().get(1));
-            }
-            if (!root.isManyToMany()) {
-                fromStep = fromStep.leftJoin(String.format(TIES_DATA, getDbName(child.getObjectType()))).on(connection
-                        .getConditions().get(0));
-            } else {
-                fromStep = fromStep.join(String.format(TIES_DATA, getDbName(child.getObjectType()))).on(connection
-                        .getConditions().get(0));
-            }
-        }
-        return fromStep;
-    }
-
-    private static SelectJoinStep<Record> buildFromStepSetJoin(QueryElement child, String returnObject,
-            SelectJoinStep<Record> fromStep, TableJoinConnection connection) {
-        if (child.getObjectType().equals(returnObject)) {
-            return fromStep.rightJoin(String.format(TIES_DATA, getDbName(child.getObjectType()))).on(connection
-                    .getConditions().get(0));
-        } else {
-            return fromStep.leftJoin(String.format(TIES_DATA, getDbName(child.getObjectType()))).on(connection
-                    .getConditions().get(0));
-        }
-    }
-
-    private static List<TableJoinConnection> findJoinConnections(QueryElement qe1, QueryElement qe2,
-            List<String> relationships) {
-        List<RelationType> relationTypes;
-        if (qe1.isManyToMany() || qe1.isRelConnectingSameEntity()) {
-            relationTypes = List.of(SchemaRegistry.getRelationTypeByName(qe1.getObjectType()));
-        } else {
-            relationTypes = SchemaRegistry.getRelationTypesBetweenEntities(qe1.getObjectType(), qe2.getObjectType(),
-                    relationships);
-        }
-        return createJoinConnections(qe1, qe2, relationTypes);
-    }
-
-    private static List<TableJoinConnection> createJoinConnections(QueryElement qe1, QueryElement qe2,
-            List<RelationType> relationTypes) {
-        List<TableJoinConnection> joins = new ArrayList<>();
-        for (RelationType relationType : relationTypes) {
-            switch (relationType.getRelationshipStorageLocation()) {
-                case A_SIDE:
-                    joins.add(createASideJoin(relationType));
-                    break;
-                case B_SIDE:
-                    joins.add(createBSideJoin(relationType));
-                    break;
-                case RELATION:
-                    joins.add(createRelationJoin(qe1, qe2, relationType));
-                    break;
-            }
-        }
-        return joins;
-    }
-
-    private static TableJoinConnection createSameEntityJoin(QueryElement qe1, QueryElement qe2, RelationType relationType) {
-        String table = relationType.getTableName() + ".";
-        if (!qe1.isRelConnectingSameEntity()) {
-            return new TableJoinConnection(relationType.getRelationshipStorageLocation(), relationType.getTableName(), List
-                    .of(condition(field(table + String.format(QUOTED_STRING, relationType.bSideColumnName())).eq(field(
-                            String.format(TIES_DATA, getDbName(qe2.getObjectType())) + "." + String.format(QUOTED_STRING,
-                                    ID_COLUMN_NAME)))), condition(field(table + String.format(QUOTED_STRING, relationType
-                                            .aSideColumnName())).eq(field(String.format(TIES_DATA, qe1
-                                                    .getObjectType()) + "." + String.format(QUOTED_STRING,
-                                                            ID_COLUMN_NAME))))), true);
-        } else {
-            return new TableJoinConnection(relationType.getRelationshipStorageLocation(), String.format(TIES_DATA,
-                    getDbName(qe2.getObjectType())), List.of(condition(field(table + String.format(QUOTED_STRING,
-                            relationType.bSideColumnName())).eq(field(String.format(TIES_DATA, getDbName(qe2
-                                    .getObjectType())) + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME)))), condition(
-                                            field(table + String.format(QUOTED_STRING, relationType.aSideColumnName())).eq(
-                                                    field(String.format(TIES_DATA, getDbName(qe2
-                                                            .getObjectType())) + "." + String.format(QUOTED_STRING,
-                                                                    ID_COLUMN_NAME))))), true);
-        }
-    }
-
-    private static TableJoinConnection createASideJoin(RelationType relationType) {
-        String table = relationType.getTableName() + ".";
-        return new TableJoinConnection(relationType.getRelationshipStorageLocation(), null, List.of(condition(field(
-                table + String.format(QUOTED_STRING, relationType.bSideColumnName())).eq(field(String.format(TIES_DATA,
-                        getDbName(relationType.getBSide().getName())) + "." + String.format(QUOTED_STRING,
-                                ID_COLUMN_NAME))))), false);
-    }
-
-    private static TableJoinConnection createBSideJoin(RelationType relationType) {
-        String table = relationType.getTableName() + ".";
-        return new TableJoinConnection(relationType.getRelationshipStorageLocation(), null, List.of(condition(field(
-                table + String.format(QUOTED_STRING, relationType.aSideColumnName())).eq(field(String.format(TIES_DATA,
-                        getDbName(relationType.getASide().getName())) + "." + String.format(QUOTED_STRING,
-                                ID_COLUMN_NAME))))), false);
-    }
-
-    private static TableJoinConnection createRelationJoin(QueryElement qe1, QueryElement qe2, RelationType relationType) {
-        String table = relationType.getTableName() + ".";
-        if (relationType.isConnectsSameEntity()) {
-            return createSameEntityJoin(qe1, qe2, relationType);
-        } else if (!qe1.isManyToMany()) {
-            return new TableJoinConnection(relationType.getRelationshipStorageLocation(), relationType.getTableName(), List
-                    .of(condition(field(table + String.format(QUOTED_STRING, relationType.bSideColumnName())).eq(field(
-                            String.format(TIES_DATA, getDbName(qe2.getObjectType())) + "." + String.format(QUOTED_STRING,
-                                    ID_COLUMN_NAME)))), condition(field(table + String.format(QUOTED_STRING, relationType
-                                            .aSideColumnName())).eq(field(String.format(TIES_DATA, qe1
-                                                    .getObjectType()) + "." + String.format(QUOTED_STRING,
-                                                            ID_COLUMN_NAME))))), false);
-        } else {
-            String colInManyToManyTable = relationType.getASide().getName().equals(qe2.getObjectType()) ?
-                    relationType.aSideColumnName() :
-                    relationType.bSideColumnName();
-            return new TableJoinConnection(relationType.getRelationshipStorageLocation(), relationType.getTableName(), List
-                    .of(condition(field(table + String.format(QUOTED_STRING, colInManyToManyTable)).eq(field(String.format(
-                            TIES_DATA, getDbName(qe2.getObjectType())) + "." + String.format(QUOTED_STRING,
-                                    ID_COLUMN_NAME))))), false);
-        }
-    }
-
-    private static Select<Record> buildUnionBody(DSLContext context, QueryElement root, String returnObject,
-            List<String> relationships, Condition joinFilter, boolean[] isValidHop) {
-        SelectSelectStep<Record> selectStep = buildSelectStepForUnion(context, root, returnObject);
-        SelectJoinStep<Record> fromStep = buildFromStep(selectStep, root, relationships, isValidHop, returnObject);
-        return buildWhereStep(fromStep, root, joinFilter, relationships);
-    }
-
-    private static Select<Record> buildWhereStep(Select<Record> query, QueryElement root, Condition joinFilter,
-            List<String> relationships) {
-        Condition condition = DSL.noCondition();
-        condition = buildWhereAnd(condition, root, relationships);
-        for (QueryElement child : root.getChildren()) {
-            condition = buildWhereAnd(condition, child, null);
-        }
-        if (!root.isManyToMany()) {
-            condition = buildWhereOr(condition, root);
-        }
-        for (QueryElement child : root.getChildren()) {
-            condition = buildWhereOr(condition, child);
-        }
-        if (joinFilter != null && root.getObjectType() != null) {
-            condition = condition.and(joinFilter);
-        } else if (joinFilter != null) {
-            condition = condition.or(joinFilter);
-        }
-        return query.$where(condition);
-    }
-
-    private static Condition buildWhereAnd(Condition condition, QueryElement root, List<String> relationships) {
-        if (root.hasFilters() && (root.hasFilterOfType(TokenType.AND) || root.hasFilterOfType(TokenType.NO_TYPE))) {
-            condition = condition.and(DSL.and(Stream.concat(root.getFiltersOfTypes(List.of(TokenType.AND,
-                    TokenType.NO_TYPE)).stream().flatMap(filter -> filter.hasLeafConditions() ?
-                            filter.getLeavesData().stream().map(leaf -> field(String.format(TIES_DATA, getDbName(root
-                                    .getObjectType())) + "." + String.format(QUOTED_STRING, getDbName(leaf.getName()))).eq(
-                                            leaf.getValue())) :
-                            null), root.getFiltersOfTypes(List.of(TokenType.AND, TokenType.NO_TYPE)).stream().map(
-                                    filter -> filter.hasContainsFunctionCondition() ?
-                                            field(String.format(TIES_DATA, getDbName(root.getObjectType())) + "." + String
-                                                    .format(QUOTED_STRING, getDbName(filter
-                                                            .getContainsFunctionConditionLeafName()))).contains(filter
-                                                                    .getContainsFunctionConditionValue()) :
-                                            DSL.noCondition())).toList()));
-        }
-
-        condition = getConditionsWithRelationships(condition, relationships);
-
-        return condition;
-    }
-
-    private static Condition getConditionsWithRelationships(Condition condition, List<String> relationships) {
-        if (relationships != null) {
-            List<RelationType> relationTypes = new ArrayList<>();
-
-            for (String relationship : relationships) {
-                relationTypes.add(SchemaRegistry.getRelationTypeByName(relationship));
-            }
-
-            for (RelationType relationType : relationTypes) {
-                for (Field<?> field : relationType.getBaseFieldsWithId()) {
-                    condition = condition.and(field.isNotNull());
-                }
-            }
-        }
-        return condition;
-    }
-
-    private static Condition buildWhereOr(Condition condition, QueryElement root) {
-        if (root.hasFilters() && root.hasFilterOfType(TokenType.OR)) {
-            condition = condition.or(DSL.or(root.getFiltersOfTypes(List.of(TokenType.OR)).stream().map(filter -> DSL.and(
-                    filter.hasLeafConditions() ?
-                            filter.getLeavesData().stream().map(leaf -> field(String.format(TIES_DATA, getDbName(root
-                                    .getObjectType())) + "." + String.format(QUOTED_STRING, getDbName(leaf.getName()))).eq(
-                                            leaf.getValue())).toList() :
-                            List.of(DSL.noCondition()))).toList()));
-            condition = condition.or(DSL.or(root.getFiltersOfTypes(List.of(TokenType.OR)).stream().map(filter -> filter
-                    .hasContainsFunctionCondition() ?
-                            field(String.format(TIES_DATA, getDbName(root.getObjectType())) + "." + String.format(
-                                    QUOTED_STRING, getDbName(filter.getContainsFunctionConditionLeafName()))).contains(
-                                            filter.getContainsFunctionConditionValue()) :
-                            DSL.noCondition()).toList()));
-        }
-        return condition;
-    }
-
-    private static List<String> getColumnList(QueryElement root) {
-        List<String> columns = new ArrayList<>();
-
-        if (root.isIncluded()) {
-            if (!root.hasAttributes()) {
-                columns.add(String.format(TIES_DATA, getDbName(root.getObjectType())) + "." + String.format(QUOTED_STRING,
-                        ID_COLUMN_NAME));
-            } else {
-                if (root.getAttributes().isEmpty()) {
-                    columns.addAll(SchemaRegistry.getEntityTypeByName(root.getObjectType()).getAttributeColumnsWithId());
-                } else {
-                    columns.addAll(root.getAttributes().stream().map(attribute -> String.format(TIES_DATA, getDbName(root
-                            .getObjectType())) + "." + String.format(QUOTED_STRING, getDbName(attribute))).toList());
-                    if (!columns.contains(String.format(TIES_DATA, getDbName(root.getObjectType())) + "." + String.format(
-                            QUOTED_STRING, ID_COLUMN_NAME))) {
-                        columns.add(String.format(TIES_DATA, getDbName(root.getObjectType())) + "." + String.format(
-                                QUOTED_STRING, ID_COLUMN_NAME));
-                    }
-                }
-            }
-        }
-        if (root.hasChildren()) {
-            columns.addAll(root.getChildren().stream().flatMap(child -> getColumnList(child).stream()).toList());
-        }
-
-        return columns;
-    }
-
-    private static List<PathToken> processPath(String path, boolean isSemiColonAllowed) {
-        return processPath(path, isSemiColonAllowed, null);
-    }
-
-    private static List<PathToken> processPath(String path, boolean isSemiColonAllowed, TokenType lastToken) {
-        List<PathToken> tiesPath = new ArrayList<>();
-
-        if (path.isEmpty()) {
-            return tiesPath;
-        }
-
-        if (!isSemiColonAllowed && path.indexOf(';') > -1) {
-            throw TiesPathException.grammarError(String.format("Character ';' is not allowed at %d", path.indexOf(';')));
-        }
-
-        if (path.contains(BAR) || path.contains(SEMICOLON)) {
-            String delimiter = findDelimiter(path);
-
-            String[] tokens = path.split(Pattern.quote(delimiter), 2);
-            TokenType type = delimiter.equals(BAR) ? TokenType.OR : TokenType.AND;
-            addPathSafe(tiesPath, tokens[0], type);
-            tiesPath.addAll(processPath(tokens[1], isSemiColonAllowed, type));
-        } else {
-            addPathSafe(tiesPath, path, lastToken != null ? lastToken : TokenType.NO_TYPE);
-        }
-        return tiesPath;
-    }
-
-    private static String findDelimiter(String path) {
-        if (path.contains(BAR) && path.contains(SEMICOLON)) {
-            return path.indexOf(BAR) < path.indexOf(SEMICOLON) ? SEMICOLON : BAR;
-        } else {
-            return path.contains(BAR) ? BAR : SEMICOLON;
-        }
-    }
-
-    private static void addPathSafe(List<PathToken> tiesPath, String path, TokenType type) {
-        try {
-            tiesPath.add(new PathToken(type, getTiesPathQuery(path)));
-        } catch (ParseCancellationException e) {
-            throw TiesPathException.grammarError(e.getMessage());
-        } catch (PathParsingException e) {
-            throw TiesPathException.grammarError(e.getDetails());
-        }
-    }
-
-    private static List<String> parseRelationships(final String relationships) {
-        if (relationships == null || relationships.isEmpty()) {
-            return new ArrayList<>();
-        }
-        String[] relationshipTokens = relationships.split(",");
-        List<String> relationshipsList = new ArrayList<>();
-        Arrays.stream(relationshipTokens).forEach(relationship -> {
-            String trimmed = relationship.trim();
-            if (SchemaRegistry.getRelationNames().contains(trimmed)) {
-                relationshipsList.add(trimmed);
-            } else {
-                throw TiesPathException.invalidRelationshipName(trimmed);
-            }
-        });
-        return relationshipsList;
-    }
-
-    private static QueryElement buildQueryTree(String objectType, List<PathToken> targets, List<PathToken> scopes,
-            String domain) {
-        QueryElement root = new QueryElement(objectType);
-        RelationType relationType = SchemaRegistry.getRelationTypeByName(objectType);
-        if (objectType != null && relationType != null) {
-            if (relationType.isConnectsSameEntity()) {
-                root.setRelConnectingSameEntity();
-            } else if (RELATION.equals(relationType.getRelationshipStorageLocation())) {
-                root.setManyToMany();
-            }
-        }
-
-        processTargets(root, targets, domain);
-        processScopes(root, scopes, domain);
-
-        return root;
-    }
-
-    private static void processTargets(QueryElement root, List<PathToken> targets, String domain) {
-        String prevToken = null;
-        String prevPrevToken = null;
-
-        if (targets.isEmpty()) {
-            root.include();
-        }
-
-        for (PathToken target : targets) {
-            QueryElement[] currentElement = { root };
-            boolean isValidHop = true;
-            for (int i = 0; i < target.getValue().getContainerNames().size(); ++i) {
-                String container = target.getValue().getContainerNames().get(i);
-                isValidHop = processTargetContainer(root, currentElement, container, prevToken, domain, prevPrevToken);
-                if (!isValidHop) {
-                    break;
-                }
-                prevPrevToken = prevToken;
-                prevToken = container;
-            }
-            if (isValidHop) {
-                addTargetAttributes(currentElement[0], target);
-            }
-            prevToken = null;
-        }
-
-        if (root.getObjectType() == null && root.getChildren().isEmpty()) {
-            throw TiesPathException.grammarError("No match for targetFilter condition");
-        }
-    }
-
-    private static boolean processTargetContainer(QueryElement root, QueryElement[] currentElement, String container,
-            String prevToken, String domain, String prevPrevToken) {
-        if (SchemaRegistry.isValidEntityName(container)) {
-            if (prevToken != null) {
-                throw TiesPathException.grammarError(String.format("Missing ';' or '|' before %s", container));
-            }
-            if (root.getObjectType() != null && !SchemaRegistry.hasDirectHopBetween(currentElement[0].getObjectType(),
-                    container)) {
-                return false;
-            }
-            if (root.getObjectType() == null && !SchemaRegistry.getEntityNamesByDomain(domain).contains(container)) {
-                throw TiesPathException.grammarError(String.format("%s is not part of %s domain", container, domain));
-            }
-            currentElement[0].addChild(new QueryElement(container, true));
-            currentElement[0] = currentElement[0].getChild(container);
-            prevToken = container;
-        } else if (root.getObjectType() != null && currentElement[0].getObjectType().equals(root.getObjectType()) && !root
-                .hasChildren()) {
-            root.include();
-        }
-
-        processTargetAttribute(container, prevToken, currentElement[0]);
-
-        processTargetContainerIfItIsAttributes(root, currentElement, container, prevToken, domain);
-
-        processTargetContainerIfItIsID(root, currentElement, container, prevToken, domain);
-
-        processTargetContainerPrevPrevTokenNull(root, container, prevToken, prevPrevToken);
-
-        return true;
-    }
-
-    private static void processTargetContainerPrevPrevTokenNull(QueryElement root, String container, String prevToken,
-            String prevPrevToken) {
-        if (prevPrevToken == null && prevToken != null && prevToken.equals(ATTRIBUTES) && !container.equals(
-                ID_COLUMN_NAME) && !container.equals(ATTRIBUTES)) {
-            List<QueryElement> doesNotHaveAttribute = new ArrayList<>();
-            for (QueryElement child : root.getChildren()) {
-                processTargetAttribute(container, prevToken, child);
-                if (child.getAttributes().isEmpty()) {
-                    doesNotHaveAttribute.add(child);
-                }
-            }
-            if (root.getObjectType() == null) {
-                removeChildFromRoot(doesNotHaveAttribute, root);
-            }
-        } else if (prevPrevToken == null && prevToken != null && prevToken.equals(ATTRIBUTES) && container.equals(
-                ID_COLUMN_NAME)) {
-            throw TiesPathException.idAmongAttributesError();
-        }
-    }
-
-    private static void removeChildFromRoot(List<QueryElement> childrenToRemove, QueryElement root) {
-        for (QueryElement child : childrenToRemove) {
-            root.removeChild(child);
-        }
-
-    }
-
-    private static void processTargetContainerIfItIsAttributes(QueryElement root, QueryElement[] currentElement,
-            String container, String prevToken, String domain) {
-        if (container.equals(ATTRIBUTES) && root.getObjectType() == null && prevToken == null) {
-            for (String entity : SchemaRegistry.getEntityNamesByDomain(domain)) {
-                if (currentElement[0].getChild(entity) == null) {
-                    QueryElement entityInDomain = new QueryElement(entity);
-                    addTargetContainer(entityInDomain, prevToken);
-                    currentElement[0].addChild(entityInDomain);
-                }
-            }
-        } else if (container.equals(ATTRIBUTES)) {
-            addTargetContainer(currentElement[0], prevToken);
-        }
-    }
-
-    private static void processTargetContainerIfItIsID(QueryElement root, QueryElement[] currentElement, String container,
-            String prevToken, String domain) {
-        if (container.equals(ID_COLUMN_NAME) && root.getObjectType() == null && prevToken == null) {
-            for (String entity : SchemaRegistry.getEntityNamesByDomain(domain)) {
-                if (currentElement[0].getChild(entity) == null && SchemaRegistry.doesEntityContainsAttribute(entity,
-                        container)) {
-                    QueryElement entityInDomain = new QueryElement(entity, true);
-                    currentElement[0].addChild(entityInDomain);
-                    addTargetContainer(entityInDomain, prevToken);
-                    addTargetAttribute(entityInDomain, container);
-                }
-            }
-        }
-
-    }
-
-    private static void processTargetAttribute(String container, String prevToken, QueryElement currentElement) {
-        if (SchemaRegistry.doesEntityContainsAttribute(currentElement.getObjectType(), container)) {
-            if (container.equals(ID_COLUMN_NAME) && prevToken == null) {
-                addTargetContainer(currentElement, null);
-                addTargetAttribute(currentElement, container);
-
-            } else if (container.equals(ID_COLUMN_NAME)) {
-                if (SchemaRegistry.isValidEntityName(prevToken)) {
-                    addTargetContainer(currentElement, prevToken);
-                    addTargetAttribute(currentElement, container);
-                } else {
-                    throw TiesPathException.idAmongAttributesError();
-                }
-            } else {
-                if (prevToken == null) {
-                    throw TiesPathException.grammarError(String.format("Missing 'attributes' before %s", container));
-                } else if (prevToken.equals(ATTRIBUTES)) {
-                    addTargetAttribute(currentElement, container);
-
-                } else {
-                    throw TiesPathException.grammarError(String.format("/%s/%s is not accepted", prevToken, container));
-                }
-            }
-        }
-    }
-
-    private static void addTargetContainer(QueryElement element, String prevToken) {
-        if (ATTRIBUTES.equals(prevToken)) {
-            throw TiesPathException.grammarError(String.format("Missing ';' or '|' before %s", prevToken));
-        }
-        if (!element.hasAttributes()) {
-            element.setAttributes(new ArrayList<>());
-            element.include();
-        }
-    }
-
-    private static void addTargetAttribute(QueryElement element, String container) {
-        if (!element.hasAttributes()) {
-            throw TiesPathException.grammarError(String.format("Missing 'attributes' before %s", container));
-        }
-        element.addAttribute(container);
-    }
-
-    private static void addTargetAttributes(QueryElement element, PathToken target) {
-        if (target.getValue().getNormalizedXpath().equals("/" + ID_COLUMN_NAME) && !target.getValue().getAttributeNames()
-                .isEmpty()) {
-            throw TiesPathException.grammarError("/" + ID_COLUMN_NAME + "/" + target.getValue().getAttributeNames().get(
-                    0) + " is not accepted.");
-        }
-        if (element.getObjectType() != null) {
-            addTargetAttributesIfObjectTypeIsNotNull(element, target);
-
-        } else {
-            addTargetAttributesIfObjectTypeIsNull(element, target);
-
-        }
-    }
-
-    private static void addTargetAttributesIfObjectTypeIsNotNull(QueryElement element, PathToken target) {
-        for (String attribute : target.getValue().getAttributeNames()) {
-            if (!element.isManyToMany() && attribute.equals(ID_COLUMN_NAME)) {
-                throw TiesPathException.idAmongAttributesError();
-            }
-            if (!element.isManyToMany() && !SchemaRegistry.doesEntityContainsAttribute(element.getObjectType(),
-                    attribute) && !SchemaRegistry.getRelationNamesByEntityName(element.getObjectType()).contains(attribute
-                            .replace("REL_ID_", "")) && !SchemaRegistry.getRelationNames().contains(element
-                                    .getObjectType()) && !SchemaRegistry.getAssociationNamesByEntityName(element
-                                            .getObjectType()).contains(attribute.replace("REL_FK_", ""))) {
-                throw TiesPathException.columnNameError(element.getObjectType(), attribute);
-            }
-            if (!element.hasAttributes()) {
-                throw TiesPathException.grammarError(String.format("Missing 'attributes' before (%s...", target.getValue()
-                        .getAttributeNames().get(0)));
-            }
-            element.addAttribute(attribute);
-        }
-    }
-
-    private static void addTargetAttributesIfObjectTypeIsNull(QueryElement element, PathToken target) {
-        Set<QueryElement> hasNoAttribute = new HashSet<>();
-        for (String attribute : target.getValue().getAttributeNames()) {
-            if (attribute.equals(ID_COLUMN_NAME)) {
-                throw TiesPathException.idAmongAttributesError();
-            }
-
-            for (QueryElement entity : element.getChildren()) {
-                if (SchemaRegistry.doesEntityContainsAttribute(entity.getObjectType(), attribute)) {
-                    entity.addAttribute(attribute);
-                    hasNoAttribute.remove(entity);
-                } else {
-                    hasNoAttribute.add(entity);
-                }
-            }
-        }
-        for (QueryElement child : hasNoAttribute) {
-            element.removeChild(child);
-        }
-
-    }
-
-    private static void processScopes(QueryElement root, List<PathToken> scopes, String domain) {
-        String prevToken;
-
-        for (PathToken scope : scopes) {
-            QueryElement[] currentElement = { root };
-            prevToken = null;
-            boolean isValidHop = true;
-            for (int i = 0; i < scope.getValue().getContainerNames().size(); ++i) {
-                String container = scope.getValue().getContainerNames().get(i);
-                isValidHop = processScopeContainer(currentElement, container, prevToken, domain);
-                prevToken = container;
-            }
-            if ((prevToken != null && isValidHop) && (scope.getValue().hasLeafConditions() || scope.getValue()
-                    .hasContainsFunctionCondition()) && scope.value.getNormalizedParentPath().isEmpty() && root
-                            .getObjectType() == null) {
-
-                checkIdExpressions(scope.getValue().getContainsFunctionConditionLeafName(), prevToken, scope.getValue()
-                        .getLeavesData());
-
-                processScopesIfRootsObjectTypeIsNull(currentElement[0].getChildren(), scope, prevToken);
-
-            } else if (isValidHop && (scope.getValue().hasLeafConditions() || scope.getValue()
-                    .hasContainsFunctionCondition())) {
-
-                checkConditions(currentElement[0], scope);
-
-                if (!root.isManyToMany() && !root.isRelConnectingSameEntity() && scope.getValue()
-                        .hasContainsFunctionCondition() && !SchemaRegistry.doesEntityContainsAttribute(currentElement[0]
-                                .getObjectType(), scope.getValue().getContainsFunctionConditionLeafName())) {
-                    throw TiesPathException.columnNameError(currentElement[0].getObjectType(), scope.getValue()
-                            .getContainsFunctionConditionLeafName());
-                }
-
-                checkIdAttributes(currentElement[0], prevToken);
-
-                String leafName = scope.getValue().getContainsFunctionConditionLeafName();
-
-                checkIdExpressions(leafName, prevToken, scope.getValue().getLeavesData());
-
-                currentElement[0].addFilter(scope.getType(), scope.getValue());
-            }
-        }
-    }
-
-    private static void checkIdAttributes(QueryElement currentElement, String prevToken) {
-        if (!currentElement.hasFilters() && !prevToken.equals(ID_COLUMN_NAME)) {
-            throw TiesPathException.grammarError("Missing 'attributes' before '[''");
-        }
-    }
-
-    private static void checkIdExpressions(String leafName, String prevToken, List<TiesPathQuery.DataLeaf> leavesData) {
-        if (leavesData != null) {
-            List<TiesPathQuery.DataLeaf> leavesDataWithId = leavesData.stream().filter(leaf -> leaf.getName().equals(
-                    ID_COLUMN_NAME)).toList();
-            if ((!leavesDataWithId.isEmpty() && !prevToken.equals(ID_COLUMN_NAME)) || ((leavesData
-                    .size() > 1 || leavesDataWithId.size() != 1) && prevToken.equals(ID_COLUMN_NAME))) {
-                throw TiesPathException.grammarError("Expression is not accepted");
-            }
-        }
-
-        if (leafName != null && (leafName.equals(ID_COLUMN_NAME) && !prevToken.equals(
-                ID_COLUMN_NAME)) || leafName != null && (!leafName.equals(ID_COLUMN_NAME) && prevToken.equals(
-                        ID_COLUMN_NAME))) {
-            throw TiesPathException.grammarError("Expression is not accepted");
-        }
-    }
-
-    private static boolean processScopeContainer(QueryElement[] currentElement, String container, String prevToken,
-            String domain) {
-        if (SchemaRegistry.isValidEntityName(container)) {
-            if (prevToken != null) {
-                throw TiesPathException.grammarError(String.format("Missing ';' or '|' before %s", container));
-            }
-            if (currentElement[0].getObjectType() != null && !currentElement[0].isManyToMany() && !currentElement[0]
-                    .isRelConnectingSameEntity() && !SchemaRegistry.hasDirectHopBetween(currentElement[0].getObjectType(),
-                            container)) {
-                return false;
-            }
-            if (currentElement[0].getObjectType() == null && !SchemaRegistry.getEntityNamesByDomain(domain).contains(
-                    container)) {
-                throw TiesPathException.grammarError(String.format("%s is not part of %s domain", container, domain));
-            }
-            currentElement[0].addChild(new QueryElement(container));
-            currentElement[0] = currentElement[0].getChild(container);
-        }
-        processScopeContainerIfContainerIsAttributesOrId(currentElement[0], container, prevToken);
-
-        return true;
-    }
-
-    private static void processScopeContainerIfContainerIsAttributesOrId(QueryElement currentElement, String container,
-            String prevToken) {
-        if ((container.equals(ATTRIBUTES) || container.equals(ID_COLUMN_NAME)) && prevToken == null && currentElement
-                .getObjectType() == null) {
-            for (QueryElement entity : currentElement.getChildren()) {
-                addScopeFilter(entity, container, prevToken);
-            }
-        } else if (container.equals(ATTRIBUTES) || container.equals(ID_COLUMN_NAME)) {
-            addScopeFilter(currentElement, container, prevToken);
-        }
-    }
-
-    private static void addScopeFilter(QueryElement element, String container, String prevToken) {
-        if (container.equals(prevToken)) {
-            throw TiesPathException.grammarError(String.format("Missing ';' or '|' before %s", container));
-        }
-        if (!element.hasFilters()) {
-            element.setFilters(new EnumMap<>(TokenType.class));
-        }
-    }
-
-    private static void checkConditions(QueryElement element, PathToken scope) {
-        if (element.getObjectType() != null) {
-            if (scope.getValue().hasLeafConditions()) {
-                for (TiesPathQuery.DataLeaf leaf : scope.getValue().getLeavesData()) {
-                    if (!element.isManyToMany() && !element.isRelConnectingSameEntity() && !SchemaRegistry
-                            .doesEntityContainsAttribute(element.getObjectType(), leaf.getName())) {
-                        throw TiesPathException.columnNameError(element.getObjectType(), leaf.getName());
-                    }
-                }
-            }
-            if (!element.isManyToMany() && !element.isRelConnectingSameEntity() && scope.getValue()
-                    .hasContainsFunctionCondition() && !SchemaRegistry.doesEntityContainsAttribute(element.getObjectType(),
-                            scope.getValue().getContainsFunctionConditionLeafName())) {
-                throw TiesPathException.columnNameError(element.getObjectType(), scope.getValue()
-                        .getContainsFunctionConditionLeafName());
-            }
-        }
-
-    }
-
-    private static void processScopesIfRootsObjectTypeIsNull(List<QueryElement> elements, PathToken scope,
-            String prevToken) {
-        processScopesIfRootsObjectTypeIsNullHasLeafCondition(elements, scope, prevToken);
-        processScopesIfRootsObjectTypeIsNullHasContainsCondition(elements, scope, prevToken);
-    }
-
-    private static void processScopesIfRootsObjectTypeIsNullHasLeafCondition(List<QueryElement> elements, PathToken scope,
-            String prevToken) {
-
-        if (scope.getValue().hasLeafConditions()) {
-            int counter = 0;
-            boolean anyOfElementsContainsLeaf = true;
-            for (QueryElement element : elements) {
-                for (TiesPathQuery.DataLeaf leaf : scope.getValue().getLeavesData()) {
-                    checkIdAttributes(element, prevToken);
-                    if (!SchemaRegistry.doesEntityContainsAttribute(element.getObjectType(), leaf.getName())) {
-                        anyOfElementsContainsLeaf = false;
-                        break;
-                    }
-                }
-                if (anyOfElementsContainsLeaf) {
-                    element.addFilter(TokenType.OR, scope.getValue());
-                    counter++;
-                }
-
-                anyOfElementsContainsLeaf = true;
-            }
-            if (counter == 0) {
-                throw TiesPathException.grammarError(
-                        "None of the entities in domain has the attribute that was provided in scopeFilter");
-            }
-        }
-    }
-
-    private static void processScopesIfRootsObjectTypeIsNullHasContainsCondition(List<QueryElement> elements,
-            PathToken scope, String prevToken) {
-
-        if (scope.getValue().hasContainsFunctionCondition()) {
-            boolean anyOfElementsContainsLeaf = false;
-            for (QueryElement element : elements) {
-                checkIdAttributes(element, prevToken);
-                if (SchemaRegistry.doesEntityContainsAttribute(element.getObjectType(), scope.getValue()
-                        .getContainsFunctionConditionLeafName())) {
-                    element.addFilter(TokenType.OR, scope.getValue());
-                    anyOfElementsContainsLeaf = true;
-                }
-            }
-            if (!anyOfElementsContainsLeaf) {
-                throw TiesPathException.grammarError(
-                        "None of the entities in domain has the attribute that was provided in scopeFilter");
-            }
-        }
-    }
-
-    @Getter
-    @Setter
-    @AllArgsConstructor
-    private static class PathToken {
-        private TokenType type;
-        private TiesPathQuery value;
-    }
-
-    @Getter
-    @AllArgsConstructor
-    private static class TableJoinConnection {
-        private RelationshipDataLocation relationshipDataLocation;
-        private String tableName;
-        private List<Condition> conditions;
-        private boolean relConnectingSameEntity;
-    }
-}
index f064de5..e27e91e 100644 (file)
@@ -26,6 +26,7 @@ import org.springframework.http.HttpStatus;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 @Getter
 public class TiesPathException extends RuntimeException {
@@ -80,6 +81,10 @@ public class TiesPathException extends RuntimeException {
         return clientException("Grammar Error", "ID is not considered to be an attribute");
     }
 
+    public static TiesPathException invalidQueryError() {
+        return clientException("Invalid query", "The provided query in scopeFilter is invalid");
+    }
+
     public static TiesPathException entityNameError(String entity) {
         return clientException("Grammar Error", String.format("%s is not a valid entity", entity));
     }
@@ -89,6 +94,29 @@ public class TiesPathException extends RuntimeException {
                 "%s did not match any topology objects in the given domain", topologyObject));
     }
 
+    public static TiesPathException invalidInnerContainer(String innerContainer) {
+        return clientException("Invalid data in scopeFilter", String.format("Unable to resolve %s", innerContainer));
+    }
+
+    public static TiesPathException invalidTargetFilter(Set<String> params) {
+        return clientException("Invalid targetFilter content", String.format(
+                "%s did not match any topology objects in the given domain", String.join(", ", params)));
+    }
+
+    public static TiesPathException invalidTargetFilter() {
+        return clientException("Invalid targetFilter content", "Given targetFilters could not be resolved");
+    }
+
+    public static TiesPathException invalidTargetFilterScopeFilterCombination() {
+        return clientException("Invalid targetFilter and scopeFilter content",
+                "Given targetFilter and scopeFilter can not be combined");
+    }
+
+    public static TiesPathException invalidScopeFilter(String leaf) {
+        return clientException("Invalid scopeFilter content", String.format(
+                "%s did not match any topology objects in the given domain", leaf));
+    }
+
     public static TiesPathException ambiguousTopologyObject(String topologyObject) {
         return clientException("Invalid topology object", String.format(
                 "%s is ambiguous, %s matches multiple topology object types", topologyObject, topologyObject));
@@ -113,8 +141,8 @@ public class TiesPathException extends RuntimeException {
         return clientException("Filter Error", "TopologyObjects given in scopeFilter and targetFilter are not matching");
     }
 
-    private static TiesPathException clientExceptionWithDefaultResponse(final String message, final String details) {
-        return new TiesPathException(message, details, HttpStatus.BAD_REQUEST, defaultResponse);
+    public static TiesPathException invalidQueryCondition(String details) {
+        return clientException("Invalid query condition", details);
     }
 
     private TiesPathException(final String message, final String details, final HttpStatus httpStatus,
index a7e609c..8bacf50 100644 (file)
@@ -72,6 +72,9 @@ spring:
   caching:
     consumer-data-ttl-ms: 60000
 
+consumer-data:
+  batch-size: 100
+
 endpoints.health.sensitive: "false"
 info.app.name: '@name@'
 info.app.description: Topology Exposure and Inventory Service
@@ -116,12 +119,13 @@ kafka:
     retry-attempts: 2147483647
     retry-interval-ms: 1000
   topology-ingestion:
+    topic:
+      name: topology-inventory-ingestion
+      partitions: 4
+      replicas: 3
+      retention-ms: 86400000
+      retention-bytes: 104857600
     consumer:
-      topic:
-        name: topology-inventory-ingestion
-        partitions: 4
-        replicas: 3
-        retention-ms: 86400000
       group-id: topology-inventory-ingestion-consumer
       auto-offset-reset: earliest
       max-poll-records: 500
@@ -136,7 +140,4 @@ database:
   retry-policies:
     deadlock:
       retry-attempts: 10
-      retry-backoff-ms: 200
-
-feature_flags:
-  use_alternate_delete_logic: false
\ No newline at end of file
+      retry-backoff-ms: 200
\ No newline at end of file
index 6eba710..3db898e 100644 (file)
 <configuration>
     <appender name="json" class="ch.qos.logback.core.ConsoleAppender">
         <encoder class="net.logstash.logback.encoder.LogstashEncoder">
-            <version>0.3.0</version>
-            <includeContext>false</includeContext>
-            <includeTags>false</includeTags>
 
             <fieldNames>
-                <level>[ignore]</level>
-                <version>version</version>
+                <version>
+                    <fieldName>version</fieldName>
+                    <version>1.2.0</version>
+                </version>
                 <timestamp>timestamp</timestamp>
-                <thread>thread</thread>
-                <logger>logger</logger>
-                <levelValue>[ignore]</levelValue>
             </fieldNames>
 
             <!-- Add fields from MDC [user and correlation_id] -->
                     <omitEmptyFields>true</omitEmptyFields>
                     <pattern>
                         {
-                        "service_id": "${SERVICE_ID:-unknown}",
-                        "correlation_id": "%mdc{X-B3-TraceId}"
+                            "service_id": "${SERVICE_ID:-unknown}",
+                            "message": "%msg"
+                        }
+                    </pattern>
+                </pattern>
+                <pattern>
+                    <omitEmptyFields>true</omitEmptyFields>
+                    <pattern>
+                        {
+                            "facility": "%X{facility}",
+                            "subject": "%X{subject}",
+                            "extra_data": {
+                                "logger": "%logger",
+                                "thread_info": {
+                                    "thread_name": "%thread"
+                                },
+                                "dst": {
+                                    "trace_id": "%mdc{traceId}"
+                                },
+                                "exception": {
+                                    "stack_trace": "%xEx"
+                                }
+                            }
                         }
                     </pattern>
                 </pattern>
         </encoder>
     </appender>
 
-    <root level="INFO">
+    <root level="${ROOT_LOG_LEVEL:-INFO}">
         <appender-ref ref="json"/>
     </root>
+
+    <logger name="/" level="${ROOT_LOG_LEVEL:-INFO}"/>
 </configuration>
 
index ed557f5..8cc7a89 100644 (file)
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.oran.smo.teiv.utils.TiesTestConstants.APPLICATION_JSON;
 
 import java.util.Objects;
 
@@ -55,8 +56,6 @@ class CoreApplicationTest {
     @MockBean
     private SchemaHandler schemaHandler;
 
-    private final String ACCEPT_TYPE = "application/json";
-
     @Test
     void testMetricsAvailable() throws Exception {
         // spotless:off
@@ -97,6 +96,9 @@ class CoreApplicationTest {
         Assertions.assertTrue(result.getResponse().getContentAsString().contains("ties_exposure_http_get_relationship_by_id_fail_total"));
         Assertions.assertTrue(result.getResponse().getContentAsString().contains("ties_exposure_http_get_relationships_by_type_fail_total"));
         Assertions.assertTrue(result.getResponse().getContentAsString().contains("ties_exposure_http_get_relationships_by_entity_id_fail_total"));
+
+        Assertions.assertTrue(result.getResponse().getContentAsString().contains("ties_exposure_http_update_classifiers_fail_total"));
+        Assertions.assertTrue(result.getResponse().getContentAsString().contains("ties_exposure_http_update_decorators_fail_total"));
         // spotless:on
     }
 
@@ -109,27 +111,29 @@ class CoreApplicationTest {
             "getTopologyEntityTypes:/domains/RAN_LOGICAL/entity-types",
             "getTopologyRelationshipTypes:/domains/RAN_LOGICAL/relationship-types" }, delimiter = ':')
     public void testPaginationRelatedEndpoints(String method, String url) throws Exception {
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("offset", "-1").accept(ACCEPT_TYPE)).andExpect(status()
-                .isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result.getResolvedException())
-                        .getMessage(), method + ".offset: must be greater than or equal to 0"));
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "0").accept(ACCEPT_TYPE)).andExpect(status()
-                .isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result.getResolvedException())
-                        .getMessage(), method + ".limit: must be greater than or equal to 1"));
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "501").accept(ACCEPT_TYPE)).andExpect(status()
-                .isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result.getResolvedException())
-                        .getMessage(), method + ".limit: must be less than or equal to 500"));
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("offset", "-1").accept(APPLICATION_JSON)).andExpect(
+                status().isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result
+                        .getResolvedException()).getMessage(), method + ".offset: must be greater than or equal to 0"));
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "0").accept(APPLICATION_JSON)).andExpect(
+                status().isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result
+                        .getResolvedException()).getMessage(), method + ".limit: must be greater than or equal to 1"));
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "501").accept(APPLICATION_JSON)).andExpect(
+                status().isBadRequest()).andExpect(result -> assertEquals(Objects.requireNonNull(result
+                        .getResolvedException()).getMessage(), method + ".limit: must be less than or equal to 500"));
 
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("offset", "0").accept(ACCEPT_TYPE)).andExpect(result -> {
-            if (result.getResponse().getStatus() != HttpStatus.OK.value())
-                assertNotEquals(ConstraintViolationException.class, Objects.requireNonNull(result.getResolvedException())
-                        .getClass());
-        });
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "1").accept(ACCEPT_TYPE)).andExpect(result -> {
-            if (result.getResponse().getStatus() != HttpStatus.OK.value())
-                assertNotEquals(ConstraintViolationException.class, Objects.requireNonNull(result.getResolvedException())
-                        .getClass());
-        });
-        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "500").accept(ACCEPT_TYPE)).andExpect(
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("offset", "0").accept(APPLICATION_JSON)).andExpect(
+                result -> {
+                    if (result.getResponse().getStatus() != HttpStatus.OK.value())
+                        assertNotEquals(ConstraintViolationException.class, Objects.requireNonNull(result
+                                .getResolvedException()).getClass());
+                });
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "1").accept(APPLICATION_JSON)).andExpect(
+                result -> {
+                    if (result.getResponse().getStatus() != HttpStatus.OK.value())
+                        assertNotEquals(ConstraintViolationException.class, Objects.requireNonNull(result
+                                .getResolvedException()).getClass());
+                });
+        mvc.perform(get(TiesConstants.REQUEST_MAPPING + url).param("limit", "500").accept(APPLICATION_JSON)).andExpect(
                 result -> {
                     if (result.getResponse().getStatus() != HttpStatus.OK.value())
                         assertNotEquals(ConstraintViolationException.class, Objects.requireNonNull(result
index 4a3a5db..183eae8 100644 (file)
  */
 package org.oran.smo.teiv.controller.health;
 
+import static org.mockito.Mockito.doReturn;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
+import org.oran.smo.teiv.availability.DependentServiceAvailabilityKafka;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.service.SchemaCleanUpService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -54,28 +55,21 @@ class TiesExposureHealthIndicatorTest {
 
     @MockBean
     private PostgresSchemaLoader postgresSchemaLoader;
+    @MockBean
+    ModelRepository modelRepository;
+    @MockBean
+    SchemaCleanUpService schemaCleanUpService;
 
-    @AfterEach
-    protected void tearDown() {
-        healthStatus.setSchemaInitialized(false);
-    }
+    @MockBean
+    private SchemaHandler schemaHandler;
 
-    @Test
-    void upAndHealthy() throws Exception {
-        mvc.perform(get(readinessProbePath).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(
-                content().json("{'status' : 'UP'}"));
-        mvc.perform(get(livenessProbePath).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(
-                content().json("{'status' : 'UP'}"));
-        mvc.perform(get(tiesExposureProbePath).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
-                .andExpect(content().json(String.format("{'status':'UP','details':{'UP': '%s is UP and Healthy.'}}",
-                        SERVICE_NAME)));
-    }
+    @MockBean
+    private DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka;
 
     @Test
-    void upSchemaServiceLoaded() throws Exception {
-        SchemaHandler schemaHandlerSpy = Mockito.spy(new SchemaHandler(postgresSchemaLoader, healthStatus));
-        schemaHandlerSpy.initializeSchema();
-        Assertions.assertTrue(healthStatus.isSchemaInitialized());
+    void upAndHealthy() throws Exception {
+        healthStatus.setSchemaInitialized(true);
+        doReturn(true).when(dependentServiceAvailabilityKafka).checkService();
         mvc.perform(get(readinessProbePath).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(
                 content().json("{'status' : 'UP'}"));
         mvc.perform(get(livenessProbePath).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(
@@ -88,6 +82,7 @@ class TiesExposureHealthIndicatorTest {
     @Test
     void downSchemaServiceNotLoaded() throws Exception {
         healthStatus.setSchemaInitialized(false);
+        doReturn(true).when(dependentServiceAvailabilityKafka).checkService();
         performReadinessGroupProbesDownWithMessage(" Schema is yet to be initialized.");
     }
 
index 75fbed1..312cff0 100644 (file)
@@ -29,6 +29,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.service.SchemaCleanUpService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -44,7 +46,7 @@ import org.oran.smo.teiv.startup.SchemaHandler;
 @AutoConfigureMockMvc
 @SpringBootTest(properties = { "spring.profiles.active=test,ingestion", "management.endpoint.health.probes.enabled=true",
         "management.endpoint.health.group.readiness.include=readinessState,tiesIngestion" })
-public class TiesIngestionHealthIndicatorTest {
+class TiesIngestionHealthIndicatorTest {
     private final String readinessProbePath = "/actuator/health/readiness";
     private final String livenessProbePath = "/actuator/health/liveness";
     private final String tiesIngestionProbePath = "/actuator/health/tiesIngestion";
@@ -62,6 +64,10 @@ public class TiesIngestionHealthIndicatorTest {
 
     @MockBean
     PostgresSchemaLoader postgresSchemaLoader;
+    @MockBean
+    ModelRepository modelRepository;
+    @MockBean
+    SchemaCleanUpService schemaCleanUpService;
 
     @AfterEach
     protected void tearDown() {
@@ -91,7 +97,8 @@ public class TiesIngestionHealthIndicatorTest {
 
     @Test
     void downKafkaUnavailable() throws Exception {
-        SchemaHandler schemaHandlerSpy = Mockito.spy(new SchemaHandler(postgresSchemaLoader, healthStatus));
+        SchemaHandler schemaHandlerSpy = Mockito.spy(new SchemaHandler(postgresSchemaLoader, healthStatus, modelRepository,
+                schemaCleanUpService));
         schemaHandlerSpy.initializeSchema();
         assertTrue(healthStatus.isSchemaInitialized());
         doReturn(false).when(spiedDependentServiceAvailabilityKafka).checkService();
index db7f18a..ff0cb66 100644 (file)
@@ -43,7 +43,12 @@ public class TestPostgresqlContainer extends PostgreSQLContainer<TestPostgresqlC
                     "pgsqlschema/00_init-oran-smo-teiv-data.sql"), "/pgsqlschema/00_init-oran-smo-teiv-data.sql");
             container.withCopyFileToContainer(MountableFile.forClasspathResource(
                     "pgsqlschema/01_init-oran-smo-teiv-model.sql"), "/pgsqlschema/01_init-oran-smo-teiv-model.sql");
-            container.withCopyFileToContainer(MountableFile.forClasspathResource("data/data.sql"), "/02_data.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource(
+                    "pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql"),
+                    "/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource("pgsqlschema/data.sql"), "/03_data.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource("pgsqlschema/consumer-data-v1.sql"),
+                    "/04_consumer-data.sql");
             container.setCommand("postgres", "-c", "max_connections=2000");
 
             container.start();
@@ -52,6 +57,8 @@ public class TestPostgresqlContainer extends PostgreSQLContainer<TestPostgresqlC
                         "--set=pguser=\"test\";");
                 container.execInContainer("psql", "-U", "test", "-w", "-f", "/pgsqlschema/01_init-oran-smo-teiv-model.sql",
                         "--set=pguser=\"test\";");
+                container.execInContainer("psql", "-U", "test", "-w", "-f",
+                        "/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql", "--set=pguser=\"test\";");
             } catch (UnsupportedOperationException | IOException | InterruptedException e) {
                 throw new RuntimeException(e.getMessage());
             }
@@ -61,7 +68,8 @@ public class TestPostgresqlContainer extends PostgreSQLContainer<TestPostgresqlC
 
     public static void loadSampleData() {
         try {
-            container.execInContainer("psql", "-U", "test", "-w", "-f", "/02_data.sql", "--set=pguser=\"test\";");
+            container.execInContainer("psql", "-U", "test", "-w", "-f", "/03_data.sql", "--set=pguser=\"test\";");
+            container.execInContainer("psql", "-U", "test", "-w", "-f", "/04_consumer-data.sql", "--set=pguser=\"test\";");
         } catch (UnsupportedOperationException | IOException | InterruptedException e) {
             throw new RuntimeException(e.getMessage());
         }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/db/TestPostgresqlContainerV1.java b/teiv/src/test/java/org/oran/smo/teiv/db/TestPostgresqlContainerV1.java
new file mode 100644 (file)
index 0000000..581059f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  ============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.teiv.db;
+
+import java.io.IOException;
+
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.utility.DockerImageName;
+import org.testcontainers.utility.MountableFile;
+
+public class TestPostgresqlContainerV1 extends PostgreSQLContainer<TestPostgresqlContainerV1> {
+
+    private static TestPostgresqlContainerV1 container;
+
+    private TestPostgresqlContainerV1(DockerImageName image) {
+        super(image);
+    }
+
+    public static TestPostgresqlContainerV1 getInstance() {
+        if (container == null) {
+            container = new TestPostgresqlContainerV1(DockerImageName.parse("postgis/postgis:13-3.4-alpine")
+                    .asCompatibleSubstituteFor("postgres"));
+            container.withCopyFileToContainer(MountableFile.forClasspathResource(
+                    "pgsqlschema/01_init-oran-smo-teiv-model-v1.sql"), "/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource(
+                    "pgsqlschema/00_init-oran-smo-teiv-data-v1.sql"), "/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource(
+                    "pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql"),
+                    "/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource("pgsqlschema/model.sql"),
+                    "/pgsqlschema/model.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource("pgsqlschema/data-v1.sql"),
+                    "/pgsqlschema/data-v1.sql");
+            container.withCopyFileToContainer(MountableFile.forClasspathResource("pgsqlschema/consumer-data-v1.sql"),
+                    "/pgsqlschema/consumer-data-v1.sql");
+            container.setCommand("postgres", "-c", "max_connections=2000");
+
+            container.start();
+            try {
+                container.execInContainer("psql", "-U", "test", "-w", "-f",
+                        "/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql", "--set=pguser=\"test\";");
+                container.execInContainer("psql", "-U", "test", "-w", "-f", "/pgsqlschema/model.sql",
+                        "--set=pguser=\"test\";");
+                container.execInContainer("psql", "-U", "test", "-w", "-f",
+                        "/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql", "--set=pguser=\"test\";");
+                container.execInContainer("psql", "-U", "test", "-w", "-f",
+                        "/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql", "--set=pguser=\"test\";");
+                container.execInContainer("psql", "-U", "test", "-w", "-f", "/pgsqlschema/consumer-data-v1.sql",
+                        "--set=pguser=\"test\";");
+            } catch (UnsupportedOperationException | IOException | InterruptedException e) {
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+        return container;
+    }
+
+    public static void loadSampleData() {
+        try {
+            container.execInContainer("psql", "-U", "test", "-w", "-f", "/pgsqlschema/data-v1.sql",
+                    "--set=pguser=\"test\";");
+            container.execInContainer("psql", "-U", "test", "-w", "-f", "/pgsqlschema/consumer-data-v1.sql",
+                    "--set=pguser=\"test\";");
+        } catch (UnsupportedOperationException | IOException | InterruptedException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedNonXPathTest.java b/teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedNonXPathTest.java
deleted file mode 100644 (file)
index d6dea51..0000000
+++ /dev/null
@@ -1,317 +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 org.oran.smo.teiv.e2e;
-
-import org.oran.smo.teiv.api.model.OranTeivDomains;
-import org.oran.smo.teiv.api.model.OranTeivDomainsItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypes;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-
-import org.oran.smo.teiv.db.TestPostgresqlContainer;
-import org.oran.smo.teiv.exposure.data.rest.controller.DataRestController;
-import org.oran.smo.teiv.schema.PostgresSchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.jooq.DSLContext;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
-import javax.sql.DataSource;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import static org.oran.smo.teiv.utils.TiesConstants.TEIV_DOMAIN;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
-
-@Slf4j
-@ActiveProfiles({ "test", "exposure" })
-@SpringBootTest
-public class DataControllerE2EContainerizedNonXPathTest {
-
-    public static final String ACCEPT_TYPE = "application/yang+json";
-
-    @Autowired
-    public DataRestController underTest;
-    public static TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
-
-    @Autowired
-    DSLContext writeDataDslContext;
-
-    @DynamicPropertySource
-    static void setProperties(DynamicPropertyRegistry registry) {
-        registry.add("spring.datasource.read.jdbc-url", () -> postgreSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.read.username", () -> postgreSQLContainer.getUsername());
-        registry.add("spring.datasource.read.password", () -> postgreSQLContainer.getPassword());
-
-        registry.add("spring.datasource.write.jdbc-url", () -> postgreSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.write.username", () -> postgreSQLContainer.getUsername());
-        registry.add("spring.datasource.write.password", () -> postgreSQLContainer.getPassword());
-    }
-
-    @BeforeAll
-    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
-        String url = postgreSQLContainer.getJdbcUrl();
-        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
-        DSLContext dslContext = DSL.using(ds, SQLDialect.POSTGRES);
-        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(dslContext, new ObjectMapper());
-        postgresSchemaLoader.loadSchemaRegistry();
-    }
-
-    @BeforeEach
-    public void deleteAll() {
-        writeDataDslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(
-                t -> writeDataDslContext.truncate(t).cascade().execute());
-        TestPostgresqlContainer.loadSampleData();
-    }
-
-    @Test
-    public void testGetAllDomains() {
-        final OranTeivDomains responseMessage = underTest.getAllDomains(ACCEPT_TYPE, 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage);
-        Assertions.assertEquals(9, responseMessage.getItems().size());
-
-        Map<String, String> expectedData = new HashMap<>();
-        expectedData.put("name", TEIV_DOMAIN);
-        expectedData.put("entityTypes", "/domains/" + TEIV_DOMAIN + "/entity-types");
-        expectedData.put("relationshipTypes", "/domains/" + TEIV_DOMAIN + "/relationship-types");
-
-        OranTeivDomainsItemsInner actualItem = responseMessage.getItems().get(8);
-
-        Assertions.assertEquals(expectedData.get("name"), actualItem.getName());
-        Assertions.assertEquals(expectedData.get("entityTypes"), actualItem.getEntityTypes().getHref());
-        Assertions.assertEquals(expectedData.get("relationshipTypes"), actualItem.getRelationshipTypes().getHref());
-
-        Map<String, String> expectedDataCloud = new HashMap<>();
-        expectedDataCloud.put("name", "CLOUD");
-        expectedDataCloud.put("entityTypes", "/domains/CLOUD/entity-types");
-        expectedDataCloud.put("relationshipTypes", "/domains/CLOUD/relationship-types");
-
-        OranTeivDomainsItemsInner actualItemCloud = responseMessage.getItems().get(0);
-
-        Assertions.assertEquals(expectedDataCloud.get("name"), actualItemCloud.getName());
-        Assertions.assertEquals(expectedDataCloud.get("entityTypes"), actualItemCloud.getEntityTypes().getHref());
-        Assertions.assertEquals(expectedDataCloud.get("relationshipTypes"), actualItemCloud.getRelationshipTypes()
-                .getHref());
-
-        Map<String, String> expectedDataLogicalToEquipment = new HashMap<>();
-        expectedDataLogicalToEquipment.put("name", "EQUIPMENT_TO_RAN");
-        expectedDataLogicalToEquipment.put("entityTypes", "/domains/EQUIPMENT_TO_RAN/entity-types");
-        expectedDataLogicalToEquipment.put("relationshipTypes", "/domains/EQUIPMENT_TO_RAN/relationship-types");
-
-        OranTeivDomainsItemsInner actualItemLogicalToEquipment = responseMessage.getItems().get(3);
-
-        Assertions.assertEquals(expectedDataLogicalToEquipment.get("name"), actualItemLogicalToEquipment.getName());
-        Assertions.assertEquals(expectedDataLogicalToEquipment.get("entityTypes"), actualItemLogicalToEquipment
-                .getEntityTypes().getHref());
-        Assertions.assertEquals(expectedDataLogicalToEquipment.get("relationshipTypes"), actualItemLogicalToEquipment
-                .getRelationshipTypes().getHref());
-    }
-
-    @Test
-    public void testGetTopologyEntityTypes() {
-        final OranTeivEntityTypes responseMessage = underTest.getTopologyEntityTypes(ACCEPT_TYPE, "EQUIPMENT_TO_RAN", 0, 20)
-                .getBody();
-
-        Assertions.assertNotNull(responseMessage);
-        Assertions.assertEquals(20, responseMessage.getItems().size());
-
-        Map<String, String> expectedSite = new HashMap<>();
-        expectedSite.put("name", "Site");
-        expectedSite.put("entities", "/domains/EQUIPMENT_TO_RAN/entity-types/Site/entities");
-
-        OranTeivEntityTypesItemsInner item1 = responseMessage.getItems().stream().filter(items -> {
-            return "Site".equals(items.getName());
-        }).findFirst().get();
-        Assertions.assertEquals(expectedSite.get("name"), item1.getName());
-        Assertions.assertEquals(expectedSite.get("entities"), item1.getEntities().getHref());
-
-        Map<String, String> expectedNRCellCu = new HashMap<>();
-        expectedNRCellCu.put("name", "NRCellCU");
-        expectedNRCellCu.put("entities", "/domains/EQUIPMENT_TO_RAN/entity-types/NRCellCU/entities");
-
-        OranTeivEntityTypesItemsInner item2 = responseMessage.getItems().stream().filter(items -> {
-            return "NRCellCU".equals(items.getName());
-        }).findFirst().get();
-        Assertions.assertEquals(expectedNRCellCu.get("name"), item2.getName());
-        Assertions.assertEquals(expectedNRCellCu.get("entities"), item2.getEntities().getHref());
-
-        Map<String, String> expectedGNBCUUFunction = new HashMap<>();
-        expectedGNBCUUFunction.put("name", "GNBCUUPFunction");
-        expectedGNBCUUFunction.put("entities", "/domains/EQUIPMENT_TO_RAN/entity-types/GNBCUUPFunction/entities");
-
-        OranTeivEntityTypesItemsInner item3 = responseMessage.getItems().stream().filter(items -> {
-            return "GNBCUUPFunction".equals(items.getName());
-        }).findFirst().get();
-        Assertions.assertEquals(expectedGNBCUUFunction.get("name"), item3.getName());
-        Assertions.assertEquals(expectedGNBCUUFunction.get("entities"), item3.getEntities().getHref());
-    }
-
-    @Test
-    public void testGetTopologyRelationshipTypes() {
-        final OranTeivRelationshipTypes responseMessage = underTest.getTopologyRelationshipTypes(ACCEPT_TYPE,
-                "EQUIPMENT_TO_RAN", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage);
-        Assertions.assertEquals(20, responseMessage.getItems().size());
-
-        Map<String, String> expectedData1 = new HashMap<>();
-        expectedData1.put("name", "NRCELLDU_USES_NRSECTORCARRIER");
-        expectedData1.put("relationships",
-                "/domains/EQUIPMENT_TO_RAN/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships");
-
-        OranTeivRelationshipTypesItemsInner item1 = responseMessage.getItems().get(14);
-        Assertions.assertEquals(expectedData1.get("name"), item1.getName());
-        Assertions.assertEquals(expectedData1.get("relationships"), item1.getRelationships().getHref());
-
-        Map<String, String> expectedData2 = new HashMap<>();
-        expectedData2.put("name", "ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE");
-        expectedData2.put("relationships",
-                "/domains/EQUIPMENT_TO_RAN/relationship-types/ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE/relationships");
-
-        OranTeivRelationshipTypesItemsInner item2 = responseMessage.getItems().get(1);
-        Assertions.assertEquals(expectedData2.get("name"), item2.getName());
-        Assertions.assertEquals(expectedData2.get("relationships"), item2.getRelationships().getHref());
-
-        Map<String, String> expectedData3 = new HashMap<>();
-        expectedData3.put("name", "SECTOR_GROUPS_ANTENNAMODULE");
-        expectedData3.put("relationships",
-                "/domains/EQUIPMENT_TO_RAN/relationship-types/SECTOR_GROUPS_ANTENNAMODULE/relationships");
-
-        OranTeivRelationshipTypesItemsInner item3 = responseMessage.getItems().get(17);
-        Assertions.assertEquals(expectedData3.get("name"), item3.getName());
-        Assertions.assertEquals(expectedData3.get("relationships"), item3.getRelationships().getHref());
-    }
-
-    @Test
-    public void testGetTopologyById() {
-        final Object responseMessage = underTest.getTopologyById(ACCEPT_TYPE, "RAN", "Sector",
-                "2F445AA5744FA3D230FD6838531F1407").getBody();
-
-        Assertions.assertNotNull(responseMessage);
-
-        Map<String, Object> expectedResponse = new HashMap<>();
-        Map<String, Object> innerMap = new HashMap<>();
-        Map<String, Object> attributes = new HashMap<>();
-
-        attributes.put("sectorId", 1);
-        attributes.put("geo-location", "POINT(59.4019881 17.9419888)");
-        attributes.put("sectorId", 1);
-        attributes.put("azimuth", 1);
-
-        innerMap.put("attributes", attributes);
-        innerMap.put("id", "2F445AA5744FA3D230FD6838531F1407");
-        innerMap.put("sourceIds", Collections.EMPTY_LIST);
-
-        expectedResponse.put("o-ran-smo-teiv-ran:Sector", Collections.singletonList(innerMap));
-
-        Map<String, Object> actualResponse = (Map<String, Object>) responseMessage;
-
-        Assertions.assertEquals(expectedResponse.size(), actualResponse.size());
-        for (Map.Entry<String, Object> entry : expectedResponse.entrySet()) {
-            String key = entry.getKey();
-            Object expectedValue = entry.getValue();
-            Object actualValue = actualResponse.get(key);
-            if (expectedValue instanceof List && actualValue instanceof List) {
-                List<?> expectedList = (List<?>) expectedValue;
-                List<?> actualList = (List<?>) actualValue;
-                Assertions.assertEquals(expectedList.size(), actualList.size());
-                for (int i = 0; i < expectedList.size(); i++) {
-                    Object expectedMap = expectedList.get(i);
-                    Object actualMap = actualList.get(i);
-                    Assertions.assertTrue(expectedMap instanceof Map);
-                    Assertions.assertTrue(actualMap instanceof Map);
-                    String expectedAttributesString = ((Map<String, Object>) expectedMap).get("attributes").toString();
-                    String actualAttributesString = ((Map<String, Object>) actualMap).get("attributes").toString();
-                    Assertions.assertEquals(expectedAttributesString, actualAttributesString);
-                }
-            } else {
-                Assertions.assertEquals(expectedValue, actualValue);
-            }
-        }
-    }
-
-    @Test
-    public void testGetAllRelationshipsForEntityId() {
-        final OranTeivRelationshipsResponseMessage responseMessage = underTest.getAllRelationshipsForEntityId(ACCEPT_TYPE,
-                "RAN", "Sector", "2F445AA5744FA3D230FD6838531F1407", "", "", 0, 10).getBody();
-
-        Assertions.assertNotNull(responseMessage);
-        Assertions.assertEquals(0, responseMessage.getTotalCount());
-        Assertions.assertTrue(responseMessage.getItems().isEmpty());
-
-        final OranTeivRelationshipsResponseMessage responseMessage2 = underTest.getAllRelationshipsForEntityId(ACCEPT_TYPE,
-                "RAN", "GNBDUFunction", "1050570EBB1315E1AE7A9FD5E1400A00", "", "", 0, 10).getBody();
-
-        Assertions.assertNotNull(responseMessage2);
-        Assertions.assertEquals(1, responseMessage2.getTotalCount());
-
-        Map<String, Object> innerResponse = new HashMap<>();
-        innerResponse.put("bSide", "1050570EBB1315E1AE7A9FD5E1400A00");
-        innerResponse.put("aSide", "6F02817AFE4D53237DB235EBE5378613");
-        innerResponse.put("id",
-                "urn:base64:TWFuYWdlZEVsZW1lbnQ6NkYwMjgxN0FGRTRENTMyMzdEQjIzNUVCRTUzNzg2MTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjEwNTA1NzBFQkIxMzE1RTFBRTdBOUZENUUxNDAwQTAw");
-        Map<String, Object> response = new HashMap<>();
-        response.put("o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", List.of(innerResponse));
-        Assertions.assertEquals(response, responseMessage2.getItems().get(0));
-    }
-
-    @Test
-    public void testGetRelationshipById() {
-        final Object responseMessage = underTest.getRelationshipById(ACCEPT_TYPE, "CLOUD",
-                "NODECLUSTER_LOCATED_AT_CLOUDSITE",
-                "urn:base64:Tm9kZUNsdXN0ZXI6MDE1QzJEREJEN0FDNzIyQjM0RUQ2QTIwRURFRUI5QzM6TE9DQVRFRF9BVDpDbG91ZFNpdGU6MTZFRTE3QUU4OURGMTFCNjlFOTRCM0Y2ODI3QzJDMEU=")
-                .getBody();
-
-        Assertions.assertNotNull(responseMessage);
-        Assertions.assertTrue(responseMessage instanceof Map);
-
-        Map<String, List<Map<String, Object>>> responseMap = (Map<String, List<Map<String, Object>>>) responseMessage;
-
-        Assertions.assertTrue(responseMap.containsKey("o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE"));
-        List<Map<String, Object>> relationshipList = responseMap.get(
-                "o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE");
-
-        Assertions.assertNotNull(relationshipList);
-        Assertions.assertFalse(relationshipList.isEmpty());
-
-        for (Map<String, Object> relationship : relationshipList) {
-            Assertions.assertTrue(relationship.containsKey("bSide"));
-            Assertions.assertTrue(relationship.containsKey("aSide"));
-            Assertions.assertTrue(relationship.containsKey("id"));
-            Assertions.assertTrue(relationship.containsKey("sourceIds"));
-        }
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedTest.java b/teiv/src/test/java/org/oran/smo/teiv/e2e/DataControllerE2EContainerizedTest.java
deleted file mode 100644 (file)
index 8a6cf1f..0000000
+++ /dev/null
@@ -1,249 +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 org.oran.smo.teiv.e2e;
-
-import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-import org.oran.smo.teiv.db.TestPostgresqlContainer;
-import org.oran.smo.teiv.exposure.data.rest.controller.DataRestController;
-import org.oran.smo.teiv.schema.PostgresSchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.jooq.DSLContext;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
-
-import javax.sql.DataSource;
-
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
-
-import java.util.*;
-
-@Slf4j
-@ActiveProfiles({ "test", "exposure" })
-@SpringBootTest
-public class DataControllerE2EContainerizedTest {
-
-    public static final String ACCEPT_TYPE = "application/yang+json";
-
-    @Autowired
-    public DataRestController underTest;
-    public static TestPostgresqlContainer postgresSQLContainer = TestPostgresqlContainer.getInstance();
-
-    @Autowired
-    DSLContext writeDataDslContext;
-
-    @DynamicPropertySource
-    static void setProperties(DynamicPropertyRegistry registry) {
-        registry.add("spring.datasource.read.jdbc-url", () -> postgresSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.read.username", () -> postgresSQLContainer.getUsername());
-        registry.add("spring.datasource.read.password", () -> postgresSQLContainer.getPassword());
-
-        registry.add("spring.datasource.write.jdbc-url", () -> postgresSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.write.username", () -> postgresSQLContainer.getUsername());
-        registry.add("spring.datasource.write.password", () -> postgresSQLContainer.getPassword());
-    }
-
-    @BeforeAll
-    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
-        String url = postgresSQLContainer.getJdbcUrl();
-        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
-        DSLContext dslContext = DSL.using(ds, SQLDialect.POSTGRES);
-        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(dslContext, new ObjectMapper());
-        postgresSchemaLoader.loadSchemaRegistry();
-    }
-
-    @BeforeEach
-    public void deleteAll() {
-        writeDataDslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(
-                t -> writeDataDslContext.truncate(t).cascade().execute());
-        TestPostgresqlContainer.loadSampleData();
-    }
-
-    @Test
-    public void getRelationshipsByTypeWithoutScopeFilterTest() {
-        final OranTeivRelationshipsResponseMessage responseMessage1 = underTest.getRelationshipsByType(ACCEPT_TYPE, "RAN",
-                "NRCELLDU_USES_NRSECTORCARRIER", null, "", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-        Map<String, Object> innerResponse = new HashMap<>();
-        innerResponse.put("bSide", "E49D942C16E0364E1E0788138916D70C");
-        innerResponse.put("aSide", "B480427E8A0C0B8D994E437784BB382F");
-        innerResponse.put("id",
-                "urn:base64:TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM=");
-        Map<String, Object> response = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER", List.of(innerResponse));
-        Assertions.assertEquals(response, responseMessage1.getItems().get(0));
-    }
-
-    @Test
-    public void getRelationshipsByTypeWithScopeFilterTest() {
-        final OranTeivRelationshipsResponseMessage responseMessage1 = underTest.getRelationshipsByType(ACCEPT_TYPE, "RAN",
-                "SECTOR_GROUPS_NRCELLDU", null, "/NRCellDU/attributes[@cellLocalId=1]", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-        Map<String, Object> innerResponse = new HashMap<>();
-        innerResponse.put("bSide", "98C3A4591A37718E1330F0294E23B62A");
-        innerResponse.put("aSide", "F5128C172A70C4FCD4739650B06DE9E2");
-        innerResponse.put("id",
-                "urn:base64:U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==");
-        Map<String, Object> response = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU", List.of(innerResponse));
-        Assertions.assertEquals(response, responseMessage1.getItems().get(0));
-    }
-
-    @Test
-    public void getTopologyByEntityTypeNameWithScopeFilterTest() {
-        final OranTeivEntitiesResponseMessage responseMessage1 = underTest.getTopologyByEntityTypeName(
-
-                ACCEPT_TYPE, "RAN", "NRCellDU", null, "/NRCellDU/attributes[@cellLocalId=1]", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-        Map<String, Object> innerResponse = new HashMap<>();
-        innerResponse.put("id", "98C3A4591A37718E1330F0294E23B62A");
-
-        Map<String, Object> response = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:NRCellDU", List.of(innerResponse));
-        Assertions.assertEquals(response, responseMessage1.getItems().get(0));
-    }
-
-    @Test
-    public void getTopologyByEntityTypeWithoutScopeFilterTest() {
-        final OranTeivEntitiesResponseMessage responseMessage1 = underTest.getTopologyByEntityTypeName(
-
-                ACCEPT_TYPE, "RAN", "NRCellDU", null, "", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-
-        List<String> ids = new ArrayList<>();
-        ids.add("67A1BDA10B5AF43028D07C7BE5CB1AE2");
-        ids.add("76E9F605D4F37330BF0B505E94F64F11");
-        ids.add("98C3A4591A37718E1330F0294E23B62A");
-        ids.add("B3B0A1939EFCA654A37005B6A7F24BD7");
-        ids.add("B480427E8A0C0B8D994E437784BB382F");
-        ids.add("F9546E82313AC1D5E690DCD7BE55606F");
-
-        List<Map<String, String>> idList = new ArrayList<>();
-        for (String id : ids) {
-            Map<String, String> idMap = new HashMap<>();
-            idMap.put("id", id);
-            idList.add(idMap);
-        }
-
-        Map<String, Object> response = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:NRCellDU", idList);
-        Assertions.assertEquals(response, responseMessage1.getItems().get(0));
-    }
-
-    @Test
-    public void getEntitiesByDomainWithoutScopeFilter() {
-        final OranTeivEntitiesResponseMessage responseMessage1 = underTest.getEntitiesByDomain(ACCEPT_TYPE, "RAN",
-                "/NRCellDU/attributes/nCI", "", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-
-        @SuppressWarnings("unchecked") List<Map<String, Object>> actualList = (List<Map<String, Object>>) ((Map<String, Object>) responseMessage1
-                .getItems().get(0)).get("o-ran-smo-teiv-ran:NRCellDU");
-
-        List<Map<String, Object>> expectedList = new ArrayList<>();
-        Map<String, Object> entity = new HashMap<>();
-
-        entity.put("attributes", Map.of("nCI", 1));
-        entity.put("id", "98C3A4591A37718E1330F0294E23B62A");
-        expectedList.add(entity);
-
-        entity = new HashMap<>();
-        entity.put("attributes", Map.of("nCI", 2));
-        entity.put("id", "F9546E82313AC1D5E690DCD7BE55606F");
-        expectedList.add(entity);
-
-        entity = new HashMap<>();
-        entity.put("attributes", Map.of("nCI", 3));
-        entity.put("id", "B480427E8A0C0B8D994E437784BB382F");
-        expectedList.add(entity);
-
-        entity = new HashMap<>();
-        entity.put("attributes", Map.of("nCI", 91));
-        entity.put("id", "76E9F605D4F37330BF0B505E94F64F11");
-        expectedList.add(entity);
-
-        entity = new HashMap<>();
-        entity.put("attributes", Map.of("nCI", 92));
-        entity.put("id", "67A1BDA10B5AF43028D07C7BE5CB1AE2");
-        expectedList.add(entity);
-
-        entity = new HashMap<>();
-        entity.put("attributes", Map.of("nCI", 93));
-        entity.put("id", "B3B0A1939EFCA654A37005B6A7F24BD7");
-        expectedList.add(entity);
-
-        Assertions.assertEquals(expectedList.size(), actualList.size());
-        for (int i = 0; i < expectedList.size(); i++) {
-            Map<String, Object> actualEntity = actualList.get(i);
-            Map<String, Object> expectedEntity = expectedList.get(i);
-
-            Map<String, Object> actualAttributes = (Map<String, Object>) actualEntity.get("attributes");
-            Map<String, Object> expectedAttributes = (Map<String, Object>) expectedEntity.get("attributes");
-
-            Assertions.assertEquals(((Number) expectedAttributes.get("nCI")).intValue(), ((Number) actualAttributes.get(
-                    "nCI")).intValue());
-
-        }
-    }
-
-    @Test
-    public void getEntitiesByDomainWithScopeFilter() {
-        final String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
-        final OranTeivEntitiesResponseMessage responseMessage1 = underTest.getEntitiesByDomain(ACCEPT_TYPE, "RAN",
-                "/NRCellDU/attributes/nCI", "/NRCellDU/attributes[@cellLocalId=1]", 0, 20).getBody();
-
-        Assertions.assertNotNull(responseMessage1);
-        Assertions.assertEquals(1, responseMessage1.getItems().size());
-
-        Map<String, Object> actualResponseMap = new HashMap<>((Map<String, Object>) responseMessage1.getItems().get(0));
-
-        Map<String, Object> expectedResponse = new HashMap<>();
-        Map<String, Object> innerMap = new HashMap<>();
-        Map<String, Object> attributes = new HashMap<>();
-        attributes.put("nCI", 1);
-        innerMap.put("id", "98C3A4591A37718E1330F0294E23B62A");
-        innerMap.put("attributes", attributes);
-        expectedResponse.put("o-ran-smo-teiv-ran:NRCellDU", List.of(innerMap));
-
-        Assertions.assertEquals(expectedResponse.toString(), actualResponseMap.toString());
-    }
-}
index 44360ee..345472e 100644 (file)
  */
 package org.oran.smo.teiv.exposure.api.contract;
 
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.exposure.utils.RequestValidator;
-import java.util.List;
+import javax.sql.DataSource;
 
-import org.oran.smo.teiv.api.model.OranTeivSchema;
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.api.model.OranTeivSchemaList;
-import org.oran.smo.teiv.exposure.api.contract.utils.RelationshipTestUtility;
-import org.oran.smo.teiv.exposure.api.contract.utils.TopologyObjectTestUtility;
-import org.oran.smo.teiv.exposure.data.api.impl.DataServiceImpl;
-import org.oran.smo.teiv.exposure.data.rest.controller.DataRestController;
-import org.oran.smo.teiv.exposure.exception.ApplicationExceptionHandler;
-import org.oran.smo.teiv.exposure.model.api.impl.ModelSchemaServiceImpl;
-import org.oran.smo.teiv.exposure.model.rest.controller.ModelSchemaRestController;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-
-import org.junit.jupiter.api.AfterAll;
+import org.jooq.DSLContext;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.oran.smo.teiv.db.TestPostgresqlContainerV1;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder;
+import org.springframework.web.context.WebApplicationContext;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
 import io.restassured.module.mockmvc.RestAssuredMockMvc;
 
-@ExtendWith(MockitoExtension.class)
+import org.oran.smo.teiv.schema.PostgresSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+import org.oran.smo.teiv.startup.SchemaHandler;
+
+@AutoConfigureMockMvc
+@SpringBootTest
 public abstract class TopologyExposureApiBase {
+    public static TestPostgresqlContainerV1 postgresSQLContainer = TestPostgresqlContainerV1.getInstance();
 
-    private static final ModelSchemaServiceImpl modelSchemaService = Mockito.mock(ModelSchemaServiceImpl.class);
+    @MockBean
+    private SchemaHandler schemaHandler;
 
-    private static final DataServiceImpl dataService = Mockito.mock(DataServiceImpl.class);
-    private static final CustomMetrics customMetrics = Mockito.mock(CustomMetrics.class);
-    private static final RequestValidator requestValidator = Mockito.mock(RequestValidator.class);
+    @Autowired
+    private ApplicationContext context;
 
-    @InjectMocks
-    private ModelSchemaRestController modelSchemaRestController;
+    @Autowired
+    private MockMvc mockMvc;
 
-    @InjectMocks
-    private DataRestController dataRestController;
+    @DynamicPropertySource
+    static void setProperties(DynamicPropertyRegistry registry) {
+        registry.add("spring.datasource.read.jdbc-url", () -> postgresSQLContainer.getJdbcUrl());
+        registry.add("spring.datasource.read.username", () -> postgresSQLContainer.getUsername());
+        registry.add("spring.datasource.read.password", () -> postgresSQLContainer.getPassword());
 
-    @BeforeEach
-    public void setup() {
-        mockData();
-        final StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(modelSchemaRestController,
-                dataRestController).setControllerAdvice(new ApplicationExceptionHandler());
-        RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder);
-    }
-
-    public void mockData() {
-        RelationshipTestUtility.getMockForAllRelationshipsForObjectId(dataService);
-        TopologyObjectTestUtility.getMockForAllTopologyObjectById(dataService);
+        registry.add("spring.datasource.write.jdbc-url", () -> postgresSQLContainer.getJdbcUrl());
+        registry.add("spring.datasource.write.username", () -> postgresSQLContainer.getUsername());
+        registry.add("spring.datasource.write.password", () -> postgresSQLContainer.getPassword());
     }
 
     @BeforeAll
-    public static void mockModelSchemaData() {
-
-        OranTeivSchema schemasMetaData = new OranTeivSchema();
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/schemas/o-ran-smo-teiv-cloud-to-ran/content");
-        schemasMetaData.setName("o-ran-smo-teiv-cloud-to-ran");
-        schemasMetaData.setDomain("CLOUD_TO_RAN");
-        schemasMetaData.setRevision("2023-06-26");
-        schemasMetaData.setContent(href);
-
-        List<OranTeivSchema> schemaList = List.of(schemasMetaData);
-
-        OranTeivSchemaList schemas = new OranTeivSchemaList();
-        schemas.setItems(schemaList);
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref("/schemas?offset=0&limit=100");
-        schemas.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref("/schemas?offset=0&limit=100");
-        schemas.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref("/schemas?offset=0&limit=100");
-        schemas.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref("/schemas?offset=0&limit=100");
-        schemas.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref("/schemas?offset=0&limit=100");
-        schemas.setLast(hrefLast);
-
-        OranTeivSchemaList schemaQuery = new OranTeivSchemaList();
-        schemaQuery.setItems(schemaList);
-        OranTeivHref hrefFirst1 = new OranTeivHref();
-        hrefFirst1.setHref("/schemas?domain=RAN&offset=0&limit=8");
-        schemaQuery.setFirst(hrefFirst1);
-        OranTeivHref hrefNext1 = new OranTeivHref();
-        hrefNext1.setHref("/schemas?domain=RAN&offset=0&limit=8");
-        schemaQuery.setNext(hrefNext1);
-        OranTeivHref hrefPrev1 = new OranTeivHref();
-        hrefPrev1.setHref("/schemas?domain=RAN&offset=0&limit=8");
-        schemaQuery.setPrev(hrefPrev1);
-        OranTeivHref hrefSelf1 = new OranTeivHref();
-        hrefSelf1.setHref("/schemas?domain=RAN&offset=0&limit=8");
-        schemaQuery.setSelf(hrefSelf1);
-        OranTeivHref hrefLast1 = new OranTeivHref();
-        hrefLast1.setHref("/schemas?domain=RAN&offset=0&limit=8");
-        schemaQuery.setLast(hrefLast1);
-
-        OranTeivSchemaList emptyResponse = new OranTeivSchemaList();
-        emptyResponse.setItems(List.of());
-        OranTeivHref hrefFirst2 = new OranTeivHref();
-        hrefFirst2.setHref("/schemas?domain=LOGICAL&offset=0&limit=500");
-        emptyResponse.setFirst(hrefFirst2);
-        OranTeivHref hrefNext2 = new OranTeivHref();
-        hrefNext2.setHref("/schemas?domain=LOGICAL&offset=0&limit=500");
-        emptyResponse.setNext(hrefNext2);
-        OranTeivHref hrefPrev2 = new OranTeivHref();
-        hrefPrev2.setHref("/schemas?domain=LOGICAL&offset=0&limit=500");
-        emptyResponse.setPrev(hrefPrev2);
-        OranTeivHref hrefSelf2 = new OranTeivHref();
-        hrefSelf2.setHref("/schemas?domain=LOGICAL&offset=0&limit=500");
-        emptyResponse.setSelf(hrefSelf2);
-        OranTeivHref hrefLast2 = new OranTeivHref();
-        hrefLast2.setHref("/schemas?domain=LOGICAL&offset=0&limit=500");
-        emptyResponse.setLast(hrefLast2);
-
-        String modelSchema = "module o-ran-smo-teiv-cloud-to-ran { yang-version 1.1; }";
-
-        Mockito.when(modelSchemaService.getSchemas(PaginationDTO.builder().offset(0).limit(100).basePath("/schemas")
-                .build())).thenReturn(schemas).thenThrow(new RuntimeException());
-
-        Mockito.when(modelSchemaService.getSchemaByName("o-ran-smo-teiv-cloud-to-ran")).thenReturn(modelSchema).thenThrow(
-                new RuntimeException());
-
-        Mockito.when(modelSchemaService.getSchemasInDomain("RAN", PaginationDTO.builder().offset(0).limit(8).basePath(
-                "/schemas").addPathParameters("domain", "RAN").build())).thenReturn(schemaQuery).thenThrow(
-                        new RuntimeException());
-
-        Mockito.when(modelSchemaService.getSchemasInDomain("LOGICAL", PaginationDTO.builder().offset(0).limit(500).basePath(
-                "/schemas").addPathParameters("domain", "LOGICAL").build())).thenReturn(emptyResponse).thenThrow(
-                        new RuntimeException());
+    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
+        String url = postgresSQLContainer.getJdbcUrl();
+        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
+        DSLContext dslContext = DSL.using(ds, SQLDialect.POSTGRES);
+        TestPostgresqlContainerV1.loadSampleData();
+        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(dslContext, new ObjectMapper());
+        postgresSchemaLoader.loadSchemaRegistry();
     }
 
-    @AfterAll
-    public static void teardown() {
-        Mockito.reset(modelSchemaService);
+    @BeforeEach
+    public void setup() {
+        mockMvc = MockMvcBuilders.webAppContextSetup((WebApplicationContext) context).addFilters().build();
+
+        RestAssuredMockMvc.mockMvc(mockMvc);
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/RelationshipTestUtility.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/RelationshipTestUtility.java
deleted file mode 100644 (file)
index e80ac4e..0000000
+++ /dev/null
@@ -1,86 +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 org.oran.smo.teiv.exposure.api.contract.utils;
-
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.data.api.DataService;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-
-import static org.mockito.Mockito.when;
-
-public class RelationshipTestUtility {
-
-    private static final Map<String, Object> ITEMS = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-            Map.of("id", "urn:sha512:R05CRFVGdW5jdGlvbjpTdWJOZXR3b3JrPUV1cm9wZSxTdWJOZXR3", "aSide",
-                    "urn:3gpp:dn:ManagedElement=1,GNBDUFunction=1", "bSide",
-                    "urn:3gpp:dn:ManagedElement=1,GNBDUFunction=1,NRCellDU=1", "decorators", Map.of("location",
-                            "Stockholm"), "classifiers", List.of("Rural"), "sourceIds", new ArrayList<>(), "metadata", Map
-                                    .of("trustLevel", "RELIABLE"))));
-    private static DataService dataService;
-
-    public static void getMockForAllRelationshipsForObjectId(DataService dataService) {
-        RelationshipTestUtility.dataService = dataService;
-        mockRanGNBDUFunctionRelationships();
-    }
-
-    private static void mockRanGNBDUFunctionRelationships() {
-        OranTeivRelationshipsResponseMessage gnbduMap = new OranTeivRelationshipsResponseMessage();
-
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100");
-        gnbduMap.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100");
-        gnbduMap.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100");
-        gnbduMap.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100");
-        gnbduMap.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100");
-        gnbduMap.setLast(hrefLast);
-
-        gnbduMap.setItems(List.of(ITEMS));
-
-        when(dataService.getAllRelationshipsForObjectId(eq("GNBDUFunction"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1"),
-                any())).thenReturn(gnbduMap);
-
-        when(dataService.getAllRelationshipsForObjectId(eq("5GCell"), eq("R05CRFVGdW5jdGlvbg"), any())).thenThrow(
-                TiesException.unknownEntityType("5GCell", Collections.emptyList()));
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/TopologyObjectTestUtility.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/api/contract/utils/TopologyObjectTestUtility.java
deleted file mode 100644 (file)
index c367dfb..0000000
+++ /dev/null
@@ -1,164 +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 org.oran.smo.teiv.exposure.api.contract.utils;
-
-import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.data.api.DataService;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.endsWith;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-public class TopologyObjectTestUtility {
-
-    private static final Map<String, Object> ITEMS =
-
-            Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                    "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1", "attributes", Map.of(
-                            "gNBDUId", 1), "metadata", Map.of("trustLevel", "RELIABLE"))
-
-            ));
-
-    private static DataService dataService;
-
-    public static void getMockForAllTopologyObjectById(DataService dataService) {
-        TopologyObjectTestUtility.dataService = dataService;
-        mockRanGNBDUFunctionTopologyObject();
-        mockRanNRCellDUTopologyObject();
-    }
-
-    private static void mockRanGNBDUFunctionTopologyObject() {
-
-        OranTeivEntitiesResponseMessage gnbduMap = new OranTeivEntitiesResponseMessage();
-        OranTeivEntitiesResponseMessage gnbduQueryMap = new OranTeivEntitiesResponseMessage();
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50");
-        gnbduMap.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50");
-        gnbduMap.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50");
-        gnbduMap.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50");
-        gnbduMap.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50");
-        gnbduMap.setLast(hrefLast);
-
-        gnbduMap.setItems(List.of(ITEMS));
-
-        OranTeivHref hrefFirstQuery = new OranTeivHref();
-        hrefFirstQuery.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100");
-        gnbduQueryMap.setFirst(hrefFirstQuery);
-        OranTeivHref hrefNextQuery = new OranTeivHref();
-        hrefNextQuery.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100");
-        gnbduQueryMap.setNext(hrefNextQuery);
-        OranTeivHref hrefPrevQuery = new OranTeivHref();
-        hrefPrevQuery.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100");
-        gnbduQueryMap.setPrev(hrefPrevQuery);
-        OranTeivHref hrefSelfQuery = new OranTeivHref();
-        hrefSelfQuery.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100");
-        gnbduQueryMap.setSelf(hrefSelfQuery);
-        OranTeivHref hrefLastQuery = new OranTeivHref();
-        hrefLastQuery.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100");
-        gnbduQueryMap.setLast(hrefLastQuery);
-
-        gnbduQueryMap.setItems(List.of(ITEMS));
-
-        when(dataService.getTopologyById(eq("GNBDUFunction"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1")))
-                        .thenReturn(
-
-                                Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                                        "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1",
-                                        "attributes", Map.of("gNBId", 1, "gNBDUId", 1, "gNBIdLength", 2, "dUpLMNId", Map.of(
-                                                "mcc", "110", "mnc", "210")), "decorators", Map.of("location", "Stockholm"),
-                                        "classifiers", List.of("Rural"), "sourceIds", List.of(
-                                                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1"),
-                                        "metadata", Map.of("trustLevel", "RELIABLE")))));
-
-        when(dataService.getTopologyById(eq("GNBDUFunction"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D2")))
-                        .thenReturn(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=2", "attributes",
-                                Map.of("gNBId", 2, "gNBDUId", 2, "gNBIdLength", 2, "dUpLMNId", Map.of("mcc", "110", "mnc",
-                                        "210")), "decorators", Map.of("location", "Stockholm"), "classifiers", List.of(
-                                                "Rural"), "sourceIds", List.of(
-                                                        "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=2"),
-                                "metadata", Map.of("trustLevel", "RELIABLE")))));
-
-        when(dataService.getTopologyById(eq("GBFunction"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1")))
-                        .thenThrow(TiesException.unknownEntityType("GBFunction", Collections.emptyList()));
-
-        when(dataService.getTopologyById(eq("NRDU"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D1")))
-                        .thenThrow(TiesException.unknownEntityType("NRDU", Collections.emptyList()));
-
-        when(dataService.getTopologyByType(eq("GNBDUFunction"), endsWith("%2Fattributes(gNBDUId)"), any(), any()))
-                .thenReturn(gnbduMap);
-
-        when(dataService.getTopologyByType(eq("GNBDUFunction"), endsWith("%2Fattributes(gNBDUId)"), endsWith(
-                "%2Fattributes[@gNBDUId=1]"), any())).thenReturn(gnbduQueryMap);
-
-        when(dataService.getTopologyByType(eq("GNBBUFunction"), any(), any(), any())).thenThrow(TiesException
-                .unknownEntityType("GNBBUFunction", Collections.emptyList()));
-    }
-
-    private static void mockRanNRCellDUTopologyObject() {
-        when(dataService.getTopologyById(eq("NRCellDU"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D1")))
-                        .thenReturn(Map.of("o-ran-smo-teiv-ran:NRCellDU", List.of(Map.of("id",
-                                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=1",
-                                "attributes", Map.of("nCI", 1, "nRPCI", 35, "nRTAC", 50, "cellLocalId", 91), "decorators",
-                                Map.of("location", "Stockholm"), "classifiers", List.of("Rural"), "sourceIds", List.of(
-                                        "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=1"),
-                                "metadata", Map.of("trustLevel", "RELIABLE")))));
-
-        when(dataService.getTopologyById(eq("NRCellDU"), eq(
-                "urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D2")))
-                        .thenReturn(Map.of("o-ran-smo-teiv-ran:NRCellDU", List.of(Map.of("id",
-                                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=2",
-                                "attributes", Map.of("nCI", 5, "nRPCI", 35, "nRTAC", 50, "cellLocalId", 95), "decorators",
-                                Map.of("location", "Stockholm"), "classifiers", List.of("Rural"), "sourceIds", List.of(
-                                        "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=2"),
-                                "metadata", Map.of("trustLevel", "RELIABLE")))));
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/data/api/impl/DataServiceImplTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/data/api/impl/DataServiceImplTest.java
deleted file mode 100644 (file)
index 709c121..0000000
+++ /dev/null
@@ -1,654 +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 org.oran.smo.teiv.exposure.data.api.impl;
-
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.mapper.MapperUtility;
-import org.oran.smo.teiv.exposure.spi.mapper.PaginationMetaData;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-
-import org.oran.smo.teiv.api.model.OranTeivDomains;
-import org.oran.smo.teiv.api.model.OranTeivDomainsItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypes;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import static org.oran.smo.teiv.schema.SchemaRegistry.*;
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.oran.smo.teiv.utils.TiesConstants.ITEMS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class DataServiceImplTest {
-
-    private static DataPersistanceService mockedDataPersistanceService;
-    private static DataServiceImpl underTest;
-    private static final String REL_ID_PREFIX = "urn:base64:";
-    private static MockHttpServletRequest request = new MockHttpServletRequest();
-
-    @BeforeAll
-    static void setUp() throws SchemaLoaderException {
-
-        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
-        mockedDataPersistanceService = mock(DataPersistanceService.class);
-        SchemaLoader mockedSchemaLoader = new MockSchemaLoader();
-        mockedSchemaLoader.loadSchemaRegistry();
-        underTest = new DataServiceImpl(mockedDataPersistanceService, new MapperUtility());
-        mockGetTopologyById();
-        mockGetRelationshipById();
-        mockGetRelationshipByType();
-        mockGetAllRelationships();
-        mockGetTopologyByType();
-        MockGetTopologyByTargetFilter();
-    }
-
-    @Test
-    void testGetTopologyById() {
-        Assertions.assertEquals(generateResponse("GNBDUFunction", "5A548EA9D166341776CA0695837E55D8"), underTest
-                .getTopologyById("GNBDUFunction", "5A548EA9D166341776CA0695837E55D8"));
-        Assertions.assertEquals(generateResponse("NRCellDU", "98C3A4591A37718E1330F0294E23B62A"), underTest.getTopologyById(
-                "NRCellDU", "98C3A4591A37718E1330F0294E23B62A"));
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getTopologyById("NRCellDU", "NOT_EXISTING"));
-    }
-
-    @Test
-    void testGetTopologyByType() {
-        OranTeivEntitiesResponseMessage expectedResponse1 = new OranTeivEntitiesResponseMessage();
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath("/domains/RAN/entity-types/GNBDUFunction/entities")
-                .offset(0).limit(2).addQueryParameters("scopeFilter",
-                        "/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]")
-                .addQueryParameters("targetFilter", "/attributes/fdn;/attributes/id").build();
-        paginationDTO1.setTotalSize(2);
-
-        expectedResponse1.setItems(List.of(Map.of("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=111", "id",
-                "5BAE4346C241237AA8C74AE1259EF203"), Map.of("fdn",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=112",
-                        "id", "6B55F987ED838C0FA58DC11AB19CD1D3")));
-
-        OranTeivHref hrefFirst1 = new OranTeivHref();
-        hrefFirst1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=2&scopeFilter=/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]&targetFilter=/attributes/fdn;/attributes/id");
-        expectedResponse1.setFirst(hrefFirst1);
-        OranTeivHref hrefNext1 = new OranTeivHref();
-        hrefNext1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=2&scopeFilter=/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]&targetFilter=/attributes/fdn;/attributes/id");
-        expectedResponse1.setNext(hrefNext1);
-        OranTeivHref hrefPrev1 = new OranTeivHref();
-        hrefPrev1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=2&scopeFilter=/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]&targetFilter=/attributes/fdn;/attributes/id");
-        expectedResponse1.setPrev(hrefPrev1);
-        OranTeivHref hrefSelf1 = new OranTeivHref();
-        hrefSelf1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=2&scopeFilter=/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]&targetFilter=/attributes/fdn;/attributes/id");
-        expectedResponse1.setSelf(hrefSelf1);
-        OranTeivHref hrefLast1 = new OranTeivHref();
-        hrefLast1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=2&scopeFilter=/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]&targetFilter=/attributes/fdn;/attributes/id");
-        expectedResponse1.setLast(hrefLast1);
-        expectedResponse1.setTotalCount(2);
-
-        Assertions.assertEquals(expectedResponse1, underTest.getTopologyByType("GNBDUFunction",
-                "/attributes/fdn;/attributes/id",
-                "/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]", paginationDTO1));
-    }
-
-    @Test
-    void testGetEntitiesByDomain() {
-        OranTeivEntitiesResponseMessage expectedResult = new OranTeivEntitiesResponseMessage();
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/RAN/entities").offset(0).limit(1)
-                .addQueryParameters("targetFilter", "/GNBDUFunction/id").build();
-        paginationDTO.setTotalSize(1);
-
-        expectedResult.setItems(List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                "1050570EBB1315E1AE7A9FD5E1400A00")))));
-
-        OranTeivHref hrefFirst1 = new OranTeivHref();
-        hrefFirst1.setHref("/domains/RAN/entities?offset=0&limit=1&targetFilter=/GNBDUFunction/id");
-        expectedResult.setFirst(hrefFirst1);
-        OranTeivHref hrefNext1 = new OranTeivHref();
-        hrefNext1.setHref("/domains/RAN/entities?offset=0&limit=1&targetFilter=/GNBDUFunction/id");
-        expectedResult.setNext(hrefNext1);
-        OranTeivHref hrefPrev1 = new OranTeivHref();
-        hrefPrev1.setHref("/domains/RAN/entities?offset=0&limit=1&targetFilter=/GNBDUFunction/id");
-        expectedResult.setPrev(hrefPrev1);
-        OranTeivHref hrefSelf1 = new OranTeivHref();
-        hrefSelf1.setHref("/domains/RAN/entities?offset=0&limit=1&targetFilter=/GNBDUFunction/id");
-        expectedResult.setSelf(hrefSelf1);
-        OranTeivHref hrefLast1 = new OranTeivHref();
-        hrefLast1.setHref("/domains/RAN/entities?offset=0&limit=1&targetFilter=/GNBDUFunction/id");
-        expectedResult.setLast(hrefLast1);
-        expectedResult.setTotalCount(1);
-
-        Assertions.assertEquals(expectedResult, underTest.getEntitiesByDomain("RAN", "/GNBDUFunction/id", null,
-                paginationDTO));
-
-    }
-
-    @Test
-    void testGetRelationshipById() {
-        String id = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==";
-        String notExistingId = "NOT_EXISTING";
-        Map<String, Object> response = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-                generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A", id,
-                        Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(response, underTest.getRelationshipById("GNBDUFUNCTION_PROVIDES_NRCELLDU", id));
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getRelationshipById(
-                "GNBDUFUNCTION_PROVIDES_NRCELLDU", notExistingId));
-    }
-
-    @Test
-    void testGetRelationshipsByType() {
-        OranTeivRelationshipsResponseMessage response = new OranTeivRelationshipsResponseMessage();
-        OranTeivRelationshipsResponseMessage response2 = new OranTeivRelationshipsResponseMessage();
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath(
-                "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships").offset(0).limit(5).build();
-
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships").offset(0)
-                .limit(5).build();
-
-        response.setItems(List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "BCA882C87D49687E731F9B3872EFDBD3",
-                REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkxOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzE=",
-                Collections.EMPTY_LIST)))));
-
-        response2.setItems(List.of(Map.of("o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", List.of(
-                generateResponse("A05C67D47D117C2DC5BDF5E00AE70", "2256120E73ADD4026A43A971DCE5C151",
-                        REL_ID_PREFIX + "R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJE=",
-                        Collections.EMPTY_LIST)))));
-
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setFirst(hrefFirst);
-        OranTeivHref hrefFirst2 = new OranTeivHref();
-        hrefFirst2.setHref(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships?offset=0&limit=5");
-        response2.setFirst(hrefFirst2);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setNext(hrefNext);
-        OranTeivHref hrefNext2 = new OranTeivHref();
-        hrefNext2.setHref(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships?offset=0&limit=5");
-        response2.setNext(hrefNext2);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setPrev(hrefPrev);
-        OranTeivHref hrefPrev2 = new OranTeivHref();
-        hrefPrev2.setHref(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships?offset=0&limit=5");
-        response2.setPrev(hrefPrev2);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setSelf(hrefSelf);
-        OranTeivHref hrefSelf2 = new OranTeivHref();
-        hrefSelf2.setHref(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships?offset=0&limit=5");
-        response2.setSelf(hrefSelf2);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setLast(hrefLast);
-        OranTeivHref hrefLast2 = new OranTeivHref();
-        hrefLast2.setHref(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships?offset=0&limit=5");
-        response2.setLast(hrefLast2);
-
-        response.setTotalCount(1);
-        response2.setTotalCount(1);
-
-        Assertions.assertEquals(response, underTest.getRelationshipsByType("GNBDUFUNCTION_PROVIDES_NRCELLDU", null,
-                paginationDTO));
-
-        Assertions.assertEquals(response2, underTest.getRelationshipsByType("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", null,
-                paginationDTO2));
-    }
-
-    @Test
-    void testAllRelationshipsForObjectId() {
-        OranTeivRelationshipsResponseMessage response1 = new OranTeivRelationshipsResponseMessage();
-        OranTeivRelationshipsResponseMessage response2 = new OranTeivRelationshipsResponseMessage();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships").offset(0).limit(
-                        100).build();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships").offset(0).limit(
-                        100).build();
-
-        List<Object> mapList = new ArrayList<>();
-        List<Object> items1 = new ArrayList<>();
-        List<Object> items2 = new ArrayList<>();
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "BCA882C87D49687E731F9B3872EFDBD3",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6RVV0cmFuQ2VsbDpCQ0E4ODJDODdENDk2ODdFNzMxRjlCMzg3MkVGREJEMw==",
-                Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "3256120E73ADD4026A43A971DCE5C151",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MQ==",
-                Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVESYSTEM", List.of(
-                generateResponse("0525930249302B9649FC8F201EC4F7FC", "2256120E73ADD4026A43A971DCE5C151",
-                        REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MR==",
-                        Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY", List.of(generateResponse(
-                "3256120E73ADD4026A43A971DCE5C151", "3223120E73ADD4026A43A971DCE5C151",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MS==",
-                Collections.EMPTY_LIST))));
-
-        items1.add(mapList.get(0));
-        items1.add(mapList.get(1));
-        items1.add(mapList.get(2));
-
-        items2.add(mapList.get(1));
-        items2.add(mapList.get(3));
-
-        response1.setItems(items1);
-        response2.setItems(items2);
-
-        OranTeivHref hrefFirst1 = new OranTeivHref();
-        hrefFirst1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships?offset=0&limit=100");
-        response1.setFirst(hrefFirst1);
-        OranTeivHref hrefNext1 = new OranTeivHref();
-        hrefNext1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships?offset=0&limit=100");
-        response1.setNext(hrefNext1);
-        OranTeivHref hrefPrev1 = new OranTeivHref();
-        hrefPrev1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships?offset=0&limit=100");
-        response1.setPrev(hrefPrev1);
-        OranTeivHref hrefSelf1 = new OranTeivHref();
-        hrefSelf1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships?offset=0&limit=100");
-        response1.setSelf(hrefSelf1);
-        OranTeivHref hrefLast1 = new OranTeivHref();
-        hrefLast1.setHref(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships?offset=0&limit=100");
-        response1.setLast(hrefLast1);
-        response1.setTotalCount(3);
-
-        OranTeivHref hrefFirst2 = new OranTeivHref();
-        hrefFirst2.setHref(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships?offset=0&limit=100");
-        response2.setFirst(hrefFirst2);
-        OranTeivHref hrefNext2 = new OranTeivHref();
-        hrefNext2.setHref(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships?offset=0&limit=100");
-        response2.setNext(hrefNext2);
-        OranTeivHref hrefPrev2 = new OranTeivHref();
-        hrefPrev2.setHref(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships?offset=0&limit=100");
-        response2.setPrev(hrefPrev2);
-        OranTeivHref hrefSelf2 = new OranTeivHref();
-        hrefSelf2.setHref(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships?offset=0&limit=100");
-        response2.setSelf(hrefSelf2);
-        OranTeivHref hrefLast2 = new OranTeivHref();
-        hrefLast2.setHref(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships?offset=0&limit=100");
-        response2.setLast(hrefLast2);
-        response2.setTotalCount(1);
-
-        Assertions.assertEquals(response1, underTest.getAllRelationshipsForObjectId("GNBDUFunction",
-                "0525930249302B9649FC8F201EC4F7FC", paginationDTO1));
-        Assertions.assertEquals(response2, underTest.getAllRelationshipsForObjectId("NRSectorCarrier",
-                "3256120E73ADD4026A43A971DCE5C151", paginationDTO2));
-    }
-
-    @Test
-    void testGetTopologyRelationshipTypes() {
-        OranTeivRelationshipTypes expectedResponse = new OranTeivRelationshipTypes();
-        List<OranTeivRelationshipTypesItemsInner> items = new ArrayList<>();
-        OranTeivRelationshipTypesItemsInner item1 = new OranTeivRelationshipTypesItemsInner();
-        OranTeivRelationshipTypesItemsInner item2 = new OranTeivRelationshipTypesItemsInner();
-        OranTeivRelationshipTypesItemsInner item3 = new OranTeivRelationshipTypesItemsInner();
-        OranTeivRelationshipTypesItemsInner item4 = new OranTeivRelationshipTypesItemsInner();
-        OranTeivHref relationships1 = new OranTeivHref();
-        OranTeivHref relationships2 = new OranTeivHref();
-        OranTeivHref relationships3 = new OranTeivHref();
-        OranTeivHref relationships4 = new OranTeivHref();
-
-        item1.setName("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        relationships1.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships");
-        item1.setRelationships(relationships1);
-
-        item2.setName("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
-        relationships2.setHref("/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER/relationships");
-
-        item2.setRelationships(relationships2);
-
-        item3.setName("NRCELLDU_USES_NRSECTORCARRIER");
-        relationships3.setHref("/domains/RAN/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships");
-        item3.setRelationships(relationships3);
-
-        item4.setName("NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-        relationships4.setHref("/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships");
-        item4.setRelationships(relationships4);
-
-        items.add(item1);
-        items.add(item2);
-        items.add(item3);
-        items.add(item4);
-
-        expectedResponse.setItems(items);
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref("/domains/RAN/relationship-types?offset=0&limit=5");
-        expectedResponse.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref("/domains/RAN/relationship-types?offset=0&limit=5");
-        expectedResponse.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref("/domains/RAN/relationship-types?offset=0&limit=5");
-        expectedResponse.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref("/domains/RAN/relationship-types?offset=0&limit=5");
-        expectedResponse.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref("/domains/RAN/relationship-types?offset=0&limit=5");
-        expectedResponse.setLast(hrefLast);
-        expectedResponse.setTotalCount(4);
-
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().basePath("/domains/RAN/relationship-types").offset(0).limit(
-                5).build();
-
-        Assertions.assertEquals(expectedResponse, underTest.getTopologyRelationshipTypes("RAN", paginationDTO3));
-    }
-
-    @Test
-    void testGetTopologyEntityTypes() {
-        OranTeivEntityTypes expectedResponse = new OranTeivEntityTypes();
-        List<OranTeivEntityTypesItemsInner> items = new ArrayList<>();
-
-        OranTeivEntityTypesItemsInner item1 = new OranTeivEntityTypesItemsInner();
-        OranTeivEntityTypesItemsInner item2 = new OranTeivEntityTypesItemsInner();
-
-        item1.setName("AntennaCapability");
-        OranTeivHref entities1 = new OranTeivHref();
-        entities1.setHref("/domains/EQUIPMENT_TO_RAN/entity-types/AntennaCapability/entities");
-        item1.setEntities(entities1);
-
-        item2.setName("AntennaModule");
-        OranTeivHref entities2 = new OranTeivHref();
-        entities2.setHref("/domains/EQUIPMENT_TO_RAN/entity-types/AntennaModule/entities");
-        item2.setEntities(entities2);
-
-        items.add(item1);
-        items.add(item2);
-        expectedResponse.setItems(items);
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref("/domains/EQUIPMENT_TO_RAN/entity-types?offset=0&limit=2");
-        expectedResponse.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref("/domains/EQUIPMENT_TO_RAN/entity-types?offset=2&limit=2");
-        expectedResponse.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref("/domains/EQUIPMENT_TO_RAN/entity-types?offset=0&limit=2");
-        expectedResponse.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref("/domains/EQUIPMENT_TO_RAN/entity-types?offset=0&limit=2");
-        expectedResponse.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref("/domains/EQUIPMENT_TO_RAN/entity-types?offset=6&limit=2");
-        expectedResponse.setLast(hrefLast);
-        expectedResponse.setTotalCount(8);
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/EQUIPMENT_TO_RAN/entity-types").offset(0)
-                .limit(2).build();
-
-        Assertions.assertEquals(expectedResponse, underTest.getTopologyEntityTypes("EQUIPMENT_TO_RAN", paginationDTO));
-    }
-
-    @Test
-    void testGetDomainTypes() {
-        OranTeivDomains expectedResponse = new OranTeivDomains();
-        OranTeivDomainsItemsInner item1 = new OranTeivDomainsItemsInner();
-        OranTeivDomainsItemsInner item2 = new OranTeivDomainsItemsInner();
-
-        item1.setName("CLOUD");
-        OranTeivHref entityType1 = new OranTeivHref();
-        OranTeivHref relationshipType1 = new OranTeivHref();
-        entityType1.setHref("/domains/CLOUD/entity-types");
-        relationshipType1.setHref("/domains/CLOUD/relationship-types");
-        item1.setEntityTypes(entityType1);
-        item1.setRelationshipTypes(relationshipType1);
-
-        item2.setName("CLOUD_TO_RAN");
-        OranTeivHref entityType2 = new OranTeivHref();
-        OranTeivHref relationshipType2 = new OranTeivHref();
-        entityType2.setHref("/domains/CLOUD_TO_RAN/entity-types");
-        relationshipType2.setHref("/domains/CLOUD_TO_RAN/relationship-types");
-        item2.setEntityTypes(entityType2);
-        item2.setRelationshipTypes(relationshipType2);
-
-        List<OranTeivDomainsItemsInner> items = new ArrayList<>();
-        items.add(item1);
-        items.add(item2);
-        expectedResponse.setItems(items);
-
-        OranTeivHref hrefFirst = new OranTeivHref();
-        hrefFirst.setHref("/domains?offset=0&limit=2");
-        expectedResponse.setFirst(hrefFirst);
-        OranTeivHref hrefNext = new OranTeivHref();
-        hrefNext.setHref("/domains?offset=2&limit=2");
-        expectedResponse.setNext(hrefNext);
-        OranTeivHref hrefPrev = new OranTeivHref();
-        hrefPrev.setHref("/domains?offset=0&limit=2");
-        expectedResponse.setPrev(hrefPrev);
-        OranTeivHref hrefSelf = new OranTeivHref();
-        hrefSelf.setHref("/domains?offset=0&limit=2");
-        expectedResponse.setSelf(hrefSelf);
-        OranTeivHref hrefLast = new OranTeivHref();
-        hrefLast.setHref("/domains?offset=6&limit=2");
-        expectedResponse.setLast(hrefLast);
-        expectedResponse.setTotalCount(2);
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains").offset(0).limit(2).build();
-        paginationDTO.setTotalSize(8);
-
-        Assertions.assertEquals(expectedResponse, underTest.getDomainTypes(paginationDTO));
-    }
-
-    private static void mockGetTopologyById() {
-        EntityType entity1 = getEntityTypeByName("GNBDUFunction");
-        EntityType entity2 = getEntityTypeByName("NRCellDU");
-
-        when(mockedDataPersistanceService.getTopology(entity1, "5A548EA9D166341776CA0695837E55D8")).thenReturn(
-                generateResponse("GNBDUFunction", "5A548EA9D166341776CA0695837E55D8"));
-        when(mockedDataPersistanceService.getTopology(entity2, "98C3A4591A37718E1330F0294E23B62A")).thenReturn(
-                generateResponse("NRCellDU", "98C3A4591A37718E1330F0294E23B62A"));
-        when(mockedDataPersistanceService.getTopology(entity2, "NOT_EXISTING")).thenThrow(TiesException.class);
-    }
-
-    private static void mockGetTopologyByType() {
-        Map<String, Object> mockedResponse1 = new HashMap<>();
-        PaginationMetaData pmd1 = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath("/domains/RAN/entity-types/GNBDUFunction/entities")
-                .offset(0).limit(2).addQueryParameters("targetFilter", "/attributes/fdn;/attributes/id").addQueryParameters(
-                        "scopeFilter",
-                        "/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]").build();
-        paginationDTO1.setTotalSize(2);
-        mockedResponse1.putAll(pmd1.getObjectList(paginationDTO1));
-
-        mockedResponse1.put("items", List.of(Map.of("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=111", "id",
-                "5BAE4346C241237AA8C74AE1259EF203"), Map.of("fdn",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=112",
-                        "id", "6B55F987ED838C0FA58DC11AB19CD1D3")));
-        mockedResponse1.putAll(pmd1.getObjectList(paginationDTO1));
-
-        when(mockedDataPersistanceService.getTopologyByType("GNBDUFunction", "/attributes/fdn;/attributes/id",
-                "/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]", paginationDTO1))
-                        .thenReturn(mockedResponse1);
-    }
-
-    private static void MockGetTopologyByTargetFilter() {
-        Map<String, Object> mockedResponse = new HashMap<>();
-        Map<String, Object> query = new HashMap<>();
-
-        query.put("targetFilter", "/GNBDUFunction/id");
-
-        PaginationMetaData pmd1 = new PaginationMetaData();
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/RAN/entities").offset(0).limit(1)
-                .addQueryParameters("targetFilter", "/GNBDUFunction/id").build();
-
-        paginationDTO.setTotalSize(1);
-        mockedResponse.putAll(pmd1.getObjectList(paginationDTO));
-        mockedResponse.put("query", query);
-
-        mockedResponse.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                "1050570EBB1315E1AE7A9FD5E1400A00")))));
-
-        when(mockedDataPersistanceService.getEntitiesByDomain("RAN", "/GNBDUFunction/id", null, paginationDTO)).thenReturn(
-                mockedResponse);
-
-    }
-
-    private static void mockGetRelationshipById() {
-        String id = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==";
-        String wrongId = "NOT_EXISTING";
-        String relationshipName = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
-        Map<String, Object> response = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-                generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A", id,
-                        Collections.EMPTY_LIST)));
-
-        when(mockedDataPersistanceService.getRelationshipWithSpecifiedId(id, SchemaRegistry.getRelationTypeByName(
-                relationshipName))).thenReturn(response);
-        when(mockedDataPersistanceService.getRelationshipWithSpecifiedId(wrongId, SchemaRegistry.getRelationTypeByName(
-                relationshipName))).thenThrow(TiesException.class);
-    }
-
-    private static void mockGetRelationshipByType() {
-        Map<String, Object> mockedResponse = new HashMap<>();
-        Map<String, Object> items = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "BCA882C87D49687E731F9B3872EFDBD3",
-                REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkxOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzE=",
-                Collections.EMPTY_LIST)));
-        RelationType relationType = getRelationTypeByName("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-
-        PaginationMetaData pmd1 = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath(
-                "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships").offset(0).limit(5).build();
-        paginationDTO1.setTotalSize(1);
-        mockedResponse.putAll(pmd1.getObjectList(paginationDTO1));
-        mockedResponse.put(ITEMS, List.of(items));
-
-        when(mockedDataPersistanceService.getRelationshipsByType(relationType, null, PaginationDTO.builder().basePath(
-                "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships").offset(0).limit(5)
-                .build())).thenReturn(mockedResponse);
-
-        Map<String, Object> mockedResponse2 = new HashMap<>();
-        Map<String, Object> items2 = Map.of("o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", List.of(
-                generateResponse("A05C67D47D117C2DC5BDF5E00AE70", "2256120E73ADD4026A43A971DCE5C151",
-                        REL_ID_PREFIX + "R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJE=",
-                        Collections.EMPTY_LIST)));
-        RelationType relationType2 = getRelationTypeByName("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-
-        PaginationMetaData pmd2 = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships").offset(0)
-                .limit(5).build();
-        paginationDTO2.setTotalSize(1);
-        mockedResponse2.putAll(pmd2.getObjectList(paginationDTO2));
-        mockedResponse2.put(ITEMS, List.of(items2));
-
-        when(mockedDataPersistanceService.getRelationshipsByType(relationType2, null, PaginationDTO.builder().basePath(
-                "/domains/EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships").offset(0)
-                .limit(5).build())).thenReturn(mockedResponse2);
-    }
-
-    private static void mockGetAllRelationships() {
-        final EntityType gnbduFunction = getEntityTypeByName("GNBDUFunction");
-        final EntityType nrSectorCarrier = getEntityTypeByName("NRSectorCarrier");
-        Map<String, Object> mockedResponse1 = new HashMap<>();
-        Map<String, Object> mockedResponse2 = new HashMap<>();
-        List<Object> mapList = new ArrayList<>();
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "BCA882C87D49687E731F9B3872EFDBD3",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6RVV0cmFuQ2VsbDpCQ0E4ODJDODdENDk2ODdFNzMxRjlCMzg3MkVGREJEMw==",
-                Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", List.of(generateResponse(
-                "0525930249302B9649FC8F201EC4F7FC", "3256120E73ADD4026A43A971DCE5C151",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MQ==",
-                Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVESYSTEM", List.of(
-                generateResponse("0525930249302B9649FC8F201EC4F7FC", "2256120E73ADD4026A43A971DCE5C151",
-                        REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MR==",
-                        Collections.EMPTY_LIST))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY", List.of(generateResponse(
-                "3256120E73ADD4026A43A971DCE5C151", "3223120E73ADD4026A43A971DCE5C151",
-                REL_ID_PREFIX + "RU5vZGVCRnVuY3Rpb246MDUyNTkzMDI0OTMwMkI5NjQ5RkM4RjIwMUVDNEY3RkM6UFJPVklERVM6TFRFU2VjdG9yQ2FycmllcjozMjU2MTIwRTczQURENDAyNkE0M0E5NzFEQ0U1QzE1MS==",
-                Collections.EMPTY_LIST))));
-
-        PaginationMetaData pmd1 = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath(
-                "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships").offset(0).limit(
-                        100).build();
-        paginationDTO1.setTotalSize(3);
-        mockedResponse1.putAll(pmd1.getObjectList(paginationDTO1));
-        mockedResponse1.put(ITEMS, List.of(mapList.get(0), mapList.get(1), mapList.get(2)));
-
-        PaginationMetaData pmd2 = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath(
-                "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships").offset(0).limit(
-                        100).build();
-        paginationDTO2.setTotalSize(1);
-        mockedResponse2.putAll(pmd2.getObjectList(paginationDTO2));
-        mockedResponse2.put(ITEMS, List.of(mapList.get(1), mapList.get(3)));
-
-        when(mockedDataPersistanceService.getAllRelationships(gnbduFunction, getRelationTypesByEntityName("GNBDUFunction"),
-                "0525930249302B9649FC8F201EC4F7FC", PaginationDTO.builder().basePath(
-                        "/domains/RAN/entity-types/GNBDUFunction/0525930249302B9649FC8F201EC4F7FC/relationships").offset(0)
-                        .limit(100).build())).thenReturn(mockedResponse1);
-        when(mockedDataPersistanceService.getAllRelationships(nrSectorCarrier, getRelationTypesByEntityName(
-                "NRSectorCarrier"), "3256120E73ADD4026A43A971DCE5C151", PaginationDTO.builder().basePath(
-                        "/domains/RAN/entity-types/NRSectorCarrier/3256120E73ADD4026A43A971DCE5C151/relationships").offset(
-                                0).limit(100).build())).thenReturn(mockedResponse2);
-    }
-}
index 7c8904f..2f809d7 100644 (file)
  */
 package org.oran.smo.teiv.exposure.data.api.impl;
 
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.data.rest.controller.DataRestController;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.exposure.utils.RequestValidator;
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.function.Supplier;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.oran.smo.teiv.utils.TiesTestConstants.APPLICATION_JSON;
+
+import java.util.Collections;
+import java.util.function.Supplier;
+
+import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.CustomMetrics;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.audit.LoggerHandler;
+import org.oran.smo.teiv.exposure.data.api.DataService;
+import org.oran.smo.teiv.exposure.data.rest.controller.DataController;
+import org.oran.smo.teiv.exposure.classifiers.api.ClassifiersService;
+import org.oran.smo.teiv.exposure.classifiers.rest.controller.ClassifiersRestController;
+import org.oran.smo.teiv.exposure.decorators.api.DecoratorsService;
+import org.oran.smo.teiv.exposure.decorators.rest.controller.DecoratorsRestController;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.oran.smo.teiv.exposure.utils.RequestValidator;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 
-public class ExposureMetricsTest {
+class ExposureMetricsTest {
 
-    private DataServiceImpl mockedDataService;
+    private DataService mockedDataService;
+    private ClassifiersService mockedClassifiersService;
+    private DecoratorsService mockedDecoratorsService;
     private RequestValidator mockedRequestValidator;
     private CustomMetrics underTest;
-    private DataRestController dataRestController;
-
-    private final static String ACCEPT_TYPE = "application/json";
-    private final static String DOMAIN_NAME = "RAN_LOGICAL";
-    private final static String ENTITY_ID = "5A548EA9D166341776CA0695837E55D8";
-    private final static String ENTITY_NAME = "GNBDUFunction";
-    private final static String RELATION_TYPE = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
-    private final static PaginationDTO paginationDto = PaginationDTO.builder().basePath("").offset(0).limit(1).build();
+    private DataController dataController;
+    private ClassifiersRestController classifiersRestController;
+    private DecoratorsRestController decoratorsRestController;
+    private static final String DOMAIN_NAME = "RAN";
+    private static final String ENTITY_ID = "5A548EA9D166341776CA0695837E55D8";
+    private static final String ENTITY_NAME = "GNBDUFunction";
+    private static final String RELATION_TYPE = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
 
     @BeforeEach
     void setUp() throws SchemaLoaderException {
         SchemaLoader mockedSchemaLoader = new MockSchemaLoader();
         mockedSchemaLoader.loadSchemaRegistry();
         mockedRequestValidator = mock(RequestValidator.class);
-        mockedDataService = mock(DataServiceImpl.class);
+        mockedDataService = mock(DataService.class);
+        mockedClassifiersService = mock(ClassifiersService.class);
+        mockedDecoratorsService = mock(DecoratorsService.class);
         underTest = new CustomMetrics(new SimpleMeterRegistry());
-        dataRestController = new DataRestController(mockedRequestValidator, mockedDataService, underTest);
+        dataController = new DataController(mockedRequestValidator, mockedDataService, underTest);
+        classifiersRestController = new ClassifiersRestController(mockedClassifiersService, underTest, mock(
+                LoggerHandler.class), mock(HttpServletRequest.class));
+        decoratorsRestController = new DecoratorsRestController(mockedDecoratorsService, underTest, mock(
+                LoggerHandler.class), mock(HttpServletRequest.class));
     }
 
     @Test
     void testGetRelationshipsByEntityIdFailMetrics() {
-        when(mockedDataService.getAllRelationshipsForObjectId(eq(ENTITY_NAME), eq(ENTITY_ID), any(PaginationDTO.class)))
-                .thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getAllRelationshipsForEntityId(ACCEPT_TYPE, DOMAIN_NAME, ENTITY_NAME,
+        when(mockedDataService.getAllRelationshipsForObjectId(eq(DOMAIN_NAME), eq(ENTITY_NAME), eq(ENTITY_ID), anyString(),
+                anyString(), any(RequestDetails.class))).thenThrow(TiesException.class);
+        assertMetrics(() -> dataController.getAllRelationshipsForEntityId(APPLICATION_JSON, DOMAIN_NAME, ENTITY_NAME,
                 ENTITY_ID, "", "", 0, 1), underTest.getNumUnsuccessfullyExposedRelationshipsByEntityId()::count);
     }
 
     @Test
     void testGetEntityByIdFailMetrics() {
-        when(mockedDataService.getTopologyById(ENTITY_NAME, ENTITY_ID)).thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getTopologyById(ACCEPT_TYPE, DOMAIN_NAME, ENTITY_NAME, ENTITY_ID), underTest
+        when(mockedDataService.getEntityById(ENTITY_NAME, ENTITY_ID)).thenThrow(TiesException.class);
+        assertMetrics(() -> dataController.getTopologyById(APPLICATION_JSON, DOMAIN_NAME, ENTITY_NAME, ENTITY_ID), underTest
                 .getNumUnsuccessfullyExposedEntityById()::count);
     }
 
     @Test
     void testGetEntitiesByTypeFailMetrics() {
-        when(mockedDataService.getTopologyByType(eq(ENTITY_NAME), anyString(), anyString(), any(PaginationDTO.class)))
-                .thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getTopologyByEntityTypeName(ACCEPT_TYPE, DOMAIN_NAME, ENTITY_NAME, "", "", 0,
-                1), underTest.getNumUnsuccessfullyExposedEntitiesByType()::count);
+        when(mockedDataService.getTopologyByType(anyString(), eq(ENTITY_NAME), anyString(), anyString(), any(
+                RequestDetails.class))).thenThrow(TiesException.class);
+        assertMetrics(() -> dataController.getTopologyByEntityTypeName(APPLICATION_JSON, DOMAIN_NAME, ENTITY_NAME, "", "",
+                0, 1), underTest.getNumUnsuccessfullyExposedEntitiesByType()::count);
     }
 
     @Test
     void testGetEntitiesByDomainFailMetrics() {
-        when(mockedDataService.getEntitiesByDomain(eq(DOMAIN_NAME), anyString(), anyString(), any(PaginationDTO.class)))
+        when(mockedDataService.getEntitiesByDomain(eq(DOMAIN_NAME), anyString(), anyString(), any(RequestDetails.class)))
                 .thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getEntitiesByDomain(ACCEPT_TYPE, DOMAIN_NAME, "", "", 0, 1), underTest
+        assertMetrics(() -> dataController.getEntitiesByDomain(APPLICATION_JSON, DOMAIN_NAME, "", "", 0, 1), underTest
                 .getNumUnsuccessfullyExposedEntitiesByDomain()::count);
     }
 
     @Test
     void testGetRelationshipByIdFailMetrics() {
         when(mockedDataService.getRelationshipById(RELATION_TYPE, ENTITY_ID)).thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getRelationshipById(ACCEPT_TYPE, DOMAIN_NAME, RELATION_TYPE, ENTITY_ID),
+        assertMetrics(() -> dataController.getRelationshipById(APPLICATION_JSON, DOMAIN_NAME, RELATION_TYPE, ENTITY_ID),
                 underTest.getNumUnsuccessfullyExposedRelationshipById()::count);
     }
 
     @Test
     void testGetRelationshipsByTypeFailMetrics() {
-        when(mockedDataService.getRelationshipsByType(eq(RELATION_TYPE), anyString(), any(PaginationDTO.class))).thenThrow(
-                TiesException.class);
-        assertMetrics(() -> dataRestController.getRelationshipsByType(ACCEPT_TYPE, DOMAIN_NAME, RELATION_TYPE, "", "", 0,
+        when(mockedDataService.getRelationshipsByType(anyString(), eq(RELATION_TYPE), anyString(), anyString(), any(
+                RequestDetails.class))).thenThrow(TiesException.class);
+        assertMetrics(() -> dataController.getRelationshipsByType(APPLICATION_JSON, DOMAIN_NAME, RELATION_TYPE, "", "", 0,
                 1), underTest.getNumUnsuccessfullyExposedRelationshipsByType()::count);
     }
 
     @Test
     void testGetRelationshipTypesFailMetrics() {
-        when(mockedDataService.getTopologyRelationshipTypes(eq(DOMAIN_NAME), any(PaginationDTO.class))).thenThrow(
+        when(mockedDataService.getTopologyRelationshipTypes(eq(DOMAIN_NAME), any(RequestDetails.class))).thenThrow(
                 TiesException.class);
-        assertMetrics(() -> dataRestController.getTopologyRelationshipTypes(ACCEPT_TYPE, DOMAIN_NAME, 0, 1), underTest
+        assertMetrics(() -> dataController.getTopologyRelationshipTypes(APPLICATION_JSON, DOMAIN_NAME, 0, 1), underTest
                 .getNumUnsuccessfullyExposedRelationshipTypes()::count);
     }
 
     @Test
     void testGetDomainTypesFailMetrics() {
-        when(mockedDataService.getDomainTypes(any(PaginationDTO.class))).thenThrow(TiesException.class);
-        assertMetrics(() -> dataRestController.getAllDomains(ACCEPT_TYPE, 0, 1), underTest
+        when(mockedDataService.getDomainTypes(any(RequestDetails.class))).thenThrow(TiesException.class);
+        assertMetrics(() -> dataController.getAllDomains(APPLICATION_JSON, 0, 1), underTest
                 .getNumUnsuccessfullyExposedDomainTypes()::count);
     }
 
     @Test
     void testGetEntityTypesFailMetrics() {
-        when(mockedDataService.getTopologyEntityTypes(eq(DOMAIN_NAME), any(PaginationDTO.class))).thenThrow(
+        when(mockedDataService.getTopologyEntityTypes(eq(DOMAIN_NAME), any(RequestDetails.class))).thenThrow(
                 TiesException.class);
-        assertMetrics(() -> dataRestController.getTopologyEntityTypes(ACCEPT_TYPE, DOMAIN_NAME, 0, 1), underTest
+        assertMetrics(() -> dataController.getTopologyEntityTypes(APPLICATION_JSON, DOMAIN_NAME, 0, 1), underTest
                 .getNumUnsuccessfullyExposedEntityTypes()::count);
     }
 
-    private <T> void assertMetrics(Supplier<T> dataServiceMethod, Supplier<T> failerSupplier) {
-        Assertions.assertThrowsExactly(TiesException.class, dataServiceMethod::get);
+    @Test
+    void testUpdateClassifiersFailMetrics() {
+        doThrow(TiesException.invalidClassifiersException(Collections.emptyList())).when(mockedClassifiersService).update(
+                any(OranTeivClassifier.class));
+        assertMetrics(() -> classifiersRestController.updateClassifier(APPLICATION_JSON, APPLICATION_JSON,
+                OranTeivClassifier.builder().operation(OranTeivClassifier.OperationEnum.MERGE).build()), underTest
+                        .getNumUnsuccessfullyUpdatedClassifiers()::count);
+    }
+
+    @Test
+    void testUpdateDecoratorsFailMetrics() {
+        doThrow(TiesException.invalidClassifiersException(Collections.emptyList())).when(mockedDecoratorsService).update(
+                any(OranTeivDecorator.class));
+        assertMetrics(() -> decoratorsRestController.updateDecorator(APPLICATION_JSON, APPLICATION_JSON, OranTeivDecorator
+                .builder().operation(OranTeivDecorator.OperationEnum.MERGE).build()), underTest
+                        .getNumUnsuccessfullyUpdatedDecorators()::count);
+    }
+
+    private <T> void assertMetrics(Supplier<T> controllerMethod, Supplier<T> failerSupplier) {
+        Assertions.assertThrowsExactly(TiesException.class, controllerMethod::get);
         Assertions.assertEquals(1.0, failerSupplier.get());
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/data/rest/controller/DataRestControllerTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/data/rest/controller/DataRestControllerTest.java
deleted file mode 100644 (file)
index d72e1f6..0000000
+++ /dev/null
@@ -1,573 +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 org.oran.smo.teiv.exposure.data.rest.controller;
-
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.api.model.OranTeivDomains;
-import org.oran.smo.teiv.api.model.OranTeivHref;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivEntityTypes;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypesItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipsResponseMessage;
-import org.oran.smo.teiv.api.model.OranTeivRelationshipTypes;
-import org.oran.smo.teiv.api.model.OranTeivDomainsItemsInner;
-import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.data.api.impl.DataServiceImpl;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.exposure.utils.RequestValidator;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-import org.springframework.http.ResponseEntity;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-class DataRestControllerTest {
-    private static DataServiceImpl dataService;
-    private static DataRestController underTest;
-    private static RequestValidator requestValidator;
-    private static CustomMetrics customMetrics;
-    private final String ACCEPT_TYPE = "application/json";
-    private static final String EIID_PREFIX = "urn:base64:";
-
-    @BeforeAll
-    static void setUp() {
-        dataService = mock(DataServiceImpl.class);
-        requestValidator = mock(RequestValidator.class);
-        customMetrics = mock(CustomMetrics.class);
-        underTest = new DataRestController(requestValidator, dataService, customMetrics);
-        mockTopologyById();
-        mockGetTopologyRelationshipTypes();
-        mockTopologyEntityTypes();
-        mockGetRelationshipById();
-        mockGetRelationshipByType();
-        mockGetAllRelationshipsForEntityId();
-        mockGetDomainTypes();
-        mockGetTopologyEntityTypes();
-        mockTopologyByType();
-    }
-
-    @BeforeEach
-    void clearInvocations() {
-        Mockito.clearInvocations(requestValidator);
-    }
-
-    @Test
-    void testGetTopologyById() {
-        assertEquals(ResponseEntity.ok(generateResponse("GNBDUFunction", "5A548EA9D166341776CA0695837E55D8")), underTest
-                .getTopologyById(ACCEPT_TYPE, "RAN_LOGICAL", "GNBDUFunction", "5A548EA9D166341776CA0695837E55D8"));
-        assertEquals(ResponseEntity.ok(generateResponse("NRCellDU", "98C3A4591A37718E1330F0294E23B62A")), underTest
-                .getTopologyById(ACCEPT_TYPE, "RAN_LOGICAL", "NRCellDU", "98C3A4591A37718E1330F0294E23B62A"));
-        assertThrows(TiesException.class, () -> underTest.getTopologyById(ACCEPT_TYPE, "RAN_LOGICAL", "NRCellDU",
-                "NOT_EXISTING"));
-
-        verify(requestValidator, Mockito.times(3)).validateDomain("RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(1)).validateEntityType("GNBDUFunction");
-        verify(requestValidator, Mockito.times(2)).validateEntityType("NRCellDU");
-        verify(requestValidator, Mockito.times(1)).validateEntityTypeInDomain("GNBDUFunction", "RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(2)).validateEntityTypeInDomain("NRCellDU", "RAN_LOGICAL");
-    }
-
-    @Test
-    void testGetTopologyEntityTypes() {
-        OranTeivEntityTypesItemsInner element1 = new OranTeivEntityTypesItemsInner();
-        element1.setName("Site");
-        OranTeivEntityTypesItemsInner element2 = new OranTeivEntityTypesItemsInner();
-        element1.setName("AntennaModule");
-        OranTeivEntityTypesItemsInner element3 = new OranTeivEntityTypesItemsInner();
-        element1.setName("PhysicalNetworkAppliance");
-
-        List<OranTeivEntityTypesItemsInner> entityTypes = new ArrayList<>();
-        entityTypes.add(element1);
-        entityTypes.add(element2);
-        entityTypes.add(element3);
-        OranTeivEntityTypes response = new OranTeivEntityTypes();
-        response.setItems(entityTypes);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains/RAN_EQUIPMENT/entity-types?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyEntityTypes(ACCEPT_TYPE, "RAN_EQUIPMENT",
-                0, 5));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyEntityTypes("*/*", "RAN_EQUIPMENT", 0,
-                5));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyEntityTypes(
-                "application/json, application/problem+json", "RAN_EQUIPMENT", 0, 5));
-
-        verify(requestValidator, Mockito.times(3)).validateDomain("RAN_EQUIPMENT");
-    }
-
-    @Test
-    void testGetTopologyRelationshipTypes() {
-        OranTeivRelationshipTypesItemsInner element1 = new OranTeivRelationshipTypesItemsInner();
-        element1.setName("NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-        OranTeivRelationshipTypesItemsInner element2 = new OranTeivRelationshipTypesItemsInner();
-        element2.setName("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        OranTeivRelationshipTypesItemsInner element3 = new OranTeivRelationshipTypesItemsInner();
-        element3.setName("GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        OranTeivRelationshipTypesItemsInner element4 = new OranTeivRelationshipTypesItemsInner();
-        element4.setName("EUTRANCELL_USES_LTESECTORCARRIER");
-        OranTeivRelationshipTypesItemsInner element5 = new OranTeivRelationshipTypesItemsInner();
-        element5.setName("MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
-
-        List<OranTeivRelationshipTypesItemsInner> relationshipTypes = new ArrayList<>();
-        relationshipTypes.add(element1);
-        relationshipTypes.add(element2);
-        relationshipTypes.add(element3);
-        relationshipTypes.add(element4);
-        relationshipTypes.add(element5);
-
-        OranTeivRelationshipTypes response = new OranTeivRelationshipTypes();
-        response.setItems(relationshipTypes);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains/RAN_LOGICAL/relationship-types?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyRelationshipTypes(ACCEPT_TYPE,
-                "RAN_LOGICAL", 0, 5));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyRelationshipTypes("*/*", "RAN_LOGICAL", 0,
-                5));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyRelationshipTypes(
-                "application/json, application/problem+json", "RAN_LOGICAL", 0, 5));
-    }
-
-    @Test
-    void testGetDomainTypes() {
-        OranTeivDomainsItemsInner element1 = new OranTeivDomainsItemsInner();
-        element1.setName("RAN_LOGICAL_TO_EQUIPMENT");
-        OranTeivDomainsItemsInner element2 = new OranTeivDomainsItemsInner();
-        element2.setName("RAN_LOGICAL");
-        OranTeivDomainsItemsInner element3 = new OranTeivDomainsItemsInner();
-        element3.setName("RAN_EQUIPMENT");
-
-        List<OranTeivDomainsItemsInner> domains = new ArrayList<>();
-        domains.add(element1);
-        domains.add(element2);
-        domains.add(element3);
-
-        OranTeivDomains response = new OranTeivDomains();
-        response.setItems(domains);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getAllDomains(ACCEPT_TYPE, 0, 3));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getAllDomains("*/*", 0, 3));
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getAllDomains(
-                "application/json, application/problem+json", 0, 3));
-
-    }
-
-    @Test
-    void testGetRelationshipById() {
-        Map<String, Object> response = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-                generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A",
-                        EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==",
-                        Collections.emptyList())));
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getRelationshipById(ACCEPT_TYPE, "RAN_LOGICAL",
-                "GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ=="));
-
-        verify(requestValidator, Mockito.times(1)).validateDomain("RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(1)).validateRelationshipType("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        verify(requestValidator, Mockito.times(1)).validateRelationshipTypeInDomain("GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                "RAN_LOGICAL");
-    }
-
-    @Test
-    void testGetAllRelationshipsForEntityId() {
-        List<Object> mapList = new ArrayList<>();
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "D3215E08570BE58339C7463626B50E37", "B480427E8A0C0B8D994E437784BB382F",
-                EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.emptyList()))));
-        mapList.add(Map.of("o-ran-smo-teiv-equipment-to-ran:SECTOR_GROUPS_NRCELLDU", List.of(generateResponse(
-                "F5128C172A70C4FCD4739650B06DE9E2", "B480427E8A0C0B8D994E437784BB382F",
-                EIID_PREFIX + "U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.emptyList()))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER", List.of(generateResponse(
-                "B480427E8A0C0B8D994E437784BB382F", "E49D942C16E0364E1E0788138916D70C",
-                EIID_PREFIX + "TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM=",
-                Collections.emptyList()))));
-
-        OranTeivRelationshipsResponseMessage response = new OranTeivRelationshipsResponseMessage();
-
-        response.setItems(mapList);
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/entity-types/NRCellDU/entities/B480427E8A0C0B8D994E437784BB382F/relationships?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getAllRelationshipsForEntityId(ACCEPT_TYPE,
-                "RAN_LOGICAL", "NRCellDU", "B480427E8A0C0B8D994E437784BB382F", "", "", 0, 5));
-
-        verify(requestValidator, Mockito.times(1)).validateDomain("RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(1)).validateEntityType("NRCellDU");
-        verify(requestValidator, Mockito.times(1)).validateEntityTypeInDomain("NRCellDU", "RAN_LOGICAL");
-    }
-
-    @Test
-    void testGetRelationshipsByType() {
-        underTest.getRelationshipsByType(ACCEPT_TYPE, "RAN_LOGICAL", "GNBDUFUNCTION_PROVIDES_NRCELLDU", null, null, 0, 5);
-
-        verify(requestValidator, Mockito.times(1)).validateDomain("RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(1)).validateRelationshipType("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        verify(requestValidator, Mockito.times(1)).validateRelationshipTypeInDomain("GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                "RAN_LOGICAL");
-
-        OranTeivRelationshipsResponseMessage response = new OranTeivRelationshipsResponseMessage();
-
-        response.setItems(List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "91", "1", EIID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkxOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzE=",
-                Collections.emptyList()), generateResponse("92", "2",
-                        EIID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkyOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzI=",
-                        Collections.emptyList())))));
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getRelationshipsByType(ACCEPT_TYPE, "RAN_LOGICAL",
-                "GNBDUFUNCTION_PROVIDES_NRCELLDU", null, null, 0, 5));
-    }
-
-    @Test
-    void testGetTopologyByTargetFilter() {
-        underTest.getEntitiesByDomain(ACCEPT_TYPE, "RAN_LOGICAL", null, null, 0, 2);
-
-        verify(requestValidator, Mockito.times(1)).validateDomain("RAN_LOGICAL");
-    }
-
-    @Test
-    void testGetTopologyByType() {
-
-        OranTeivEntitiesResponseMessage response = new OranTeivEntitiesResponseMessage();
-        Map<String, Object> query = new HashMap<>();
-
-        query.put("scopeFilter", "/attributes[contains (@fnd, \"/SubNetwork=Ireland/\")]");
-
-        response.setItems(List.of(Map.of("GNBDUFunction", List.of(Map.of("id", "5FE67725576EDA7937752E7965164C2E"), Map.of(
-                "id", "9BCD297B8258F67908477D895636ED65"), Map.of("id", "8E249BCFAEC86C03D9ADD27FA9748254")))));
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/entity-types/GNBDUFunction/entities?scopeFilter=/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]&offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        Assertions.assertEquals(ResponseEntity.ok(response), underTest.getTopologyByEntityTypeName(ACCEPT_TYPE,
-                "RAN_LOGICAL", "GNBDUFunction", "", "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]", 0, 3));
-
-        verify(requestValidator, Mockito.times(1)).validateDomain("RAN_LOGICAL");
-        verify(requestValidator, Mockito.times(1)).validateEntityType("GNBDUFunction");
-        verify(requestValidator, Mockito.times(1)).validateEntityTypeInDomain("GNBDUFunction", "RAN_LOGICAL");
-
-        assertThrows(TiesException.class, () -> underTest.getTopologyByEntityTypeName(ACCEPT_TYPE, "RAN_LOGICAL",
-                "CloudSite", "", "/attributes[contains (@fdn, \"/SubNetwork Ireland/\")]", 0, 3));
-        assertThrows(TiesException.class, () -> underTest.getTopologyByEntityTypeName(ACCEPT_TYPE, "RAN_LOGICAL",
-                "GNBDUFunction2", "", "/attributes[contains (@fdn, \"/SubNetwork Ireland/\")]", 0, 3));
-        assertThrows(TiesPathException.class, () -> underTest.getTopologyByEntityTypeName(ACCEPT_TYPE, "RAN_LOGICAL",
-                "GNBDUFunction", "", "/attributes[contains ( fdn, \"/SubNetwork Ireland/\")]", 0, 3));
-
-    }
-
-    private static void mockTopologyById() {
-        when(dataService.getTopologyById("GNBDUFunction", "5A548EA9D166341776CA0695837E55D8")).thenReturn(generateResponse(
-                "GNBDUFunction", "5A548EA9D166341776CA0695837E55D8"));
-        when(dataService.getTopologyById("NRCellDU", "98C3A4591A37718E1330F0294E23B62A")).thenReturn(generateResponse(
-                "NRCellDU", "98C3A4591A37718E1330F0294E23B62A"));
-        when(dataService.getTopologyById("NRCellDU", "NOT_EXISTING")).thenThrow(TiesException.class);
-    }
-
-    private static void mockTopologyEntityTypes() {
-        OranTeivEntityTypesItemsInner element1 = new OranTeivEntityTypesItemsInner();
-        element1.setName("Site");
-        OranTeivEntityTypesItemsInner element2 = new OranTeivEntityTypesItemsInner();
-        element1.setName("AntennaModule");
-        OranTeivEntityTypesItemsInner element3 = new OranTeivEntityTypesItemsInner();
-        element1.setName("PhysicalNetworkAppliance");
-
-        List<OranTeivEntityTypesItemsInner> entityTypes = new ArrayList<>();
-        entityTypes.add(element1);
-        entityTypes.add(element2);
-        entityTypes.add(element3);
-        OranTeivEntityTypes response = new OranTeivEntityTypes();
-        response.setItems(entityTypes);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains/RAN_EQUIPMENT/entity-types?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        when(dataService.getTopologyEntityTypes("RAN_EQUIPMENT", PaginationDTO.builder().offset(0).limit(5).build()))
-                .thenReturn(response);
-    }
-
-    private static void mockGetRelationshipById() {
-        Map<String, Object> response = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-                generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A",
-                        EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==",
-                        Collections.emptyList())));
-
-        when(dataService.getRelationshipById("GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ=="))
-                        .thenReturn(response);
-    }
-
-    private static void mockGetRelationshipByType() {
-        PaginationDTO paginationDTO = PaginationDTO.builder().offset(0).limit(5).addPathParameters("relationshipType",
-                "GNBDUFUNCTION_PROVIDES_NRCELLDU").addPathParameters("domain", "RAN_LOGICAL").addQueryParameters(
-                        "scopeFilter", null).basePath(
-                                "/domains/RAN_LOGICAL/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships")
-                .build();
-
-        OranTeivRelationshipsResponseMessage response = new OranTeivRelationshipsResponseMessage();
-        response.setItems(List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "91", "1", EIID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkxOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzE=",
-                Collections.emptyList()), generateResponse("92", "2",
-                        EIID_PREFIX + "R05CRFVGdW5jdGlvbjpHTkJEVUZ1bmN0aW9uLzkyOlBST1ZJREVTOk5SQ2VsbERVOk5SQ2VsbERVLzI=",
-                        Collections.emptyList())))));
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        when(dataService.getRelationshipsByType("GNBDUFUNCTION_PROVIDES_NRCELLDU", null, paginationDTO)).thenReturn(
-                response);
-    }
-
-    private static void mockGetAllRelationshipsForEntityId() {
-        OranTeivRelationshipsResponseMessage response = new OranTeivRelationshipsResponseMessage();
-
-        List<Object> mapList = new ArrayList<>();
-        mapList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "D3215E08570BE58339C7463626B50E37", "B480427E8A0C0B8D994E437784BB382F",
-                EIID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.emptyList()))));
-        mapList.add(Map.of("o-ran-smo-teiv-equipment-to-ran:SECTOR_GROUPS_NRCELLDU", List.of(generateResponse(
-                "F5128C172A70C4FCD4739650B06DE9E2", "B480427E8A0C0B8D994E437784BB382F",
-                EIID_PREFIX + "U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.emptyList()))));
-        mapList.add(Map.of("o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER", List.of(generateResponse(
-                "B480427E8A0C0B8D994E437784BB382F", "E49D942C16E0364E1E0788138916D70C",
-                EIID_PREFIX + "TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM=",
-                Collections.emptyList()))));
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().addPathParameters("domain", "RAN_LOGICAL").addPathParameters(
-                "entityType", "NRCellDU").addPathParameters("id", "B480427E8A0C0B8D994E437784BB382F").basePath(String
-                        .format("/domains/%s/entity-types/%s/entities/%s/relationships", "RAN_LOGICAL", "NRCellDU",
-                                "B480427E8A0C0B8D994E437784BB382F")).offset(0).limit(5).build();
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/entity-types/NRCellDU/entities/B480427E8A0C0B8D994E437784BB382F/relationships?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        response.setItems(mapList);
-        when(dataService.getAllRelationshipsForObjectId("NRCellDU", "B480427E8A0C0B8D994E437784BB382F", paginationDTO1))
-                .thenReturn(response);
-    }
-
-    private static void mockGetDomainTypes() {
-        OranTeivDomainsItemsInner element1 = new OranTeivDomainsItemsInner();
-        element1.setName("RAN_LOGICAL_TO_EQUIPMENT");
-        OranTeivDomainsItemsInner element2 = new OranTeivDomainsItemsInner();
-        element2.setName("RAN_LOGICAL");
-        OranTeivDomainsItemsInner element3 = new OranTeivDomainsItemsInner();
-        element3.setName("RAN_EQUIPMENT");
-
-        List<OranTeivDomainsItemsInner> domains = new ArrayList<>();
-        domains.add(element1);
-        domains.add(element2);
-        domains.add(element3);
-
-        OranTeivDomains response = new OranTeivDomains();
-        response.setItems(domains);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        when(dataService.getDomainTypes(PaginationDTO.builder().offset(0).basePath("/domains").limit(3).build()))
-                .thenReturn(response);
-    }
-
-    private static void mockGetTopologyEntityTypes() {
-        OranTeivEntityTypesItemsInner element1 = new OranTeivEntityTypesItemsInner();
-        element1.setName("Site");
-        OranTeivEntityTypesItemsInner element2 = new OranTeivEntityTypesItemsInner();
-        element1.setName("AntennaModule");
-        OranTeivEntityTypesItemsInner element3 = new OranTeivEntityTypesItemsInner();
-        element1.setName("PhysicalNetworkAppliance");
-
-        List<OranTeivEntityTypesItemsInner> entityTypes = new ArrayList<>();
-        entityTypes.add(element1);
-        entityTypes.add(element2);
-        entityTypes.add(element3);
-        OranTeivEntityTypes response = new OranTeivEntityTypes();
-        response.setItems(entityTypes);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains/RAN_EQUIPMENT/entity-types?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath("/domains/RAN_EQUIPMENT/entity-types")
-                .addPathParameters("domain", "RAN_EQUIPMENT").offset(0).limit(5).build();
-
-        when(dataService.getTopologyEntityTypes("RAN_EQUIPMENT", paginationDTO1)).thenReturn(response);
-    }
-
-    private static void mockGetTopologyRelationshipTypes() {
-        OranTeivRelationshipTypesItemsInner element1 = new OranTeivRelationshipTypesItemsInner();
-        element1.setName("NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-        OranTeivRelationshipTypesItemsInner element2 = new OranTeivRelationshipTypesItemsInner();
-        element2.setName("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        OranTeivRelationshipTypesItemsInner element3 = new OranTeivRelationshipTypesItemsInner();
-        element3.setName("GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        OranTeivRelationshipTypesItemsInner element4 = new OranTeivRelationshipTypesItemsInner();
-        element4.setName("EUTRANCELL_USES_LTESECTORCARRIER");
-        OranTeivRelationshipTypesItemsInner element5 = new OranTeivRelationshipTypesItemsInner();
-        element5.setName("MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
-
-        List<OranTeivRelationshipTypesItemsInner> relationshipTypes = new ArrayList<>();
-        relationshipTypes.add(element1);
-        relationshipTypes.add(element2);
-        relationshipTypes.add(element3);
-        relationshipTypes.add(element4);
-        relationshipTypes.add(element5);
-
-        OranTeivRelationshipTypes response = new OranTeivRelationshipTypes();
-        response.setItems(relationshipTypes);
-
-        OranTeivHref href = new OranTeivHref();
-        href.setHref("/domains/RAN_LOGICAL/relationship-types?offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().basePath("/domains/RAN_LOGICAL/relationship-types").offset(0)
-                .limit(5).addPathParameters("domain", "RAN_LOGICAL").build();
-
-        when(dataService.getTopologyRelationshipTypes("RAN_LOGICAL", paginationDTO1)).thenReturn(response);
-    }
-
-    private static void mockTopologyByType() {
-        OranTeivEntitiesResponseMessage response = new OranTeivEntitiesResponseMessage();
-        Map<String, Object> query = new HashMap<>();
-
-        query.put("scopeFilter", "/attributes[contains (@fnd, \"/SubNetwork=Ireland/\")]");
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().offset(0).limit(3).addPathParameters("domain", "RAN_LOGICAL")
-                .addQueryParameters("targetFilter", "").addQueryParameters("scopeFilter",
-                        "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]").basePath(
-                                "/domains/RAN_LOGICAL/entity-types/GNBDUFunction/entities").build();
-
-        response.setItems(List.of(Map.of("GNBDUFunction", List.of(Map.of("id", "5FE67725576EDA7937752E7965164C2E"), Map.of(
-                "id", "9BCD297B8258F67908477D895636ED65"), Map.of("id", "8E249BCFAEC86C03D9ADD27FA9748254")))));
-        OranTeivHref href = new OranTeivHref();
-        href.setHref(
-                "/domains/RAN_LOGICAL/entity-types/GNBDUFunction/entities?scopeFilter=/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]&offset=0&limit=5");
-        response.setSelf(href);
-        response.setFirst(href);
-        response.setPrev(href);
-        response.setNext(href);
-        response.setLast(href);
-
-        when(dataService.getTopologyByType("GNBDUFunction", "", "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]",
-                paginationDTO)).thenReturn(response);
-
-        doThrow(TiesException.class).when(requestValidator).validateEntityTypeInDomain(eq("CloudSite"), eq("RAN_LOGICAL"));
-        doThrow(TiesException.class).when(requestValidator).validateEntityTypeInDomain(eq("GNBDUFunction2"), eq(
-                "RAN_LOGICAL"));
-
-        when(dataService.getTopologyByType("GNBDUFunction", "", "/attributes[contains ( fdn, \"/SubNetwork Ireland/\")]",
-                PaginationDTO.builder().offset(0).limit(3).addQueryParameters("targetFilter", "").addQueryParameters(
-                        "scopeFilter", "/attributes[contains ( fdn, \"/SubNetwork Ireland/\")]").basePath(
-                                "/domains/RAN_LOGICAL/entity-types/GNBDUFunction/entities").addPathParameters("domain",
-                                        "RAN_LOGICAL").build())).thenThrow(TiesPathException.grammarError("'@' missing"));
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistenceServiceImplGETRequestsContainerizedTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataPersistenceServiceImplGETRequestsContainerizedTest.java
deleted file mode 100644 (file)
index 504974d..0000000
+++ /dev/null
@@ -1,1190 +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 org.oran.smo.teiv.exposure.spi.impl;
-
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.ITEMS;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
-import static org.oran.smo.teiv.utils.exposure.PaginationVerifierTestUtil.verifyResponse;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.sql.DataSource;
-
-import org.oran.smo.teiv.schema.DataType;
-import org.jooq.DSLContext;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Configuration;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.oran.smo.teiv.db.TestPostgresqlContainer;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.spi.mapper.MapperUtility;
-import org.oran.smo.teiv.exposure.spi.mapper.PaginationMetaData;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.PostgresSchemaLoader;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.startup.SchemaHandler;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-import java.util.HashSet;
-
-@Configuration
-@SpringBootTest
-class DataPersistenceServiceImplGETRequestsContainerizedTest {
-    public static TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
-    private static DataPersistanceServiceImpl underTest;
-    private static MapperUtility mapperUtility;
-    private static DSLContext dslContext;
-    private static DSLContext writeDataDslContext;
-    private static final String REL_ID_PREFIX = "urn:base64:";
-
-    @MockBean
-    private SchemaHandler schemaHandler;
-
-    @BeforeAll
-    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
-        String url = postgreSQLContainer.getJdbcUrl();
-        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
-        dslContext = DSL.using(ds, SQLDialect.POSTGRES);
-        writeDataDslContext = DSL.using(ds, SQLDialect.POSTGRES);
-        mapperUtility = new MapperUtility();
-        underTest = new DataPersistanceServiceImpl(dslContext, writeDataDslContext, mapperUtility);
-        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(dslContext, new ObjectMapper());
-        postgresSchemaLoader.loadSchemaRegistry();
-        TestPostgresqlContainer.loadSampleData();
-    }
-
-    @BeforeEach
-    public void deleteAll() {
-        writeDataDslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(
-                t -> writeDataDslContext.truncate(t).cascade().execute());
-        TestPostgresqlContainer.loadSampleData();
-    }
-
-    @Test
-    void testGetTopology() {
-        Map<String, List<Object>> response = new HashMap<>();
-        Map<String, Object> responseData = new HashMap<>();
-        Map<String, Object> attributesMap = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:GNBDUFunction", List.of(responseData));
-        attributesMap.put("gNBDUId", null);
-        attributesMap.put("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16");
-        attributesMap.put("dUpLMNId", Map.of("mcc", "456", "mnc", "82"));
-        attributesMap.put("gNBId", 16L);
-        attributesMap.put("gNBIdLength", 2L);
-        attributesMap.put("cmId", null);
-        responseData.put("attributes", attributesMap);
-        responseData.put("id", "5A548EA9D166341776CA0695837E55D8");
-        responseData.put("sourceIds", List.of(
-                "urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary" + "/GNBDUFunction=16",
-                "urn:cmHandle:/395221E080CCF0FD1924103B15873814"));
-
-        Assertions.assertEquals(response, underTest.getTopology(SchemaRegistry.getEntityTypeByName("GNBDUFunction"),
-                "5A548EA9D166341776CA0695837E55D8"));
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getTopology(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunction"), "-1"));
-
-        response.clear();
-        responseData.clear();
-        attributesMap.clear();
-
-        response.put("o-ran-smo-teiv-ran:AntennaCapability", List.of(responseData));
-        attributesMap.put("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaCapability=1");
-        attributesMap.put("eUtranFqBands", List.of("123", "4564", "789"));
-        attributesMap.put("geranFqBands", List.of("123", "456", "789"));
-        attributesMap.put("nRFqBands", List.of("123", "456", "789"));
-        attributesMap.put("cmId", null);
-        responseData.put("attributes", attributesMap);
-        responseData.put("id", "5835F77BE9D4E102316BD59195F6370B");
-        responseData.put("sourceIds", Collections.EMPTY_LIST);
-
-        Assertions.assertEquals(response, underTest.getTopology(SchemaRegistry.getEntityTypeByName("AntennaCapability"),
-                "5835F77BE9D4E102316BD59195F6370B"));
-    }
-
-    @Test
-    void testGetAllRelationships_manyToOneAndOneToMany() {
-        List<Map<String, List<Object>>> mapsList = new ArrayList<>();
-        Map<String, Object> response = new HashMap<>();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/NRCellDU/B480427E8A0C0B8D994E437784BB382F/relationships").addPathParameters("eiid",
-                        "B480427E8A0C0B8D994E437784BB382F").addPathParameters("domain", "RAN").addPathParameters(
-                                "entityType", "NRCellDU").build();
-
-        paginationDTO1.setTotalSize(3);
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/NRCellDU/NON_EXISTING/relationships").addPathParameters("eiid", "NON_EXISTING")
-                .addPathParameters("domain", "RAN").addPathParameters("entityType", "NRCellDU").build();
-
-        mapsList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "D3215E08570BE58339C7463626B50E37", "B480427E8A0C0B8D994E437784BB382F",
-                REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg=="))));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU", List.of(generateResponse(
-                "F5128C172A70C4FCD4739650B06DE9E2", "B480427E8A0C0B8D994E437784BB382F",
-                REL_ID_PREFIX + "U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg=="))));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER", List.of(generateResponse(
-                "B480427E8A0C0B8D994E437784BB382F", "E49D942C16E0364E1E0788138916D70C",
-                REL_ID_PREFIX + "TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM="))));
-
-        response.put(ITEMS, mapsList);
-
-        verifyResponse(response, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName("NRCellDU"),
-                SchemaRegistry.getRelationTypesByEntityName("NRCellDU"), "B480427E8A0C0B8D994E437784BB382F",
-                paginationDTO1));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(SchemaRegistry
-                .getEntityTypeByName("NRCellDU"), SchemaRegistry.getRelationTypesByEntityName("NRCellDU"), "NON_EXISTING",
-                paginationDTO2));
-    }
-
-    @Test
-    void testGetAllRelationships_manyToMany() {
-        Map<String, Object> response = new HashMap<>();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/GNBCUUPFunction/BFEEAC2CE60273CB0A78319CC201A7FE/relationships").addPathParameters(
-                        "eiid", "BFEEAC2CE60273CB0A78319CC201A7FE").addPathParameters("domain", "RAN").addPathParameters(
-                                "entityType", "GNBCUUPFunction").build();
-        paginationDTO1.setTotalSize(2);
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/NRCellDU/NON_EXISTING/relationships").addPathParameters("eiid", "NON_EXISTING")
-                .addPathParameters("domain", "RAN").addPathParameters("entityType", "NRCellDU").build();
-
-        List<Map<String, List<Object>>> mapsList = new ArrayList<>();
-
-        mapsList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", List.of(
-                generateResponse("BFEEAC2CE60273CB0A78319CC201A7FE", "AD42D90497E93D276215DF6D3B899E17",
-                        REL_ID_PREFIX + "R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="))));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", List.of(generateResponse(
-                "E64371CD4D12ED0CED200DD3A7591784", "BFEEAC2CE60273CB0A78319CC201A7FE",
-                REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="))));
-
-        response.put(ITEMS, mapsList);
-
-        verifyResponse(response, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName("GNBCUUPFunction"),
-                SchemaRegistry.getRelationTypesByEntityName("GNBCUUPFunction"), "BFEEAC2CE60273CB0A78319CC201A7FE",
-                paginationDTO1));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(SchemaRegistry
-                .getEntityTypeByName("GNBCUUPFunction"), SchemaRegistry.getRelationTypesByEntityName("GNBCUUPFunction"),
-                "NON_EXISTING", paginationDTO2));
-    }
-
-    @Test
-    void testGetAllRelationshipsManyToMany_filteredByRelationship() {
-        List<Map<String, List<Object>>> mapsList = new ArrayList<>();
-        Map<String, Object> response = new HashMap<>();
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/GNBCUUPFunction/BFEEAC2CE60273CB0A78319CC201A7FE/relationships").addPathParameters(
-                        "eiid", "BFEEAC2CE60273CB0A78319CC201A7FE").addPathParameters("domain", "RAN").addPathParameters(
-                                "entityType", "GNBCUUPFunction").build();
-        paginationDTO1.setTotalSize(1);
-        paginationDTO1.setQueryParameters(Map.of("relationshipType", "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"));
-
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-        mapsList.add(Map.of("o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", List.of(generateResponse(
-                "E64371CD4D12ED0CED200DD3A7591784", "BFEEAC2CE60273CB0A78319CC201A7FE",
-                REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="))));
-        mapsList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", List.of(
-                generateResponse("BFEEAC2CE60273CB0A78319CC201A7FE", "AD42D90497E93D276215DF6D3B899E17",
-                        REL_ID_PREFIX + "R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="))));
-
-        response.put(ITEMS, List.of(mapsList.get(0)));
-        verifyResponse(response, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName("GNBCUUPFunction"), List
-                .of(SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION")),
-                "BFEEAC2CE60273CB0A78319CC201A7FE", paginationDTO1));
-
-        response.replace(ITEMS, List.of(mapsList.get(0)), List.of(mapsList.get(1)));
-        paginationDTO1.setQueryParameters(Map.of("relationshipType", "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"));
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-        verifyResponse(response, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName("GNBCUUPFunction"), List
-                .of(SchemaRegistry.getRelationTypeByName("GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION")),
-                "BFEEAC2CE60273CB0A78319CC201A7FE", paginationDTO1));
-
-        paginationDTO1.setQueryParameters(Map.of("relationshipType", "NON_EXISTING"));
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(SchemaRegistry
-                .getEntityTypeByName("GNBCUUPFunction"), List.of(SchemaRegistry.getRelationTypeByName(
-                        "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION")), "NON_EXISTING", paginationDTO1));
-    }
-
-    @Test
-    void testGetAllRelationshipsConnectingSameEntity_filteredByRelationship() {
-        String idConnectingSameEntity = REL_ID_PREFIX + "QW50ZW5uYU1vZHVsZToyNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==";
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN_EQUIPMENT/entities/AntennaModule/278A05C67D47D117C2DC5BDF5E00AE70/relationships")
-                .addPathParameters("eiid", "278A05C67D47D117C2DC5BDF5E00AE70").addPathParameters("domain", "RAN_EQUIPMENT")
-                .addPathParameters("entityType", "AntennaModule").build();
-        paginationDTO1.setTotalSize(1);
-        paginationDTO1.setQueryParameters(Map.of("relationshipType", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE"));
-
-        Map<String, Object> response = new HashMap<>(new PaginationMetaData().getObjectList(paginationDTO1));
-        Map<String, List<Object>> mapsList = Map.of("o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", List
-                .of(generateResponse("278A05C67D47D117C2DC5BDF5E00AE70", "279A05C67D47D117C2DC5BDF5E00AE70",
-                        idConnectingSameEntity)));
-        response.put(ITEMS, List.of(mapsList));
-
-        RelationType relSameEntity = SchemaRegistry.getRelationTypeByName("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-        EntityType entity = SchemaRegistry.getEntityTypeByName("AntennaModule");
-
-        Assertions.assertNotNull(relSameEntity);
-        Assertions.assertNotNull(entity);
-
-        verifyResponse(response, underTest.getAllRelationships(entity, List.of(relSameEntity),
-                "278A05C67D47D117C2DC5BDF5E00AE70", paginationDTO1));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(entity, List.of(
-                relSameEntity), "NON_EXISTING", paginationDTO1));
-    }
-
-    @Test
-    void testGetRelationshipWithSpecifiedId() {
-        String idOneToMany = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==";
-        Map<String, List<Object>> relationshipOneToMany = Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List
-                .of(generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A", idOneToMany,
-                        Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipOneToMany, underTest.getRelationshipWithSpecifiedId(idOneToMany, SchemaRegistry
-                .getRelationTypeByName("GNBDUFUNCTION_PROVIDES_NRCELLDU")));
-
-        String idManyToOne = REL_ID_PREFIX + "Tm9kZUNsdXN0ZXI6MDE1QzJEREJEN0FDNzIyQjM0RUQ2QTIwRURFRUI5QzM6TE9DQVRFRF9BVDpDbG91ZFNpdGU6MTZFRTE3QUU4OURGMTFCNjlFOTRCM0Y2ODI3QzJDMEU=";
-        Map<String, List<Object>> relationshipManyToOne = Map.of("o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE",
-                List.of(generateResponse("015C2DDBD7AC722B34ED6A20EDEEB9C3", "16EE17AE89DF11B69E94B3F6827C2C0E",
-                        idManyToOne, Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipManyToOne, underTest.getRelationshipWithSpecifiedId(idManyToOne, SchemaRegistry
-                .getRelationTypeByName("NODECLUSTER_LOCATED_AT_CLOUDSITE")));
-
-        String idManyToMany = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE";
-        Map<String, List<Object>> relationshipManyToMany = Map.of(
-                "o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", List.of(generateResponse(
-                        "4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D", idManyToMany,
-                        Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipManyToMany, underTest.getRelationshipWithSpecifiedId(idManyToMany,
-                SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION")));
-
-        String idConnectingSameEntity = REL_ID_PREFIX + "QW50ZW5uYU1vZHVsZToyNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==";
-        Map<String, List<Object>> relationshipConnectingSameEntity = Map.of(
-                "o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", List.of(generateResponse(
-                        "278A05C67D47D117C2DC5BDF5E00AE70", "279A05C67D47D117C2DC5BDF5E00AE70", idConnectingSameEntity,
-                        Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipConnectingSameEntity, underTest.getRelationshipWithSpecifiedId(
-                idConnectingSameEntity, SchemaRegistry.getRelationTypeByName("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE")));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getRelationshipWithSpecifiedId("NOT_EXISTING",
-                SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_PROVIDES_NRCELLDU")));
-    }
-
-    @Test
-    void testGetRelationshipsByType() {
-        Map<String, Object> oneToManyResult = new HashMap<>();
-        Map<String, Object> manyToOneResult = new HashMap<>();
-        Map<String, Object> manyToManyResult = new HashMap<>();
-
-        Map<String, Object> oneToManyQueryMap = new HashMap<>();
-        oneToManyQueryMap.put("query", Map.of("scopeFilter", "/attributes[@cellLocalId=2]"));
-        oneToManyResult.putAll(oneToManyQueryMap);
-
-        oneToManyResult.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(
-                generateResponse("D3215E08570BE58339C7463626B50E37", "F9546E82313AC1D5E690DCD7BE55606F",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpGOTU0NkU4MjMxM0FDMUQ1RTY5MERDRDdCRTU1NjA2Rg==")))));
-
-        PaginationMetaData metadataOneToMany = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/attributes[@cellLocalId=2]").build();
-        paginationDTO1.setTotalSize(1);
-        oneToManyResult.putAll(metadataOneToMany.getObjectList(paginationDTO1));
-
-        Map<String, Object> manyToOneQueryMap = new HashMap<>();
-        manyToOneQueryMap.put("query", Map.of("scopeFilter", "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]"));
-        manyToOneResult.putAll(manyToOneQueryMap);
-
-        manyToOneResult.put("items", List.of(Map.of("o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE",
-                List.of(generateResponse("719BD5C7CD8A939D76A83DA95DA45C01", "1C02E96B2AAE036C7AE404BC38C308E0",
-                        REL_ID_PREFIX + "Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA=")))));
-
-        PaginationMetaData metadataManyToOne = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]").build();
-        paginationDTO2.setTotalSize(1);
-        manyToOneResult.putAll(metadataManyToOne.getObjectList(paginationDTO2));
-
-        Map<String, Object> manyToManyQueryMap = new HashMap<>();
-        manyToManyQueryMap.put("query", Map.of("scopeFilter",
-                "/CloudNativeApplication/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"]"));
-        manyToManyResult.putAll(manyToManyQueryMap);
-
-        manyToManyResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", List.of(generateResponse(
-                        "4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE")))));
-
-        PaginationMetaData metadataManyToMany = new PaginationMetaData();
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/CloudNativeApplication/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"]").build();
-        paginationDTO3.setTotalSize(1);
-        manyToManyResult.putAll(metadataManyToMany.getObjectList(paginationDTO3));
-
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        RelationType manyToOne = SchemaRegistry.getRelationTypeByName("CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE");
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-
-        verifyResponse(oneToManyResult, underTest.getRelationshipsByType(oneToMany, "/attributes[@cellLocalId=2]",
-                PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter", "/attributes[@cellLocalId=2]")
-                        .build()));
-
-        verifyResponse(manyToOneResult, underTest.getRelationshipsByType(manyToOne,
-                "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]", PaginationDTO.builder().offset(0).limit(5)
-                        .addQueryParameters("scopeFilter", "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]").build()));
-
-        verifyResponse(manyToManyResult, underTest.getRelationshipsByType(manyToMany,
-                "/CloudNativeApplication/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"]", PaginationDTO.builder().offset(0)
-                        .limit(5).addQueryParameters("scopeFilter",
-                                "/CloudNativeApplication/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"]").build()));
-
-        assertThatThrownBy(() -> underTest.getRelationshipsByType(oneToMany, "/attributes[@celllocalid=2]", PaginationDTO
-                .builder().offset(0).limit(5).build())).isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(oneToMany, null, PaginationDTO.builder()
-                .offset(0).limit(5).build()));
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(oneToMany,
-                "/GNBDUFunction/attributes[contains (@fdn, \"GNBDUFunction=16\")]", PaginationDTO.builder().offset(0).limit(
-                        5).build()));
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(manyToMany,
-                "/CloudNativeApplication/attributes[@name=\"Example Cloud App/10\"] | /GNBDUFunction/id[@id=\"5A548EA9D166341776CA0695837E55D8\"]",
-                PaginationDTO.builder().offset(0).limit(5).build()));
-    }
-
-    @Test
-    void testGetRelationshipsByType_relConnectingSameEntity() {
-
-        Map<String, Object> resultOneScopeFilter = new HashMap<>();
-        Map<String, Object> resultTwoScopeFilter = new HashMap<>();
-        RelationType relationshipConnectingSameEntity = SchemaRegistry.getRelationTypeByName(
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-        String idConnectingSameEntity = REL_ID_PREFIX + "QW50ZW5uYU1vZHVsZToyNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==";
-        PaginationMetaData metadataRelConnectingSameEntity = new PaginationMetaData();
-
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]").build();
-        paginationDTO1.setTotalSize(1);
-        resultOneScopeFilter.putAll(metadataRelConnectingSameEntity.getObjectList(paginationDTO1));
-
-        Map<String, Object> queryMapOneScope = new HashMap<>();
-        queryMapOneScope.put("query", Map.of("scopeFilter", "/AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]"));
-        resultOneScopeFilter.putAll(queryMapOneScope);
-
-        resultOneScopeFilter.put("items", List.of(Map.of("o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE",
-                List.of(generateResponse("278A05C67D47D117C2DC5BDF5E00AE70", "279A05C67D47D117C2DC5BDF5E00AE70",
-                        idConnectingSameEntity)))));
-
-        verifyResponse(resultOneScopeFilter, underTest.getRelationshipsByType(relationshipConnectingSameEntity,
-                "/AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]", PaginationDTO.builder().offset(0).limit(5)
-                        .addQueryParameters("scopeFilter", "/AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]")
-                        .build()));
-
-        Map<String, Object> queryMapTwoScopes = new HashMap<>();
-        queryMapTwoScopes.put("query", Map.of("scopeFilter",
-                "/AntennaModule/id[@id=\"278A05C67D47D117C2DC5BDF5E00AE70\"] | /AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]"));
-        resultTwoScopeFilter.putAll(queryMapTwoScopes);
-
-        resultTwoScopeFilter.put("items", List.of(Map.of("o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE",
-                List.of(generateResponse("278A05C67D47D117C2DC5BDF5E00AE70", "279A05C67D47D117C2DC5BDF5E00AE70",
-                        idConnectingSameEntity)))));
-
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/AntennaModule/id[@id=\"278A05C67D47D117C2DC5BDF5E00AE70\"] | /AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]")
-                .build();
-        paginationDTO2.setTotalSize(1);
-        resultTwoScopeFilter.putAll(metadataRelConnectingSameEntity.getObjectList(paginationDTO2));
-
-        verifyResponse(resultTwoScopeFilter, underTest.getRelationshipsByType(relationshipConnectingSameEntity,
-                "/AntennaModule/id[@id=\"278A05C67D47D117C2DC5BDF5E00AE70\"]| /AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]",
-                PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                        "/AntennaModule/id[@id=\"278A05C67D47D117C2DC5BDF5E00AE70\"] | /AntennaModule/id[@id=\"279A05C67D47D117C2DC5BDF5E00AE70\"]")
-                        .build()));
-
-    }
-
-    @Test
-    void testGetTopologyByType() {
-        Map<String, Object> result = new HashMap<>();
-        Map<String, Object> queryMap = new HashMap<>();
-
-        queryMap.put("query", Map.of("targetFilter", "/attributes(fdn)", "scopeFilter",
-                "/attributes[contains(@fdn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']"));
-
-        result.putAll(queryMap);
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/RAN/entities/GNBDUFunction").offset(0)
-                .limit(2).addQueryParameters("targetFilter", "/attributes(fdn)").addQueryParameters("scopeFilter",
-                        "/attributes[contains(@fdn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']").build();
-        paginationDTO.setTotalSize(2);
-        result.putAll(new PaginationMetaData().getObjectList(paginationDTO));
-
-        result.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of(ATTRIBUTES, Map.of("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=13"), "id",
-                "25E690E22BDA90B9C4FEE1F083CBA597"), Map.of(ATTRIBUTES, Map.of("fdn",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=14"),
-                        "id", "5A3085C3400C3096E2ED2321452766B1")))));
-
-        verifyResponse(result, underTest.getTopologyByType("GNBDUFunction", "/attributes(fdn)",
-                "/attributes[contains(@fdn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']", PaginationDTO.builder()
-                        .offset(0).limit(2).basePath("/domains/RAN/entities/GNBDUFunction").addQueryParameters(
-                                "targetFilter", "/attributes(fdn)").addQueryParameters("scopeFilter",
-                                        "/attributes[contains(@fdn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']")
-                        .build()));
-
-        Assertions.assertThrows(TiesPathException.class, () -> underTest.getTopologyByType("GNBDUFunction",
-                "/attributes(fdn)", "/attributes[contains(@fdn, \"1000493\")] ; /attributes[@gNBId=4000259]", PaginationDTO
-                        .builder().offset(0).limit(2).build()));
-    }
-
-    @Test
-    void testGetEntitiesByDomain() {
-        Map<String, Object> reference1 = new HashMap<>();
-        Map<String, Object> query = new HashMap<>();
-
-        query.put("targetFilter", "/attributes(azimuth)");
-        query.put("scopeFilter", "/attributes[@azimuth=3]");
-
-        PaginationMetaData pmd1 = new PaginationMetaData();
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter", "/attributes(azimuth)").addQueryParameters("scopeFilter",
-                        "/attributes[@azimuth=3]").build();
-        paginationDTO.setTotalSize(1);
-        reference1.putAll(pmd1.getObjectList(paginationDTO));
-        reference1.put("query", query);
-
-        BigDecimal azimuth = new BigDecimal(3);
-        reference1.put("items", List.of(Map.of("o-ran-smo-teiv-ran:Sector", List.of(Map.of("id",
-                "ADB1BAAC878C0BEEFE3175C60F44BB1D", ATTRIBUTES, Map.of("azimuth", azimuth))))));
-        verifyResponse(reference1, underTest.getEntitiesByDomain("RAN", "/attributes(azimuth)", "/attributes[@azimuth=3]",
-                paginationDTO));
-
-        Map<String, Object> reference2 = new HashMap<>();
-        Map<String, Object> query2 = new HashMap<>();
-
-        query2.put("targetFilter", "/id");
-        query2.put("scopeFilter", "/id[contains(@id,\"F1407\")]");
-
-        PaginationMetaData pmd2 = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath("/domains/RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter", "/id").addQueryParameters("scopeFilter", "/id[contains(@id,\"F1407\")]")
-                .build();
-        paginationDTO2.setTotalSize(1);
-        pmd2.getObjectList(paginationDTO2);
-
-        reference2.put("query", query2);
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().basePath("/domains/RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter", "/id").addQueryParameters("scopeFilter", "/id[contains(@id,\"F1407\")]")
-                .build();
-        paginationDTO3.setTotalSize(1);
-        reference2.putAll(pmd2.getObjectList(paginationDTO3));
-
-        reference2.put("items", List.of(Map.of("o-ran-smo-teiv-ran:Sector", List.of(Map.of("id",
-                "2F445AA5744FA3D230FD6838531F1407")))));
-
-        verifyResponse(reference2, underTest.getEntitiesByDomain("RAN", "/id", "/id[contains(@id,\"F1407\")]",
-                paginationDTO2));
-
-        Map<String, Object> reference3 = new HashMap<>();
-        Map<String, Object> query3 = new HashMap<>();
-
-        query3.put("targetFilter", "/GNBDUFunction/attributes/fdn");
-        query3.put("scopeFilter", "/GNBDUFunction/attributes[contains(@fdn,\"GNBDUFunction=10\")]");
-
-        PaginationMetaData pmd3 = new PaginationMetaData();
-
-        reference3.put("query", query3);
-        PaginationDTO paginationDTO4 = PaginationDTO.builder().basePath("/domains/RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter", "/GNBDUFunction/attributes/fdn").addQueryParameters("scopeFilter",
-                        "/GNBDUFunction/attributes[contains(@fdn,\"GNBDUFunction=10\")]").build();
-        paginationDTO4.setTotalSize(1);
-        reference3.putAll(pmd3.getObjectList(paginationDTO4));
-
-        reference3.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                "1050570EBB1315E1AE7A9FD5E1400A00", ATTRIBUTES, Map.of("fdn",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=10"))))));
-
-        verifyResponse(reference3, underTest.getEntitiesByDomain("RAN", "/GNBDUFunction/attributes/fdn",
-                "/GNBDUFunction/attributes[contains(@fdn,\"GNBDUFunction=10\")]", paginationDTO4));
-
-        Object result = underTest.getEntitiesByDomain("OAM_TO_RAN", "/id", "", PaginationDTO.builder().offset(0).limit(500)
-                .build());
-        Assertions.assertEquals(10, ((Map) ((List) ((HashMap) result).get("items")).get(0)).size());
-        Assertions.assertTrue(((Map) ((List) ((HashMap) result).get("items")).get(0)).containsKey(
-                "o-ran-smo-teiv-oam:ManagedElement"));
-
-        Assertions.assertTrue(((Map) ((List) ((HashMap) result).get("items")).get(0)).containsKey(
-                "o-ran-smo-teiv-ran:GNBDUFunction"));
-    }
-
-    @Test
-    void testGetTopologyWithLongNames() {
-        Map<String, List<Object>> response = new HashMap<>();
-        Map<String, Object> responseData = new HashMap<>();
-        Map<String, Object> attributesMap = new HashMap<>();
-        response.put("o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn", List.of(
-                responseData));
-        attributesMap.put("gNBDUId", null);
-        attributesMap.put("fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16");
-        attributesMap.put("dUpLMNId", Map.of("mcc", "456", "mnc", "82"));
-        attributesMap.put("gNBId", 16L);
-        attributesMap.put("gNBIdLength", 2L);
-        attributesMap.put("cmId", null);
-        responseData.put("attributes", attributesMap);
-        responseData.put("id", "5A548EA9D166341776CA0695837E55D8");
-        responseData.put("sourceIds", Collections.EMPTY_LIST);
-
-        Assertions.assertEquals(response, underTest.getTopology(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), "5A548EA9D166341776CA0695837E55D8"));
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getTopology(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), "-1"));
-    }
-
-    @Test
-    void testGetAllRelationshipsWithLongNames_manyToOne_oneToMany_manyToMany() {
-        Map<String, Object> response = new HashMap<>();
-        List<Map<String, List<Object>>> mapsList = new ArrayList<>();
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/4CFF136200A2DE36205A13559C55DB2A/relationships")
-                .addPathParameters("eiid", "4CFF136200A2DE36205A13559C55DB2A").addPathParameters("domain", "RAN")
-                .addPathParameters("entityType", "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn")
-                .build();
-        paginationDTO.setTotalSize(6);
-        response.putAll(new PaginationMetaData().getObjectList(paginationDTO));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN",
-                List.of(generateResponse("8D51EFC759166044DACBCA63C4EDFC51", "4CFF136200A2DE36205A13559C55DB2A",
-                        REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6OEQ1MUVGQzc1OTE2NjA0NERBQ0JDQTYzQzRFREZDNTE6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjRDRkYxMzYyMDBBMkRFMzYyMDVBMTM1NTlDNTVEQjJB"))));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU", List.of(
-                generateResponse("4CFF136200A2DE36205A13559C55DB2A", "76E9F605D4F37330BF0B505E94F64F11",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTo3NkU5RjYwNUQ0RjM3MzMwQkYwQjUwNUU5NEY2NEYxMQ=="),
-                generateResponse("4CFF136200A2DE36205A13559C55DB2A", "67A1BDA10B5AF43028D07C7BE5CB1AE2",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTo2N0ExQkRBMTBCNUFGNDMwMjhEMDdDN0JFNUNCMUFFMg=="),
-                generateResponse("4CFF136200A2DE36205A13559C55DB2A", "B3B0A1939EFCA654A37005B6A7F24BD7",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTpCM0IwQTE5MzlFRkNBNjU0QTM3MDA1QjZBN0YyNEJENw=="),
-                generateResponse("4CFF136200A2DE36205A13559C55DB2A", "F26F279E91D0941DB4F646E707EA403A",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTpGMjZGMjc5RTkxRDA5NDFEQjRGNjQ2RTcwN0VBNDAzQQ=="))));
-
-        mapsList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN",
-                List.of(generateResponse("4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE"))));
-
-        response.put(ITEMS, mapsList);
-
-        verifyResponse(response, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), SchemaRegistry
-                        .getRelationTypesByEntityName("GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"),
-                "4CFF136200A2DE36205A13559C55DB2A", paginationDTO));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(SchemaRegistry
-                .getEntityTypeByName("GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), SchemaRegistry
-                        .getRelationTypesByEntityName("GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"),
-                "NON_EXISTING", paginationDTO));
-    }
-
-    @Test
-    void testGetAllRelationshipsWithLongNames_filteredByRelationship() {
-        List<Map<String, List<Object>>> mapsList = new ArrayList<>();
-
-        //One_To_One
-        Map<String, Object> expectedResponse1 = new HashMap<>();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN_OAM/entities/ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt/45EF31D8A1FD624D7276390A1215BFC3/relationships")
-                .addPathParameters("eiid", "45EF31D8A1FD624D7276390A1215BFC3").addPathParameters("domain", "RAN")
-                .addPathParameters("entityType", "ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt")
-                .build();
-        paginationDTO1.setTotalSize(1);
-        paginationDTO1.setQueryParameters(Map.of("relationshipType",
-                "MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM"));
-        expectedResponse1.putAll(new PaginationMetaData().getObjectList(paginationDTO1));
-        mapsList.add(Map.of("o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM",
-                List.of(generateResponse("45EF31D8A1FD624D7276390A1215BFC3", "C4E311A55666726FD9FE25CA572AFAF9",
-                        REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6NDVFRjMxRDhBMUZENjI0RDcyNzYzOTBBMTIxNUJGQzM6REVQTE9ZRURfQVM6Q2xvdWROYXRpdmVTeXN0ZW06QzRFMzExQTU1NjY2NzI2RkQ5RkUyNUNBNTcyQUZBRjk="))));
-        expectedResponse1.put(ITEMS, List.of(mapsList.get(0)));
-        verifyResponse(expectedResponse1, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName(
-                "ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt"), List.of(SchemaRegistry
-                        .getRelationTypeByName("MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM")),
-                "45EF31D8A1FD624D7276390A1215BFC3", paginationDTO1));
-
-        //One_To_Many
-        Map<String, Object> expectedResponse2 = new HashMap<>();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/45EF31D8A1FD624D7276390A1215BFC3/relationships")
-                .addPathParameters("eiid", "45EF31D8A1FD624D7276390A1215BFC3").addPathParameters("domain", "RAN")
-                .addPathParameters("entityType", "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn")
-                .build();
-        paginationDTO2.setTotalSize(1);
-        paginationDTO2.setQueryParameters(Map.of("relationshipType",
-                "MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN"));
-        expectedResponse2.putAll(new PaginationMetaData().getObjectList(paginationDTO2));
-        mapsList.add(Map.of("o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN",
-                List.of(generateResponse("8D51EFC759166044DACBCA63C4EDFC51", "4CFF136200A2DE36205A13559C55DB2A",
-                        REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6OEQ1MUVGQzc1OTE2NjA0NERBQ0JDQTYzQzRFREZDNTE6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjRDRkYxMzYyMDBBMkRFMzYyMDVBMTM1NTlDNTVEQjJB"))));
-        expectedResponse2.put(ITEMS, List.of(mapsList.get(1)));
-        verifyResponse(expectedResponse2, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), List.of(SchemaRegistry
-                        .getRelationTypeByName("MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN")),
-                "4CFF136200A2DE36205A13559C55DB2A", paginationDTO2));
-
-        //Many_To_One
-        Map<String, Object> expectedResponse3 = new HashMap<>();
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN_CLOUD/entities/Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/719BD5C7CD8A939D76A83DA95DA45C01/relationships")
-                .addPathParameters("eiid", "719BD5C7CD8A939D76A83DA95DA45C01").addPathParameters("domain", "RAN_CLOUD")
-                .addPathParameters("entityType", "Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
-                .build();
-        paginationDTO3.setTotalSize(1);
-        paginationDTO3.setQueryParameters(Map.of("relationshipType",
-                "CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE"));
-        expectedResponse3.putAll(new PaginationMetaData().getObjectList(paginationDTO3));
-        mapsList.add(Map.of("o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE", List
-                .of(generateResponse("719BD5C7CD8A939D76A83DA95DA45C01", "1C02E96B2AAE036C7AE404BC38C308E0",
-                        REL_ID_PREFIX + "Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA="))));
-        expectedResponse3.put(ITEMS, List.of(mapsList.get(2)));
-        verifyResponse(expectedResponse3, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName(
-                "Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"), List.of(SchemaRegistry
-                        .getRelationTypeByName("CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE")),
-                "1C02E96B2AAE036C7AE404BC38C308E0", paginationDTO3));
-
-        //Many_To_Many
-        Map<String, Object> expectedResponse4 = new HashMap<>();
-        PaginationDTO paginationDTO4 = PaginationDTO.builder().offset(0).limit(100).basePath(
-                "/domains/RAN/entities/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/4CFF136200A2DE36205A13559C55DB2A/relationships")
-                .addPathParameters("eiid", "4CFF136200A2DE36205A13559C55DB2A").addPathParameters("domain", "CLOUD_TO_RAN")
-                .addPathParameters("entityType", "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn")
-                .build();
-        paginationDTO4.setTotalSize(1);
-        paginationDTO4.setQueryParameters(Map.of("relationshipType",
-                "GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN"));
-        expectedResponse4.putAll(new PaginationMetaData().getObjectList(paginationDTO4));
-        mapsList.add(Map.of("o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN",
-                List.of(generateResponse("4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D",
-                        REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE"))));
-        expectedResponse4.put(ITEMS, List.of(mapsList.get(3)));
-        verifyResponse(expectedResponse4, underTest.getAllRelationships(SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), List.of(SchemaRegistry
-                        .getRelationTypeByName("GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN")),
-                "4CFF136200A2DE36205A13559C55DB2A", paginationDTO4));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getAllRelationships(SchemaRegistry
-                .getEntityTypeByName("GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"), List.of(
-                        SchemaRegistry.getRelationTypeByName(
-                                "GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN")), "NON_EXISTING",
-                paginationDTO4));
-    }
-
-    @Test
-    void testGetRelationshipWithSpecifiedIdWithLongNames() {
-        String idOneToOne = REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6NDVFRjMxRDhBMUZENjI0RDcyNzYzOTBBMTIxNUJGQzM6REVQTE9ZRURfQVM6Q2xvdWROYXRpdmVTeXN0ZW06QzRFMzExQTU1NjY2NzI2RkQ5RkUyNUNBNTcyQUZBRjk=";
-        Map<String, List<Object>> relationshipOneToOne = Map.of(
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM", List.of(
-                        generateResponse("45EF31D8A1FD624D7276390A1215BFC3", "C4E311A55666726FD9FE25CA572AFAF9", idOneToOne,
-                                Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipOneToOne, underTest.getRelationshipWithSpecifiedId(idOneToOne, SchemaRegistry
-                .getRelationTypeByName("MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM")));
-
-        String idOneToMany = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==";
-        Map<String, List<Object>> relationshipOneToMany = Map.of(
-                "o-ran-smo-teiv-ran:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU", List.of(
-                        generateResponse("D3215E08570BE58339C7463626B50E37", "98C3A4591A37718E1330F0294E23B62A",
-                                idOneToMany, Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipOneToMany, underTest.getRelationshipWithSpecifiedId(idOneToMany, SchemaRegistry
-                .getRelationTypeByName("GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU")));
-
-        String idManyToOne = REL_ID_PREFIX + "Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA=";
-        Map<String, List<Object>> relationshipManyToOne = Map.of(
-                "o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE", List.of(
-                        generateResponse("719BD5C7CD8A939D76A83DA95DA45C01", "1C02E96B2AAE036C7AE404BC38C308E0",
-                                idManyToOne, Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipManyToOne, underTest.getRelationshipWithSpecifiedId(idManyToOne, SchemaRegistry
-                .getRelationTypeByName("CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE")));
-
-        String idManyToMany = REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE";
-        Map<String, List<Object>> relationshipManyToMany = Map.of(
-                "o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN", List.of(
-                        generateResponse("4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D",
-                                idManyToMany, Collections.EMPTY_LIST)));
-
-        Assertions.assertEquals(relationshipManyToMany, underTest.getRelationshipWithSpecifiedId(idManyToMany,
-                SchemaRegistry.getRelationTypeByName("GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN")));
-
-        Assertions.assertThrowsExactly(TiesException.class, () -> underTest.getRelationshipWithSpecifiedId("NOT_EXISTING",
-                SchemaRegistry.getRelationTypeByName("GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU")));
-    }
-
-    @Test
-    void testGetRelationshipsByTypeWithLongNames() {
-        Map<String, Object> oneToOneResult = new HashMap<>();
-        Map<String, Object> oneToManyResult = new HashMap<>();
-        Map<String, Object> manyToOneResult = new HashMap<>();
-        Map<String, Object> manyToManyResult = new HashMap<>();
-
-        oneToOneResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM", List.of(
-                        generateResponse("45EF31D8A1FD624D7276390A1215BFC3", "C4E311A55666726FD9FE25CA572AFAF9",
-                                REL_ID_PREFIX + "TWFuYWdlZEVsZW1lbnQ6NDVFRjMxRDhBMUZENjI0RDcyNzYzOTBBMTIxNUJGQzM6REVQTE9ZRURfQVM6Q2xvdWROYXRpdmVTeXN0ZW06QzRFMzExQTU1NjY2NzI2RkQ5RkUyNUNBNTcyQUZBRjk=")))));
-        PaginationMetaData metadataOneToOne = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(5).build();
-        paginationDTO1.setTotalSize(1);
-        oneToOneResult.putAll(metadataOneToOne.getObjectList(paginationDTO1));
-
-        oneToManyResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-ran:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU", List.of(
-                        generateResponse("D3215E08570BE58339C7463626B50E37", "F9546E82313AC1D5E690DCD7BE55606F",
-                                REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpGOTU0NkU4MjMxM0FDMUQ1RTY5MERDRDdCRTU1NjA2Rg==")))));
-        PaginationMetaData metadataOneToMany = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/attributes[@cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd=2]").build();
-        paginationDTO2.setTotalSize(1);
-        oneToManyResult.putAll(metadataOneToMany.getObjectList(paginationDTO2));
-
-        manyToOneResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE", List.of(
-                        generateResponse("719BD5C7CD8A939D76A83DA95DA45C01", "1C02E96B2AAE036C7AE404BC38C308E0",
-                                REL_ID_PREFIX + "Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA=")))));
-        PaginationMetaData metadataManyToOne = new PaginationMetaData();
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]").build();
-        paginationDTO3.setTotalSize(1);
-        manyToOneResult.putAll(metadataManyToOne.getObjectList(paginationDTO3));
-
-        manyToManyResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN", List.of(
-                        generateResponse("4CFF136200A2DE36205A13559C55DB2A", "C549905CF3CC890CE5746C5E10ACF00D",
-                                REL_ID_PREFIX + "R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE")))));
-        PaginationMetaData metadataManyToMany = new PaginationMetaData();
-        PaginationDTO paginationDTO4 = PaginationDTO.builder().offset(0).limit(5).addQueryParameters("scopeFilter",
-                "/CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"] | /GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/id[@id=\"4CFF136200A2DE36205A13559C55DB2A\"]")
-                .build();
-        paginationDTO4.setTotalSize(1);
-        manyToManyResult.putAll(metadataManyToMany.getObjectList(paginationDTO4));
-
-        RelationType oneToOne = SchemaRegistry.getRelationTypeByName(
-                "MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName(
-                "GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU");
-        RelationType manyToOne = SchemaRegistry.getRelationTypeByName(
-                "CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE");
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName(
-                "GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN");
-
-        verifyResponse(oneToOneResult, underTest.getRelationshipsByType(oneToOne, null, paginationDTO1));
-        verifyResponse(oneToManyResult, underTest.getRelationshipsByType(oneToMany,
-                "/attributes[@cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd=2]", paginationDTO2));
-        verifyResponse(manyToOneResult, underTest.getRelationshipsByType(manyToOne,
-                "/id[@id=\"719BD5C7CD8A939D76A83DA95DA45C01\"]", paginationDTO3));
-        verifyResponse(manyToManyResult, underTest.getRelationshipsByType(manyToMany,
-                "/CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/id[@id=\"C549905CF3CC890CE5746C5E10ACF00D\"] | /GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/id[@id=\"4CFF136200A2DE36205A13559C55DB2A\"]",
-                paginationDTO4));
-
-        assertThatThrownBy(() -> underTest.getRelationshipsByType(oneToMany, "/attributes[@celllocalid=2]", PaginationDTO
-                .builder().offset(0).limit(5).build())).isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(oneToMany, null, PaginationDTO.builder()
-                .offset(0).limit(5).build()));
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(oneToMany,
-                "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn, \"GNBDUFunction=16\")]",
-                PaginationDTO.builder().offset(0).limit(5).build()));
-        Assertions.assertDoesNotThrow(() -> underTest.getRelationshipsByType(manyToMany,
-                "/CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes[@name=\"Example Cloud App/10\"] | /GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/id[@id=\"5A548EA9D166341776CA0695837E55D8\"]",
-                PaginationDTO.builder().offset(0).limit(5).build()));
-    }
-
-    @Test
-    void testGetRelationshipsByTypeWithLongNames_relConnectingSameEntity() {
-        Map<String, Object> sameEntityOneToOneResult = new HashMap<>();
-        Map<String, Object> sameEntityOneToManyResult = new HashMap<>();
-
-        // Rel connectingSameEntity ONE_TO_ONE
-        RelationType relSameEntityOneToOne = SchemaRegistry.getRelationTypeByName(
-                "ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE");
-        sameEntityOneToOneResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE", List.of(
-                        generateResponse("478A05C67D47D117C2DC5BDF5E00AE70", "479A05C67D47D117C2DC5BDF5E00AE70",
-                                REL_ID_PREFIX + "QW50ZW5uYU1vZHVsZTo0NzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpERVBMT1lFRF9CWTpBbnRlbm5hTW9kdWxlOjQ3OUEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==")))));
-        PaginationMetaData metadataOneToMany = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().offset(0).limit(5).build();
-        paginationDTO2.setTotalSize(1);
-        sameEntityOneToOneResult.putAll(metadataOneToMany.getObjectList(paginationDTO2));
-
-        verifyResponse(sameEntityOneToOneResult, underTest.getRelationshipsByType(relSameEntityOneToOne, null, PaginationDTO
-                .builder().offset(0).limit(5).build()));
-
-        // Rel connectingSameEntity ONE_TO_MANY
-        RelationType relSameEntityOneToMany = SchemaRegistry.getRelationTypeByName(
-                "ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE");
-        sameEntityOneToManyResult.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE", List.of(
-                        generateResponse("378A05C67D47D117C2DC5BDF5E00AE70", "379A05C67D47D117C2DC5BDF5E00AE70",
-                                REL_ID_PREFIX + "QW50ZW5uYU1vZHVsZTozNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjM3OUEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==")))));
-        PaginationMetaData metadataOneToOne = new PaginationMetaData();
-        PaginationDTO paginationDTO1 = PaginationDTO.builder().offset(0).limit(5).build();
-        paginationDTO1.setTotalSize(1);
-        sameEntityOneToManyResult.putAll(metadataOneToOne.getObjectList(paginationDTO1));
-
-        verifyResponse(sameEntityOneToManyResult, underTest.getRelationshipsByType(relSameEntityOneToMany, null,
-                PaginationDTO.builder().offset(0).limit(5).build()));
-    }
-
-    @Test
-    void testGetTopologyByTypeWithLongNames() {
-        Map<String, Object> result = new HashMap<>();
-        Map<String, Object> queryMap = new HashMap<>();
-
-        queryMap.put("query", Map.of("targetFilter",
-                "/attributes(fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn)", "scopeFilter",
-                "/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']"));
-
-        result.putAll(queryMap);
-
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/RAN/entities/GNBDUFunction").offset(0)
-                .limit(2).addQueryParameters("targetFilter",
-                        "/attributes(fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn)").addQueryParameters(
-                                "scopeFilter",
-                                "/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']")
-                .build();
-        paginationDTO.setTotalSize(2);
-        result.putAll(new PaginationMetaData().getObjectList(paginationDTO));
-
-        result.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn", List.of(Map.of(
-                        ATTRIBUTES, Map.of("fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=13"),
-                        "id", "25E690E22BDA90B9C4FEE1F083CBA597"), Map.of(ATTRIBUTES, Map.of(
-                                "fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=14"),
-                                "id", "5A3085C3400C3096E2ED2321452766B1")))));
-
-        verifyResponse(result, underTest.getTopologyByType(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "/attributes(fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn)",
-                "/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn, \"13\")] | /id[@id='5A3085C3400C3096E2ED2321452766B1']",
-                paginationDTO));
-        Assertions.assertThrows(TiesPathException.class, () -> underTest.getTopologyByType(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "/attributes(fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn)",
-                "/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn, \"1000493\")] ; /attributes[@gNBId=4000259]",
-                PaginationDTO.builder().offset(0).limit(2).build()));
-    }
-
-    @Test
-    void testGetEntitiesByDomainWithLongNames() {
-        Map<String, Object> reference1 = new HashMap<>();
-        Map<String, String> query = new LinkedHashMap<>();
-
-        query.put("scopeFilter", "/attributes[@cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd=3]");
-        query.put("targetFilter", "/attributes(cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd)");
-
-        PaginationMetaData pmd1 = new PaginationMetaData();
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/domains/EQUIPMENT_TO_RAN").offset(0).limit(5)
-                .build();
-        paginationDTO.setQueryParameters(query);
-        paginationDTO.setTotalSize(1);
-        reference1.putAll(pmd1.getObjectList(paginationDTO));
-
-        reference1.put("query", query);
-
-        reference1.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-ran:NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", List.of(Map.of("id",
-                        "B480427E8A0C0B8D994E437784BB382F", ATTRIBUTES, Map.of(
-                                "cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd", "3"))))));
-
-        Map<String, Object> reference2 = new HashMap<>();
-        Map<String, Object> query2 = new HashMap<>();
-
-        query2.put("targetFilter", "/id");
-        query2.put("scopeFilter", "/id[contains(@id,\"EA403A\")]");
-
-        PaginationMetaData pmd2 = new PaginationMetaData();
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath("/domains/EQUIPMENT_TO_RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter", "/id").addQueryParameters("scopeFilter",
-                        "/id[contains(@id,\"EA403A\")]").build();
-        paginationDTO2.setTotalSize(1);
-        reference1.putAll(pmd2.getObjectList(paginationDTO2));
-
-        reference2.put("query", query2);
-
-        reference2.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-ran:NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", List.of(Map.of("id",
-                        "F26F279E91D0941DB4F646E707EA403A")))));
-
-        verifyResponse(reference2, underTest.getEntitiesByDomain("EQUIPMENT_TO_RAN", "/id", "/id[contains(@id,\"EA403A\")]",
-                paginationDTO2));
-
-        Map<String, Object> reference3 = new HashMap<>();
-        Map<String, Object> query3 = new HashMap<>();
-
-        query3.put("targetFilter",
-                "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes/fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
-        query3.put("scopeFilter",
-                "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn,\"GNBDUFunction=10\")]");
-
-        PaginationMetaData pmd3 = new PaginationMetaData();
-        PaginationDTO paginationDTO3 = PaginationDTO.builder().basePath("/domains/EQUIPMENT_TO_RAN").offset(0).limit(5)
-                .addQueryParameters("targetFilter",
-                        "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes/fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn")
-                .addQueryParameters("scopeFilter",
-                        "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn,\"GNBDUFunction=10\")]")
-                .build();
-        paginationDTO3.setTotalSize(1);
-        reference1.putAll(pmd3.getObjectList(paginationDTO3));
-
-        reference3.put("query", query3);
-
-        reference3.put("items", List.of(Map.of(
-                "o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn", List.of(Map.of("id",
-                        "1050570EBB1315E1AE7A9FD5E1400A00", ATTRIBUTES, Map.of(
-                                "fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=10"))))));
-
-        verifyResponse(reference3, underTest.getEntitiesByDomain("RAN",
-                "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes/fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "/GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn/attributes[contains(@fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn,\"GNBDUFunction=10\")]",
-                paginationDTO3));
-
-        Object result = underTest.getEntitiesByDomain("OAM_TO_RAN", "/id", "", PaginationDTO.builder().offset(0).limit(500)
-                .build());
-        Assertions.assertEquals(10, ((Map) ((List) ((HashMap) result).get("items")).get(0)).size());
-        Assertions.assertTrue(((Map) ((List) ((HashMap) result).get("items")).get(0)).containsKey(
-                "o-ran-smo-teiv-oam:ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt"));
-
-        Assertions.assertTrue(((Map) ((List) ((HashMap) result).get("items")).get(0)).containsKey(
-                "o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn"));
-    }
-
-    @Test
-    void testAvailableClassifiers() {
-        Assertions.assertEquals(Set.of("gnbdu-function-model:Rural", "gnbcucp-gnbcuup-model:Weekend"), underTest
-                .loadClassifiers());
-    }
-
-    @Test
-    void testAvailableDecorators() {
-        Assertions.assertEquals(Map.of("gnbdu-function-model:location", DataType.PRIMITIVE,
-                "gnbcucp-gnbcuup-model:metadata", DataType.CONTAINER), underTest.loadDecorators());
-    }
-
-    @Test
-    void testGetSchemasByDomain() {
-        Set<Map<String, Object>> expected = new HashSet<>();
-        for (StoredSchema schema : getSchemasList()) {
-            if (schema.getDomain() == null || !schema.getDomain().equals("RAN_OAM_TO_CLOUD")) {
-                continue;
-            }
-            Map<String, Object> exp = new HashMap<>();
-            exp.put("domain", Collections.singletonList(schema.getDomain()));
-            exp.put("name", schema.getName());
-            exp.put("revision", schema.getRevision());
-            exp.put("content", Collections.singletonMap("href", "/schemas/" + schema.getName() + "/content"));
-            expected.add(exp);
-        }
-
-        Assertions.assertEquals(expected, new HashSet<>((List) underTest.getSchemas("RAN_OAM_TO_CLOUD", PaginationDTO
-                .builder().offset(0).limit(15).build()).get("items")));
-    }
-
-    @Test
-    void testGetSchemasWithPartialDomain() {
-        Set<Map<String, Object>> expected = new HashSet<>();
-        for (StoredSchema schema : getSchemasList()) {
-            if (schema.getDomain() == null || !schema.getDomain().matches("RAN_.*O.*")) {
-                continue;
-            }
-            Map<String, Object> exp = new HashMap<>();
-            exp.put("domain", Collections.singletonList(schema.getDomain()));
-            exp.put("name", schema.getName());
-            exp.put("revision", schema.getRevision());
-            exp.put("content", Collections.singletonMap("href", "/schemas/" + schema.getName() + "/content"));
-            expected.add(exp);
-        }
-
-        Assertions.assertEquals(expected, new HashSet<>((List) underTest.getSchemas("RAN_.*O.*", PaginationDTO.builder()
-                .offset(0).limit(15).build()).get("items")));
-    }
-
-    @Test
-    void testGetSchema() {
-        StoredSchema expected = null;
-        for (StoredSchema schema : getSchemasList()) {
-            if (schema.getName().equals("o-ran-smo-teiv-oam")) {
-                expected = schema;
-                break;
-            }
-        }
-
-        StoredSchema actual = underTest.getSchema("o-ran-smo-teiv-oam");
-        Assertions.assertTrue(actual.getContent().contains("o-ran-smo-teiv-oam"));
-
-        actual.setContent("yang model o-ran-smo-teiv-oam {}");
-        Assertions.assertEquals(expected, actual);
-
-        Assertions.assertNull(underTest.getSchema("o-ran-smo-teiv-invalid"));
-    }
-
-    @Test
-    void testSchemaCRUD() {
-        Assertions.assertNull(underTest.getSchema("newSchema"));
-
-        StoredSchema expected = new StoredSchema();
-        expected.setName("newSchema");
-        expected.setNamespace("new-namespace");
-        expected.setDomain("NEW_DOMAIN");
-        expected.setIncludedModules(new ArrayList<>());
-        expected.setContent("yang content {} \n\n \t\t\t;");
-        expected.setOwnerAppId("additional");
-        expected.setStatus("IN_USAGE");
-
-        underTest.postSchema("newSchema", "new-namespace", "NEW_DOMAIN", new ArrayList<>(), "yang content {} \n\n \t\t\t;",
-                "additional");
-
-        Assertions.assertEquals(expected, underTest.getSchema("newSchema"));
-
-        underTest.setSchemaToDeleting("newSchema");
-
-        expected.setStatus("DELETING");
-        Assertions.assertEquals(expected, underTest.getSchema("newSchema"));
-
-        underTest.deleteSchema("newSchema");
-
-        Assertions.assertNull(underTest.getSchema("newSchema"));
-    }
-
-    private List<StoredSchema> getSchemasList() {
-        final List<StoredSchema> schemas = new ArrayList<>();
-
-        StoredSchema ranLogicalToCloud = new StoredSchema();
-        ranLogicalToCloud.setName("o-ran-smo-teiv-cloud-to-ran");
-        ranLogicalToCloud.setNamespace("urn:o-ran:smo-teiv-cloud-to-ran");
-        ranLogicalToCloud.setDomain("CLOUD_TO_RAN");
-        ranLogicalToCloud.setRevision("2023-10-24");
-
-        StoredSchema ranEquipment = new StoredSchema();
-        ranEquipment.setName("o-ran-smo-teiv-equipment");
-        ranEquipment.setNamespace("urn:o-ran:smo-teiv-equipment");
-        ranEquipment.setDomain("EQUIPMENT");
-        ranEquipment.setRevision("2023-06-26");
-
-        StoredSchema ranOamToCloud = new StoredSchema();
-        ranOamToCloud.setName("o-ran-smo-teiv-oam-to-cloud");
-        ranOamToCloud.setNamespace("urn:o-ran:smo-teiv-oam-to-cloud");
-        ranOamToCloud.setDomain("OAM_TO_CLOUD");
-        ranOamToCloud.setRevision("2023-10-24");
-
-        StoredSchema ranOamToLogical = new StoredSchema();
-        ranOamToLogical.setName("o-ran-smo-teiv-oam-to-ran");
-        ranOamToLogical.setNamespace("urn:o-ran:smo-teiv-oam-to-ran");
-        ranOamToLogical.setDomain("OAM_TO_RAN");
-        ranOamToLogical.setRevision("2023-10-24");
-
-        StoredSchema ranCloud = new StoredSchema();
-        ranCloud.setName("o-ran-smo-teiv-cloud");
-        ranCloud.setNamespace("urn:o-ran:smo-teiv-cloud");
-        ranCloud.setDomain("CLOUD");
-        ranCloud.setRevision("2023-06-26");
-
-        StoredSchema ranOam = new StoredSchema();
-        ranOam.setName("o-ran-smo-teiv-oam");
-        ranOam.setNamespace("urn:o-ran:smo-teiv-oam");
-        ranOam.setDomain("OAM");
-        ranOam.setRevision("2024-05-02");
-        ranOam.setIncludedModules(new ArrayList<>());
-        ranOam.setOwnerAppId("BUILT_IN_MODULE");
-        ranOam.setStatus("IN_USAGE");
-        ranOam.setContent("yang model o-ran-smo-teiv-oam {}");
-
-        StoredSchema yangTypes = new StoredSchema();
-        yangTypes.setName("o-ran-smo-teiv-common-yang-types");
-        yangTypes.setRevision("2023-07-04");
-
-        StoredSchema ranLogicalToEquipment = new StoredSchema();
-        ranLogicalToEquipment.setName("o-ran-smo-teiv-equipment-to-ran");
-        ranLogicalToEquipment.setDomain("EQUIPMENT_TO_RAN");
-        ranLogicalToEquipment.setRevision("2023-10-24");
-
-        StoredSchema gnbcucpGnbcuupModel = new StoredSchema();
-        gnbcucpGnbcuupModel.setName("gnbcucp-gnbcuup-model");
-
-        StoredSchema yangExtensions = new StoredSchema();
-        yangExtensions.setName("o-ran-smo-teiv-common-yang-extensions");
-        yangExtensions.setRevision("2023-07-04");
-
-        StoredSchema ranLogical = new StoredSchema();
-        ranLogical.setName("o-ran-smo-teiv-ran");
-        ranLogical.setDomain("RAN");
-        ranLogical.setRevision("2023-11-03");
-
-        StoredSchema gnbduFunctionModel = new StoredSchema();
-        gnbduFunctionModel.setName("gnbdu-function-model");
-
-        schemas.add(ranLogicalToCloud);
-        schemas.add(ranEquipment);
-        schemas.add(ranOamToCloud);
-        schemas.add(ranOamToLogical);
-        schemas.add(ranCloud);
-        schemas.add(ranOam);
-        schemas.add(yangTypes);
-        schemas.add(ranLogicalToEquipment);
-        schemas.add(gnbcucpGnbcuupModel);
-        schemas.add(yangExtensions);
-        schemas.add(ranLogical);
-        schemas.add(gnbduFunctionModel);
-
-        return schemas;
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImplGETRequestsContainerizedTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/impl/DataRepositoryImplGETRequestsContainerizedTest.java
new file mode 100644 (file)
index 0000000..b88ca1c
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *  ============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.teiv.exposure.spi.impl;
+
+import static org.oran.smo.teiv.utils.TiesConstants.MODULE_REFERENCE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_CONSUMER_DATA;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_MODEL;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import javax.sql.DataSource;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.jetbrains.annotations.NotNull;
+import org.jooq.DSLContext;
+import org.jooq.Record1;
+import org.jooq.SQLDialect;
+import org.jooq.impl.DSL;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.Configuration;
+
+import org.oran.smo.teiv.db.TestPostgresqlContainer;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.exposure.spi.Module;
+import org.oran.smo.teiv.exposure.spi.ModuleStatus;
+import org.oran.smo.teiv.exposure.tiespath.refiner.BasePathRefinement;
+import org.oran.smo.teiv.schema.PostgresSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.startup.SchemaHandler;
+
+@Configuration
+@SpringBootTest
+class DataRepositoryImplGETRequestsContainerizedTest {
+    public static TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
+    private static DataRepositoryImpl underTest;
+    private static ModelRepository modelRepository;
+    private static BasePathRefinement basePathRefinement;
+    private static DSLContext readWriteDataDslContext;
+    private static DSLContext readDataDslContext;
+    private static DSLContext writeDataDslContext;
+
+    @MockBean
+    private SchemaHandler schemaHandler;
+
+    @BeforeAll
+    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
+        String url = postgreSQLContainer.getJdbcUrl();
+        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
+        readDataDslContext = DSL.using(ds, SQLDialect.POSTGRES);
+        writeDataDslContext = DSL.using(ds, SQLDialect.POSTGRES);
+        underTest = new DataRepositoryImpl(basePathRefinement, readDataDslContext);
+        modelRepository = new ModelRepositoryImpl(readDataDslContext, readWriteDataDslContext, writeDataDslContext);
+        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(readDataDslContext, new ObjectMapper());
+        postgresSchemaLoader.loadSchemaRegistry();
+        TestPostgresqlContainer.loadSampleData();
+    }
+
+    @BeforeEach
+    public void deleteAll() {
+        writeDataDslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(
+                t -> writeDataDslContext.truncate(t).cascade().execute());
+        TestPostgresqlContainer.loadSampleData();
+    }
+
+    //TODO: Make this test class generic for all repositories
+    @Test
+    void testSchemaCRUD() {
+        final String moduleName = "newSchema";
+        Optional<Module> schemaByName = modelRepository.getConsumerModuleByName(moduleName);
+        Assertions.assertFalse(schemaByName.isPresent());
+
+        Module schema = Module.builder().name(moduleName).namespace("new-namespace").domain("NEW_DOMAIN").content(
+                "yang content {} \n\n \t\t\t;").ownerAppId("APP").status(ModuleStatus.IN_USAGE).build();
+
+        modelRepository.createModule(schema);
+
+        schemaByName = modelRepository.getConsumerModuleByName(moduleName);
+        Assertions.assertTrue(schemaByName.isPresent());
+
+        modelRepository.doesModuleExists(TIES_MODEL, moduleName);
+        modelRepository.doesModuleExists(TIES_CONSUMER_DATA, moduleName);
+
+        modelRepository.updateModuleStatus(moduleName, ModuleStatus.DELETING);
+
+        final @NotNull Record1<Object> status = readDataDslContext.select(field("status")).from(table(String.format(
+                TIES_CONSUMER_DATA, MODULE_REFERENCE))).where(field("name").eq(moduleName)).fetchAny();
+
+        Assertions.assertEquals(ModuleStatus.DELETING.name(), status.get("status"));
+
+        modelRepository.deleteModuleByName(moduleName);
+
+        schemaByName = modelRepository.getConsumerModuleByName(moduleName);
+        Assertions.assertFalse(schemaByName.isPresent());
+    }
+
+    @Test
+    void getClassifiersForSchema() {
+        assertThat(List.of("test-app-module:Indoor", "test-app-module:Outdoor", "test-app-module:Rural",
+                "test-app-module:Weekday", "test-app-module:Weekend")).hasSameElementsAs(underTest.getClassifiersForSchema(
+                        "test-app-module"));
+    }
+
+    @Test
+    void getDecoratorsForSchema() {
+        assertThat(List.of("test-app-module:textdata", "test-app-module:intdata")).hasSameElementsAs(underTest
+                .getDecoratorsForSchema("test-app-module"));
+    }
+
+    @Test
+    void getRelationshipIdsForDecoratorDeletionTest() {
+        Assertions.assertEquals(Collections.singletonList(
+                "urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="),
+                underTest.getRelationshipIdsForDecoratorDeletion(SchemaRegistry.getRelationTypeByName(
+                        "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"), Set.of("gnbcucp-gnbcuup-model:metadata")));
+
+        Assertions.assertEquals(Collections.singletonList(
+                "urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="),
+                underTest.getRelationshipIdsForDecoratorDeletion(SchemaRegistry.getRelationTypeByName(
+                        "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"), Set.of("gnbcucp-gnbcuup-model:metadata")));
+    }
+
+    @Test
+    void getRelationshipIdsForClassifierDeletionTest() {
+        Assertions.assertEquals(Collections.singletonList(
+                "urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="),
+                underTest.getRelationshipIdsForClassifierDeletion(SchemaRegistry.getRelationTypeByName(
+                        "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"), Set.of("gnbcucp-gnbcuup-model:Weekend")));
+
+        Assertions.assertEquals(Collections.singletonList(
+                "urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="),
+                underTest.getRelationshipIdsForClassifierDeletion(SchemaRegistry.getRelationTypeByName(
+                        "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"), Set.of("gnbcucp-gnbcuup-model:Weekend")));
+    }
+
+    @Test
+    void getEntityIdsForDecoratorDeletionTest() {
+        Assertions.assertEquals(Collections.singletonList("E49D942C16E0364E1E0788138916D70C"), underTest
+                .getEntityIdsForDecoratorDeletion(SchemaRegistry.getEntityTypeByName("NRSectorCarrier"), Set.of(
+                        "gnbcucp-gnbcuup-model:metadata")));
+    }
+
+    @Test
+    void getEntityIdsForClassifierDeletionTest() {
+        Assertions.assertEquals(Collections.singletonList("E49D942C16E0364E1E0788138916D70C"), underTest
+                .getEntityIdsForClassifierDeletion(SchemaRegistry.getEntityTypeByName("NRSectorCarrier"), Set.of(
+                        "gnbcucp-gnbcuup-model:Weekend")));
+    }
+
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapperTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/ComplexMapperTest.java
deleted file mode 100644 (file)
index 5b63746..0000000
+++ /dev/null
@@ -1,77 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.jooq.impl.DSL.field;
-
-class ComplexMapperTest {
-    private static ComplexMapper complexMapper;
-
-    @BeforeAll
-    static void setUp() throws SchemaLoaderException {
-        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
-        mockSchemaLoader.loadSchemaRegistry();
-        complexMapper = new ComplexMapper();
-    }
-
-    @Test
-    void testMap() {
-        final Result<Record> records = DSL.using(SQLDialect.POSTGRES).newResult();
-
-        final String gNBDUName = String.format(TIES_DATA, "GNBDUFunction");
-        final String nRCellDUName = String.format(TIES_DATA, "NRCellDU");
-
-        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(gNBDUName + ".id"), field(gNBDUName + ".fdn"), field(
-                nRCellDUName + ".id")).values("9BCD297B8258F67908477D895636ED65",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91",
-                        null));
-        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(gNBDUName + ".id"), field(gNBDUName + ".fdn"), field(
-                nRCellDUName + ".id")).values(null, null, "98C3A4591A37718E1330F0294E23B62A"));
-
-        Map<String, Object> result = new HashMap<>();
-
-        result.put("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of(ATTRIBUTES, Map.of("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91"), "id",
-                "9BCD297B8258F67908477D895636ED65")));
-
-        result.put("o-ran-smo-teiv-ran:NRCellDU", List.of(Map.of("id", "98C3A4591A37718E1330F0294E23B62A")));
-
-        Assertions.assertEquals(result, complexMapper.map(records));
-    }
-
-}
index 1971be4..7e66074 100644 (file)
  */
 package org.oran.smo.teiv.exposure.spi.mapper;
 
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import org.oran.smo.teiv.schema.Module;
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
+import static org.jooq.impl.DSL.field;
+
+import java.util.List;
+import java.util.Map;
 
 import org.jooq.Record;
 import org.jooq.Result;
@@ -34,44 +33,41 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.jooq.impl.DSL.field;
+import org.oran.smo.teiv.api.model.OranTeivEntitiesResponseMessage;
+import org.oran.smo.teiv.exposure.utils.RequestDetails;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 
 class EntityMapperTest {
-    private static EntityMapper entityMapper;
+
+    EntityMapper entityMapper = new EntityMapper();
 
     @BeforeAll
     static void setUp() throws SchemaLoaderException {
-        EntityType entityType = EntityType.builder().name("GNBDUFunction").module(Module.builder().name(
-                "o-ran-smo-teiv-ran").build()).build();
-        entityMapper = new EntityMapper(entityType);
-        SchemaLoader mockSchemaLoader = new MockSchemaLoader();
+        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
         mockSchemaLoader.loadSchemaRegistry();
     }
 
     @Test
     void testMap() {
-        final Result<Record> record = DSL.using(SQLDialect.POSTGRES).newResult();
-        Map<String, Object> result = new HashMap<>();
-
-        record.add(DSL.using(SQLDialect.POSTGRES).newRecord(field("dUpLMNId"), field("fdn"), field("gNBDUId"), field(
-                "gNBId"), field("cmId"), field("gNBIdLength"), field("id"), field("CD_sourceIds")).values(Map.of("mcc",
-                        "456", "mnc", "82"),
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=95", 95,
-                        95, "null", 2, "5970A12E0AF8B0FBE0B49290FE847F9B", List.of(
-                                "urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=95",
-                                "urn:cmHandle:/395221E080CCF0FD1924103B15873814")));
+        final Result<Record> records = DSL.using(SQLDialect.POSTGRES).newResult();
+        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field("o-ran-smo-teiv-ran:GNBDUFunction.id"), field(
+                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), field("o-ran-smo-teiv-ran:NRCellDU.id"), field("count"))
+                .values("9BCD297B8258F67908477D895636ED65", 1, null, null));
+        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field("o-ran-smo-teiv-ran:GNBDUFunction.id"), field(
+                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), field("o-ran-smo-teiv-ran:NRCellDU.id"), field("count"))
+                .values(null, null, "98C3A4591A37718E1330F0294E23B62A", null));
+        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field("o-ran-smo-teiv-ran:GNBDUFunction.id"), field(
+                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), field("o-ran-smo-teiv-ran:NRCellDU.id"), field("count"))
+                .values(null, null, null, 2));
 
-        result.put("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of(ATTRIBUTES, Map.of("dUpLMNId", Map.of("mcc", "456",
-                "mnc", "82"), "fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=95", "gNBDUId",
-                95, "gNBId", 95, "cmId", "null", "gNBIdLength", 2), "id", "5970A12E0AF8B0FBE0B49290FE847F9B", "sourceIds",
-                List.of("urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=95",
-                        "urn:cmHandle:/395221E080CCF0FD1924103B15873814"))));
+        OranTeivEntitiesResponseMessage result = entityMapper.mapEntities(records, RequestDetails.builder().basePath(
+                "/test").offset(0).limit(100).build());
 
-        Assertions.assertEquals(result, entityMapper.map(record));
+        Assertions.assertEquals(2, result.getTotalCount());
+        Assertions.assertEquals(List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
+                "9BCD297B8258F67908477D895636ED65", "attributes", Map.of("gNBId", 1)))), Map.of(
+                        "o-ran-smo-teiv-ran:NRCellDU", List.of(Map.of("id", "98C3A4591A37718E1330F0294E23B62A")))), result
+                                .getItems());
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtilityTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/MapperUtilityTest.java
deleted file mode 100644 (file)
index 26b908b..0000000
+++ /dev/null
@@ -1,178 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.oran.smo.teiv.utils.TiesConstants.ATTRIBUTES;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.jooq.impl.DSL.field;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.oran.smo.teiv.utils.exposure.PaginationVerifierTestUtil.verifyResponse;
-import static org.jooq.impl.DSL.field;
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-
-class MapperUtilityTest {
-    private MapperUtility underTest;
-    private static PaginationMetaData paginationMetaData;
-
-    @BeforeEach
-    void setUp() throws SchemaLoaderException {
-        underTest = new MapperUtility();
-        SchemaLoader mockSchemaLoader = new MockSchemaLoader();
-        mockSchemaLoader.loadSchemaRegistry();
-        paginationMetaData = new PaginationMetaData();
-    }
-
-    @Test
-    void testMapEntity() {
-        final Result<Record> result = DSL.using(SQLDialect.POSTGRES).newResult();
-        result.add(DSL.using(SQLDialect.POSTGRES).newRecord(field("gNBDUId"), field("fdn"), field("dUpLMNId"), field(
-                "gNBId"), field("id"), field("gNBIdLength")).values(null, "GNBDUFunction/6653097A7B47B082BA96245354BB5BE7",
-                        Map.of("mcc", 456, "mnc", 82), "6653097A7B47B082BA96245354BB5BE7",
-                        "GNBDUFunction:6653097A7B47B082BA96245354BB5BE7", 2));
-        Assertions.assertEquals(generateResponse("GNBDUFunction", "6653097A7B47B082BA96245354BB5BE7"), underTest.mapEntity(
-                SchemaRegistry.getEntityTypeByName("GNBDUFunction"), result));
-    }
-
-    @Test
-    void testMapAllRelationships() {
-        final Result<Record> result = DSL.using(SQLDialect.POSTGRES).newResult();
-        result.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(
-                "ties_data.\"NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
-                        "ties_data.\"NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
-                                "ties_data.\"NRCellDU\".\"id\""), field(
-                                        "ties_data.\"NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\""))
-                .values("urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                        "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F", Collections.EMPTY_LIST));
-
-        Assertions.assertEquals(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F",
-                "urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.EMPTY_LIST))), underTest.mapRelationships(result, SchemaRegistry.getRelationTypeByName(
-                        "GNBDUFUNCTION_PROVIDES_NRCELLDU")));
-    }
-
-    @Test
-    void testMapRelationship() {
-        final Record record = DSL.using(SQLDialect.POSTGRES).newRecord(field(
-                "ties_data.\"NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
-                        "ties_data.\"NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
-                                "ties_data.\"NRCellDU\".\"id\""), field(
-                                        "ties_data.\"NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\""))
-                .values("urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                        "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F", Collections.EMPTY_LIST);
-
-        final Result result = DSL.using(SQLDialect.POSTGRES).newResult();
-        result.add(record);
-
-        Assertions.assertEquals(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F",
-                "urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                Collections.EMPTY_LIST))), underTest.mapRelationship(result, SchemaRegistry.getRelationTypeByName(
-                        "GNBDUFUNCTION_PROVIDES_NRCELLDU")));
-    }
-
-    @Test
-    void testMapComplexQuery() {
-        final Result<Record> records = DSL.using(SQLDialect.POSTGRES).newResult();
-
-        final String gNBDUName = String.format(TIES_DATA, "GNBDUFunction");
-        final String nRCellDUName = String.format(TIES_DATA, "NRCellDU");
-
-        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(gNBDUName + ".id"), field(gNBDUName + ".fdn"), field(
-                nRCellDUName + ".id")).values("9BCD297B8258F67908477D895636ED65",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91",
-                        null));
-        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(gNBDUName + ".id"), field(gNBDUName + ".fdn"), field(
-                nRCellDUName + ".id")).values(null, null, "98C3A4591A37718E1330F0294E23B62A"));
-
-        Map<String, Object> result = new HashMap<>();
-
-        result.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of(ATTRIBUTES, Map.of("fdn",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91"), "id",
-                "9BCD297B8258F67908477D895636ED65")), "o-ran-smo-teiv-ran:NRCellDU", List.of(Map.of("id",
-                        "98C3A4591A37718E1330F0294E23B62A")))));
-
-        try (MockedStatic<RequestContextHolder> requestContextHolderMockedStatic = Mockito.mockStatic(
-                RequestContextHolder.class)) {
-            requestContextHolderMockedStatic.when(RequestContextHolder::currentRequestAttributes).thenReturn(
-                    new ServletRequestAttributes(new MockHttpServletRequest()));
-            PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/pathTo/endPoint").offset(0).limit(5).build();
-            paginationDTO.setTotalSize(2);
-            result.putAll(paginationMetaData.getObjectList(paginationDTO));
-            verifyResponse(result, underTest.mapComplexQuery(records, paginationDTO));
-        }
-    }
-
-    @Test
-    void testMapComplexQuery_SingleEntity() {
-        final Result<Record> records = DSL.using(SQLDialect.POSTGRES).newResult();
-
-        final String gNBDUName = String.format(TIES_DATA, "GNBDUFunction");
-
-        records.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(gNBDUName + ".id"), field(gNBDUName + ".fdn")).values(
-                "9BCD297B8258F67908477D895636ED65",
-                "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91"));
-
-        Map<String, Object> reference = new HashMap<>();
-
-        reference.put("items", List.of(Map.of("o-ran-smo-teiv-ran:GNBDUFunction", List.of(Map.of("id",
-                "9BCD297B8258F67908477D895636ED65", ATTRIBUTES, Map.of("fdn",
-                        "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=91"))))));
-
-        try (MockedStatic<RequestContextHolder> requestContextHolderMockedStatic = Mockito.mockStatic(
-                RequestContextHolder.class)) {
-            requestContextHolderMockedStatic.when(RequestContextHolder::currentRequestAttributes).thenReturn(
-                    new ServletRequestAttributes(new MockHttpServletRequest()));
-            PageMetaData pageMetaDataSelf = new PageMetaData(PaginationDTO.builder().offset(0).limit(5).build());
-            reference.put("self", pageMetaDataSelf);
-            PaginationMetaData pmd = new PaginationMetaData();
-            PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/pathTo/endPoint").offset(0).limit(5).build();
-            paginationDTO.setTotalSize(0);
-            reference.putAll(pmd.getObjectList(paginationDTO));
-            verifyResponse(reference, underTest.mapComplexQuery(records, paginationDTO));
-
-        }
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaDataTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/PaginationMetaDataTest.java
deleted file mode 100644 (file)
index 3dccacc..0000000
+++ /dev/null
@@ -1,139 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.exposure.PaginationVerifierTestUtil.verifyResponse;
-
-public class PaginationMetaDataTest {
-
-    @Test
-    void testIsItFirst() {
-
-        Map<String, Object> result = new HashMap<>();
-        try (MockedStatic<RequestContextHolder> requestContextHolderMockedStatic = Mockito.mockStatic(
-                RequestContextHolder.class)) {
-            requestContextHolderMockedStatic.when(RequestContextHolder::currentRequestAttributes).thenReturn(
-                    new ServletRequestAttributes(new MockHttpServletRequest()));
-
-            PaginationMetaData paginationMetaData1 = new PaginationMetaData();
-            PageMetaData pageMetaDataSelf = new PageMetaData(0, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataNext = new PageMetaData(5, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataLast = new PageMetaData(50, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataPrev = new PageMetaData(0, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataFirst = new PageMetaData(0, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-
-            result.put("self", pageMetaDataSelf);
-            result.put("first", pageMetaDataFirst);
-            result.put("prev", pageMetaDataPrev);
-            result.put("next", pageMetaDataNext);
-            result.put("last", pageMetaDataLast);
-
-            final PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/pathTo/endPoint").offset(0).limit(5)
-                    .build();
-            paginationDTO.setTotalSize(55);
-            verifyResponse(result, paginationMetaData1.getObjectList(paginationDTO));
-        }
-    }
-
-    @Test
-    void testIsItLast() {
-
-        Map<String, Object> result = new HashMap<>();
-        try (MockedStatic<RequestContextHolder> requestContextHolderMockedStatic = Mockito.mockStatic(
-                RequestContextHolder.class)) {
-            requestContextHolderMockedStatic.when(RequestContextHolder::currentRequestAttributes).thenReturn(
-                    new ServletRequestAttributes(new MockHttpServletRequest()));
-
-            PaginationMetaData paginationMetaData1 = new PaginationMetaData();
-            PageMetaData pageMetaDataSelf = new PageMetaData(60, 10, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataNext = new PageMetaData(60, 10, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataLast = new PageMetaData(60, 10, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataPrev = new PageMetaData(50, 10, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataFirst = new PageMetaData(0, 10, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-
-            result.put("self", pageMetaDataSelf);
-            result.put("next", pageMetaDataNext);
-            result.put("last", pageMetaDataLast);
-            result.put("prev", pageMetaDataPrev);
-            result.put("first", pageMetaDataFirst);
-
-            final PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/pathTo/endPoint").offset(60).limit(10)
-                    .build();
-            paginationDTO.setTotalSize(70);
-            verifyResponse(result, paginationMetaData1.getObjectList(paginationDTO));
-        }
-    }
-
-    @Test
-    void testMiddleTable() {
-
-        Map<String, Object> result = new HashMap<>();
-        try (MockedStatic<RequestContextHolder> requestContextHolderMockedStatic = Mockito.mockStatic(
-                RequestContextHolder.class)) {
-            requestContextHolderMockedStatic.when(RequestContextHolder::currentRequestAttributes).thenReturn(
-                    new ServletRequestAttributes(new MockHttpServletRequest()));
-
-            PaginationMetaData paginationMetaData1 = new PaginationMetaData();
-            PageMetaData pageMetaDataSelf = new PageMetaData(10, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataPrev = new PageMetaData(5, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataNext = new PageMetaData(15, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataFirst = new PageMetaData(0, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-            PageMetaData pageMetaDataLast = new PageMetaData(65, 5, PaginationDTO.builder().basePath("/pathTo/endPoint")
-                    .build());
-
-            result.put("self", pageMetaDataSelf);
-            result.put("prev", pageMetaDataPrev);
-            result.put("next", pageMetaDataNext);
-            result.put("first", pageMetaDataFirst);
-            result.put("last", pageMetaDataLast);
-
-            final PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/pathTo/endPoint").offset(10).limit(5)
-                    .build();
-            paginationDTO.setTotalSize(70);
-            verifyResponse(result, paginationMetaData1.getObjectList(paginationDTO));
-        }
-    }
-}
index e8424f3..9e1ea94 100644 (file)
  */
 package org.oran.smo.teiv.exposure.spi.mapper;
 
-import org.oran.smo.teiv.schema.Association;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.Module;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
 import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
+import static org.jooq.impl.DSL.field;
+
+import java.util.List;
+import java.util.Map;
 
 import org.jooq.Record;
-import org.jooq.Result;
 import org.jooq.SQLDialect;
 import org.jooq.impl.DSL;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import java.util.List;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.jooq.impl.DSL.field;
+import org.oran.smo.teiv.exposure.spi.Module;
+import org.oran.smo.teiv.schema.Association;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 
 class RelationshipMapperTest {
     private static RelationshipMapper relationshipMapper;
@@ -53,35 +51,19 @@ class RelationshipMapperTest {
         relationType = RelationType.builder().name("GNBDUFUNCTION_PROVIDES_NRCELLDU").aSideAssociation(Association.builder()
                 .name("provided-nrCellDu").build()).aSide(EntityType.builder().name("GNBDUFUNCTION").build())
                 .bSideAssociation(Association.builder().name("provided-by-gnbduFunction").build()).bSide(EntityType
-                        .builder().name("NRCellDU").build()).relationshipStorageLocation(B_SIDE).module(Module.builder()
-                                .name("o-ran-smo-teiv-ran").build()).build();
-        relationshipMapper = new RelationshipMapper(relationType);
-    }
-
-    @Test
-    void testMap() {
-        final Result<Record> record = DSL.using(SQLDialect.POSTGRES).newResult();
-        record.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(
-                "ties_data.\"NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
-                        "ties_data.\"NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
-                                "ties_data.\"NRCellDU\".\"id\""), field(
-                                        "ties_data.\"NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\""))
-                .values("urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                        "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F", List.of("sid1", "sid2")));
-
-        Assertions.assertEquals(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F",
-                "urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                List.of("sid1", "sid2")))), relationshipMapper.map(record));
+                        .builder().name("NRCellDU").build()).relationshipStorageLocation(B_SIDE).tableName(
+                                "o-ran-smo-teiv-ran_NRCellDU").module(Module.builder().name("o-ran-smo-teiv-ran").build())
+                .build();
+        relationshipMapper = new RelationshipMapper();
     }
 
     @Test
     void testCreateProperties() {
         Record record = DSL.using(SQLDialect.POSTGRES).newRecord(field(
-                "ties_data.\"NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
-                        "ties_data.\"NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
-                                "ties_data.\"NRCellDU\".\"id\""), field(
-                                        "ties_data.\"NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\""))
+                "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
+                        "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
+                                "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"id\""), field(
+                                        "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\""))
                 .values("urn:base64:R05CRFVGdW5jdGlvbjo2QTBENUFBMjhGNzcwQzk5NDFCNzRFQkU1NzYxMUFFMTpQUk9WSURFUzpOUkNlbGxEVTowMDAxNjFCMDE0QzMyMDEwNkE5RDZCMTQxN0Y4RUIwQQ==",
                         "6A0D5AA28F770C9941B74EBE57611AE1", "000161B014C320106A9D6B1417F8EB0A", List.of("sid1", "sid2"));
 
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapperTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/spi/mapper/RelationshipsMapperTest.java
deleted file mode 100644 (file)
index f13100a..0000000
+++ /dev/null
@@ -1,75 +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 org.oran.smo.teiv.exposure.spi.mapper;
-
-import org.oran.smo.teiv.schema.Association;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.Module;
-import org.oran.smo.teiv.schema.RelationType;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
-
-import org.jooq.Record;
-import org.jooq.Result;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.ResponseGenerator.generateResponse;
-import static org.jooq.impl.DSL.field;
-
-class RelationshipsMapperTest {
-    private static RelationshipsMapper relationshipsMapper;
-
-    @BeforeAll
-    static void setUp() throws SchemaLoaderException {
-        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
-        mockSchemaLoader.loadSchemaRegistry();
-        RelationType relationType = RelationType.builder().name("GNBDUFUNCTION_PROVIDES_NRCELLDU").aSideAssociation(
-                Association.builder().name("provided-nrCellDu").build()).aSide(EntityType.builder().name("GNBDUFUNCTION")
-                        .build()).bSideAssociation(Association.builder().name("provided-by-gnbduFunction").build()).bSide(
-                                EntityType.builder().name("NRCellDU").build()).relationshipStorageLocation(B_SIDE).module(
-                                        Module.builder().name("o-ran-smo-teiv-ran").build()).build();
-        relationshipsMapper = new RelationshipsMapper(relationType);
-    }
-
-    @Test
-    void testMap() {
-        final Result<Record> record = DSL.using(SQLDialect.POSTGRES).newResult();
-        record.add(DSL.using(SQLDialect.POSTGRES).newRecord(field(
-                "ties_data.\"NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\""), field(
-                        "ties_data.\"NRCellDU\".\"REL_FK_provided-by-gnbduFunction\""), field(
-                                "ties_data.\"NRCellDU\".\"id\"")).values(
-                                        "urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==",
-                                        "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F"));
-
-        Assertions.assertEquals(Map.of("o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU", List.of(generateResponse(
-                "9BCD297B8258F67908477D895636ED65", "B480427E8A0C0B8D994E437784BB382F",
-                "urn:base64:R05CRFVGdW5jdGlvbjo5QkNEMjk3QjgyNThGNjc5MDg0NzdEODk1NjM2RUQ2NTpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg=="))),
-                relationshipsMapper.map(record));
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/DtoToJooqTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/DtoToJooqTest.java
new file mode 100644 (file)
index 0000000..456d244
--- /dev/null
@@ -0,0 +1,1214 @@
+/*
+ *  ============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.teiv.exposure.tiespath.innerlanguage;
+
+import static org.oran.smo.teiv.utils.TiesConstants.ITEM;
+import static org.jooq.impl.DSL.condition;
+import static org.jooq.impl.DSL.field;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.jooq.Condition;
+import org.jooq.Field;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.schema.DataType;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+
+class DtoToJooqTest {
+
+    private static final String GNBCUCP_FUNCTION = "GNBCUCPFunction";
+    private static final String GNBDU_FUNCTION = "GNBDUFunction";
+    private static final String ANTENNA_CAPABILITY = "AntennaCapability";
+    private static final String ANTENNA_MODULE = "AntennaModule";
+    private static final String MANAGED_ELEMENT = "ManagedElement";
+    private static final String NR_CELL_DU = "NRCellDU";
+
+    @BeforeAll
+    static void setUp() throws SchemaLoaderException {
+        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
+        mockSchemaLoader.loadSchemaRegistry();
+    }
+
+    @Test
+    void testConditions_relationIsNotNull() {
+        ScopeObject scopeObject1 = ScopeObject.builder(MANAGED_ELEMENT).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.RELATION).innerContainer(List.of("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"))
+                .queryFunction(QueryFunction.NOT_NULL).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.RELATION).innerContainer(List.of("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"))
+                .queryFunction(QueryFunction.NOT_NULL).build();
+
+        LogicalBlock lb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock lb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock olb1 = new OrLogicalBlock();
+        olb1.setChildren(List.of(lb1, lb2));
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION\" is not null\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION\" is not null\n")
+            .toString(), olb1.getCondition().toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_primitive() {
+        ScopeObject scopeObject1 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("nRPCI").queryFunction(QueryFunction.EQ).parameter("ABC789").dataType(
+                        DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("nRPCI").queryFunction(QueryFunction.CONTAINS).parameter("ABC789").dataType(
+                        DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("nRPCI").queryFunction(QueryFunction.NOT_NULL).dataType(DataType.PRIMITIVE)
+                .build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        AndOrLogicalBlock alb2 = new OrLogicalBlock();
+        alb2.setChildren(List.of(alb1, slb3));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"nRPCI\" = 'ABC789'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"nRPCI\" like (('%' || replace(\n" +
+                "    replace(\n" +
+                "      replace('ABC789', '!', '!!'),\n" +
+                "      '%',\n" +
+                "      '!%'\n" +
+                "    ),\n" +
+                "    '_',\n" +
+                "    '!_'\n" +
+                "  )) || '%') escape '!'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"nRPCI\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_bigint() {
+        ScopeObject scopeObject1 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("1").dataType(
+                        DataType.BIGINT).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("2").dataType(
+                        DataType.BIGINT).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb1.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"gNBId\" = 1\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"gNBId\" = 2\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_decimal() {
+        ScopeObject scopeObject1 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("decimalColumn").queryFunction(QueryFunction.EQ).parameter("2.5").dataType(
+                        DataType.DECIMAL).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("decimalColumn").queryFunction(QueryFunction.EQ).parameter("15.25").dataType(
+                        DataType.DECIMAL).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb1.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"decimalColumn\" = 2.5\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"decimalColumn\" = 15.25\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_geography() {
+        ScopeObject valid1 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "point(39.4019881 67.9419888)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject valid2 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881 67.9419888)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidContains = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.CONTAINS).parameter(
+                        "POINT(39.4019881 67.9419888)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidCoordinate0 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881 67.9419888 123.9878)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidCoordinate1 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidCoordinate2 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881 INVALID)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidCoordinate3 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881 67.9419888    123.9878)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidFormat1 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "(39.4019881 67.9419888)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidFormat2 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT39.4019881 67.9419888)").dataType(DataType.GEOGRAPHIC).build();
+
+        ScopeObject invalidFormat3 = ScopeObject.builder("AntennaModule").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("geoColumn").queryFunction(QueryFunction.EQ).parameter(
+                        "POINT(39.4019881 67.9419888").dataType(DataType.GEOGRAPHIC).build();
+
+        // spotless:off
+        assertEquals(condition("ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"geoColumn\" = st_geomfromtext('point(39.4019881 67.9419888)')")
+            .toString(), new ScopeLogicalBlock(valid1).getCondition().toString());
+        assertEquals(condition("ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"geoColumn\" = st_geomfromtext('POINT(39.4019881 67.9419888)')")
+            .toString(), new ScopeLogicalBlock(valid2).getCondition().toString());
+
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidContains)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidCoordinate0)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidCoordinate1)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidCoordinate2)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidCoordinate3)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidFormat1)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidFormat2)::getCondition);
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidFormat3)::getCondition);
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_containerObject() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId")).leaf("mnc").queryFunction(
+                        QueryFunction.EQ).parameter("789").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId")).leaf("mcc").queryFunction(
+                        QueryFunction.CONTAINS).parameter("456").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject invalidQueryFunction = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId")).leaf("mcc").queryFunction(
+                        QueryFunction.NOT_NULL).parameter("456").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb1.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"dUpLMNId\" -> 'mnc' = '\"789\"'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"dUpLMNId\" ->> 'mcc' like '%456%'\n")
+            .toString(), actualCondition.toString());
+
+        assertThrows(TiesPathException.class, new ScopeLogicalBlock(invalidQueryFunction)::getCondition);
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_containerObject_multipleElements() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId", "mcc")).leaf("mcca").queryFunction(
+                        QueryFunction.EQ).parameter("789").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject11 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId", "mcc")).leaf("mccb").queryFunction(
+                        QueryFunction.EQ).parameter("789").dataType(DataType.INTEGER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("dUpLMNId", "mcc")).leaf("mcca").queryFunction(
+                        QueryFunction.CONTAINS).parameter("789").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb11 = new ScopeLogicalBlock(scopeObject11);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb11));
+
+        AndOrLogicalBlock alb2 = new OrLogicalBlock();
+        alb2.setChildren(List.of(alb1, slb2));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"dUpLMNId\" -> 'mcc' -> 'mcca' = '\"789\"'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"dUpLMNId\" -> 'mcc' -> 'mccb' = '789'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"dUpLMNId\" -> 'mcc' ->> 'mcca' like '%789%'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_containerArray() {
+        ScopeObject scopeObject1 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("eUtranFqBands")).leaf(ITEM).queryFunction(
+                        QueryFunction.EQ).parameter("789").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject11 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("eUtranFqBands")).leaf(ITEM).queryFunction(
+                        QueryFunction.EQ).parameter("789").dataType(DataType.INTEGER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("eUtranFqBands")).leaf(ITEM).queryFunction(
+                        QueryFunction.CONTAINS).parameter("456").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb11 = new ScopeLogicalBlock(scopeObject11);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb11));
+
+        AndOrLogicalBlock alb2 = new OrLogicalBlock();
+        alb2.setChildren(List.of(alb1, slb2));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"eUtranFqBands\" @> '\"789\"')\n" +
+                "  or (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"eUtranFqBands\" @> '789')\n" +
+                "  or (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"eUtranFqBands\"::text like '%456%')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes_containerArray_multipleLevels() {
+        ScopeObject scopeObject1 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("jsonbColumn", "levelOneField",
+                        "levelTwoField")).leaf(ITEM).queryFunction(QueryFunction.EQ).parameter("456").dataType(
+                                DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("jsonbColumn", "levelOneField",
+                        "levelTwoField")).leaf(ITEM).queryFunction(QueryFunction.EQ).parameter("456").dataType(
+                                DataType.INTEGER).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).innerContainer(List.of("jsonbColumn", "levelOneField",
+                        "levelTwoField")).leaf(ITEM).queryFunction(QueryFunction.CONTAINS).parameter("456").dataType(
+                                DataType.INTEGER).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        AndOrLogicalBlock alb1 = new OrLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        AndOrLogicalBlock alb2 = new OrLogicalBlock();
+        alb2.setChildren(List.of(alb1, slb3));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"jsonbColumn\" -> 'levelOneField' -> 'levelTwoField' @> '\"456\"')\n" +
+                "  or (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"jsonbColumn\" -> 'levelOneField' -> 'levelTwoField' @> '456')\n" +
+                "  or (ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"jsonbColumn\" -> 'levelOneField' ->> 'levelTwoField'::text like '%456%')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAttributes() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("1").dataType(
+                        DataType.BIGINT).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ATTRIBUTES).leaf("decimalId").queryFunction(QueryFunction.EQ).parameter("2.5")
+                .dataType(DataType.DECIMAL).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).leaf("nRPCI").queryFunction(QueryFunction.CONTAINS).parameter("ABC789").dataType(
+                        DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject4 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ATTRIBUTES).innerContainer(List.of("pLMNId")).leaf("mnc").queryFunction(QueryFunction.EQ)
+                .parameter("789").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+        LogicalBlock slb4 = new ScopeLogicalBlock(scopeObject4);
+
+        AndOrLogicalBlock alb1 = new AndLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        AndOrLogicalBlock alb2 = new AndLogicalBlock();
+        alb2.setChildren(List.of(slb3, slb4));
+
+        AndOrLogicalBlock alb3 = new AndLogicalBlock();
+        alb3.setChildren(List.of(alb1, alb2));
+
+        Condition actualCondition = alb3.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"gNBId\" = 1\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"decimalId\" = 2.5\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"nRPCI\" like (('%' || replace(\n" +
+                "    replace(\n" +
+                "      replace('ABC789', '!', '!!'),\n" +
+                "      '%',\n" +
+                "      '!%'\n" +
+                "    ),\n" +
+                "    '_',\n" +
+                "    '!_'\n" +
+                "  )) || '%') escape '!'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"pLMNId\" -> 'mnc' = '\"789\"'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationshipAttributes() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ATTRIBUTES).leaf("rel_column1").queryFunction(
+                        QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ATTRIBUTES).leaf("rel_column2").queryFunction(
+                        QueryFunction.EQ).parameter("ABC789").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"rel_column1\" = 1\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"rel_column2\" = 'ABC789'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_undefinedAttributes_throws() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.UNDEFINED).container(ContainerType.ATTRIBUTES).leaf("rel_column1").queryFunction(
+                        QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+
+        assertThrows(TiesPathException.class, slb1::getCondition);
+    }
+
+    @Test
+    void testConditions_relation() {
+        ScopeObject scopeObject1 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRCELLDU")).queryFunction(
+                        QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEV").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("NRSectorCarrier").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"))
+                .queryFunction(QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEW").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER")).leaf(
+                        "id").queryFunction(QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEZ").dataType(
+                                DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        AndOrLogicalBlock alb1 = new AndLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+
+        AndOrLogicalBlock alb2 = new AndLogicalBlock();
+        alb2.setChildren(List.of(alb1, slb3));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\" = 'urn:base64:TWFuYWdlZEV'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" = 'urn:base64:TWFuYWdlZEW'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" = 'urn:base64:TWFuYWdlZEZ'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relation_throws() {
+        ScopeObject scopeObject1 = ScopeObject.builder("NOT_ENTITY").topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRCELLDU")).leaf("id")
+                .queryFunction(QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEZ").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("NOT_RELATION").topologyObjectType(TopologyObjectType.RELATION)
+                .container(ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRCELLDU")).leaf("id")
+                .queryFunction(QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEZ").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder("NOT_RELATION").topologyObjectType(TopologyObjectType.RELATION)
+                .container(ContainerType.RELATION).innerContainer(List.of("GNBDUFUNCTION_PROVIDES_NRCELLDU")).leaf("id")
+                .queryFunction(QueryFunction.CONTAINS).parameter("urn:base64:TWFuYWdlZEZ").dataType(DataType.PRIMITIVE)
+                .build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        assertThrows(TiesPathException.class, slb1::getCondition);
+        assertThrows(TiesPathException.class, slb2::getCondition);
+        assertThrows(TiesPathException.class, slb3::getCondition);
+    }
+
+    @Test
+    void testConditions_entityId() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.ID).queryFunction(QueryFunction.EQ).parameter("ABC123").dataType(
+                        DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(NR_CELL_DU).topologyObjectType(TopologyObjectType.ENTITY).container(
+                ContainerType.ID).queryFunction(QueryFunction.CONTAINS).parameter("DEF456").dataType(DataType.PRIMITIVE)
+                .build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" = 'ABC123'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"id\" like (('%' || replace(\n" +
+                "    replace(\n" +
+                "      replace('DEF456', '!', '!!'),\n" +
+                "      '%',\n" +
+                "      '!%'\n" +
+                "    ),\n" +
+                "    '_',\n" +
+                "    '!_'\n" +
+                "  )) || '%') escape '!'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationId() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ID).queryFunction(QueryFunction.EQ).parameter(
+                        "urn:base64:TWFuYWdlZEV").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ID).queryFunction(QueryFunction.CONTAINS).parameter(
+                        "urn:base64:TWFuYWdlZEW").dataType(DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\" = 'urn:base64:TWFuYWdlZEV'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" like (('%' || replace(\n" +
+                "    replace(\n" +
+                "      replace('urn:base64:TWFuYWdlZEW', '!', '!!'),\n" +
+                "      '%',\n" +
+                "      '!%'\n" +
+                "    ),\n" +
+                "    '_',\n" +
+                "    '!_'\n" +
+                "  )) || '%') escape '!'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationIdIsNotNull() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ID).queryFunction(QueryFunction.NOT_NULL).dataType(
+                        DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.ID).queryFunction(QueryFunction.NOT_NULL).dataType(
+                        DataType.PRIMITIVE).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU\" is not null\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_idThrows() {
+        ScopeLogicalBlock undefinedTOType = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU")
+                .topologyObjectType(TopologyObjectType.UNDEFINED).container(ContainerType.ID).queryFunction(
+                        QueryFunction.EQ).parameter("urn:base64:TWFuYWdlZEV").dataType(DataType.PRIMITIVE).build());
+
+        ScopeLogicalBlock invalidTopologyObjectType = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction")
+                .topologyObjectType(TopologyObjectType.UNDEFINED).container(ContainerType.ID).queryFunction(
+                        QueryFunction.NOT_NULL).parameter("urn:base64:TWFuYWdlZEV").dataType(DataType.PRIMITIVE).build());
+
+        assertThrows(TiesPathException.class, undefinedTOType::getCondition);
+        assertThrows(TiesPathException.class, invalidTopologyObjectType::getCondition);
+    }
+
+    @Test
+    void testConditions_entityAssociation_oneToMany1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ENodeBFunction").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_ENodeBFunction\".\"REL_FK_managed-by-managedElement\" = 'me1'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_FK_managed-by-managedElement\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_oneToMany2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder(MANAGED_ELEMENT).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-gnbduFunction")).leaf("id").queryFunction(QueryFunction.EQ).parameter("gnbdu1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder(MANAGED_ELEMENT).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-gnbcucpFunction")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_FK_managed-by-managedElement\" is not null\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" = 'gnbdu1'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBCUCPFunction\".\"REL_FK_managed-by-managedElement\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToOne1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_MODULE).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of("installed-at-site"))
+                .leaf("id").queryFunction(QueryFunction.EQ).parameter("site1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_MODULE).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of("installed-at-site"))
+                .leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null).build());
+
+        AndOrLogicalBlock alb = new OrLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" = 'site1'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToOne2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("Site").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "installed-antennaModule")).leaf("id").queryFunction(QueryFunction.EQ).parameter("am1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("Site").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "installed-antennaModule")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new OrLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (\n" +
+                "    ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n" +
+                "    and ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"id\" = 'am1'\n" +
+                "  )\n" +
+                "  or ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToOne1Contains() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("Site").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "installed-antennaModule")).leaf("id").queryFunction(QueryFunction.CONTAINS).parameter("am1")
+                .build());
+
+        Condition actualCondition = scopeObject1.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n" +
+                "and ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"id\" like (" +
+                "('%' || replace(" + "\n"+
+                "replace(" + "\n"+
+                "replace('am1', '!', '!!')," + "\n"+
+                "'%'," + "\n"+
+                "'!%'" + "\n"+
+                ")," + "\n"+
+                "'_'," + "\n"+
+                "'!_'" + "\n"+
+                ")) || '%') escape '!'" + "\n")
+            .toString().replace(" ", ""), actualCondition.toString().replace(" ", ""));
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToMany1Contains() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_MODULE).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serviced-antennaCapability")).leaf("id").queryFunction(QueryFunction.CONTAINS).parameter("ac1")
+                .build());
+
+        Condition actualCondition = scopeObject1.getCondition();
+        // spotless:off
+        assertEquals(("ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\"" +
+            ".\"bSide_AntennaCapability\"like(('%'||replace(" + "\n"+
+            "replace(" + "\n"+
+            "replace('ac1','!','!!')," + "\n"+
+            "'%'," + "\n"+
+            "'!%'" + "\n"+
+            ")," + "\n"+
+            "'_'," + "\n"+
+            "'!_'" + "\n"+
+            "))||'%')escape'!'")
+            .replace(" ", ""), actualCondition.toString().replace(" ", ""));
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_oneToMany1Contains() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ENodeBFunction").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.CONTAINS).parameter("me1")
+                .build());
+
+        Condition actualCondition = scopeObject1.getCondition();
+        // spotless:off
+        assertEquals(
+            ("ties_data.\"o-ran-smo-teiv-ran_ENodeBFunction\".\"REL_FK_managed-by-managedElement\"like(('%'||replace(" + "\n" +
+                "replace(" +"\n"+
+                "replace('me1','!','!!')," + "\n" +
+                "'%'," + "\n" +
+                "'!%'" + "\n" +
+                ")," + "\n" +
+                "'_'," + "\n" +
+                "'!_'" + "\n" +
+                "))||'%')escape'!'"
+            ).replace(" ", ""), actualCondition.toString().replace(" ", ""));
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToMany1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_MODULE).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serviced-antennaCapability")).leaf("id").queryFunction(QueryFunction.EQ).parameter("ac1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_MODULE).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serviced-antennaCapability")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".\"bSide_AntennaCapability\" = 'ac1'\n" +
+                "  and ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".id is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_manyToMany2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serving-antennaModule")).leaf("id").queryFunction(QueryFunction.EQ).parameter("am1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder(ANTENNA_CAPABILITY).topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serving-antennaModule")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null).build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".\"aSide_AntennaModule\" = 'am1'\n" +
+                "  and ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".id is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_oneToMany1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("managed-by-managedElement")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_ENodeBFunction\".\"REL_FK_managed-by-managedElement\" = 'me1'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_FK_managed-by-managedElement\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_oneToMany2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("managed-enodebFunction")).leaf("id").queryFunction(QueryFunction.EQ).parameter("enbf1")
+                .build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("managed-by-managedElement")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_ENodeBFunction\".\"REL_FK_managed-by-managedElement\" is not null\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_ENodeBFunction\".\"id\" = 'enbf1'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"REL_FK_managed-by-managedElement\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_manyToOne1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_INSTALLED_AT_SITE")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("installed-at-site")).leaf("id").queryFunction(QueryFunction.EQ).parameter("site1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_INSTALLED_AT_SITE")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("installed-at-site")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null).build());
+
+        AndOrLogicalBlock alb = new OrLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" = 'site1'\n" +
+                "  or ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_manyToOne2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_INSTALLED_AT_SITE")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("installed-antennaModule")).leaf("id").queryFunction(QueryFunction.EQ).parameter("am1")
+                .build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_INSTALLED_AT_SITE")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("installed-antennaModule")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new OrLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (\n" +
+                "    ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n" +
+                "    and ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"id\" = 'am1'\n" +
+                "  )\n" +
+                "  or ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\".\"REL_FK_installed-at-site\" is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_manyToMany1() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_SERVES_ANTENNACAPABILITY")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("serviced-antennaCapability")).leaf("id").queryFunction(QueryFunction.EQ).parameter("ac1")
+                .build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_SERVES_ANTENNACAPABILITY")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("serviced-antennaCapability")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".\"bSide_AntennaCapability\" = 'ac1'\n" +
+                "  and ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".id is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationAssociation_manyToMany2() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_SERVES_ANTENNACAPABILITY")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("serving-antennaModule")).leaf("id").queryFunction(QueryFunction.EQ).parameter("am1").build());
+
+        ScopeLogicalBlock scopeObject2 = new ScopeLogicalBlock(ScopeObject.builder("ANTENNAMODULE_SERVES_ANTENNACAPABILITY")
+                .topologyObjectType(TopologyObjectType.RELATION).container(ContainerType.ASSOCIATION).innerContainer(List
+                        .of("serving-antennaModule")).leaf(null).queryFunction(QueryFunction.NOT_NULL).parameter(null)
+                .build());
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(scopeObject1, scopeObject2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".\"aSide_AntennaModule\" = 'am1'\n" +
+                "  and ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".id is not null\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityAssociation_throws() {
+        ScopeLogicalBlock scopeObject1 = new ScopeLogicalBlock(ScopeObject.builder("CloudNativeApplication").container(
+                ContainerType.ASSOCIATION).innerContainer(List.of("realised-gnbduFunction")).leaf("id").queryFunction(
+                        QueryFunction.CONTAINS).parameter("gnbdu1").build());
+        assertThrows(TiesPathException.class, scopeObject1::getCondition);
+    }
+
+    @Test
+    void testConditions_entityClassifiers() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.CLASSIFIERS).leaf(ITEM).queryFunction(QueryFunction.CONTAINS).parameter(
+                        "gnbdu-function-model:Ru").dataType(DataType.CONTAINER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBCUCP_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.CLASSIFIERS).leaf(ITEM).queryFunction(QueryFunction.EQ).parameter(
+                        "gnbcucp-function-model:Weekend").dataType(DataType.CONTAINER).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"CD_classifiers\"::text like '%gnbdu-function-model:Ru%')\n" +
+                "  and (ties_data.\"o-ran-smo-teiv-ran_GNBCUCPFunction\".\"CD_classifiers\" @> '\"gnbcucp-function-model:Weekend\"')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationshipClassifiers() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.CLASSIFIERS).leaf(ITEM).queryFunction(
+                        QueryFunction.CONTAINS).parameter("gnbdu-function-model:Ru").dataType(DataType.CONTAINER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.CLASSIFIERS).leaf(ITEM).queryFunction(QueryFunction.EQ)
+                .parameter("gnbcucp-function-model:Weekend").dataType(DataType.CONTAINER).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU\"::text like '%gnbdu-function-model:Ru%')\n" +
+                "  and (ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" @> '\"gnbcucp-function-model:Weekend\"')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entitySourceIds() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.SOURCE_IDS).leaf(ITEM).queryFunction(QueryFunction.CONTAINS).parameter(
+                        "urn:cmHandle:").dataType(DataType.CONTAINER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBCUCP_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.SOURCE_IDS).leaf(ITEM).queryFunction(QueryFunction.EQ).parameter(
+                        "urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16")
+                .dataType(DataType.CONTAINER).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"CD_sourceIds\"::text like '%urn:cmHandle:%')\n" +
+                "  and (ties_data.\"o-ran-smo-teiv-ran_GNBCUCPFunction\".\"CD_sourceIds\" @> '\"urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16\"')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationshipSourceIds() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.SOURCE_IDS).leaf(ITEM).queryFunction(
+                        QueryFunction.CONTAINS).parameter("urn:cmHandle:").dataType(DataType.CONTAINER).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.SOURCE_IDS).leaf(ITEM).queryFunction(QueryFunction.EQ)
+                .parameter(
+                        "urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16")
+                .dataType(DataType.CONTAINER).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+
+        AndOrLogicalBlock alb = new AndLogicalBlock();
+        alb.setChildren(List.of(slb1, slb2));
+
+        Condition actualCondition = alb.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  (ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU\"::text like '%urn:cmHandle:%')\n" +
+                "  and (ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" @> '\"urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16\"')\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_entityDecorators() {
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.DECORATORS).leaf("gnbdu-function-model:location").queryFunction(
+                        QueryFunction.CONTAINS).parameter("Stock").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBCUCP_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.DECORATORS).leaf("gnbdu-function-model:stringdata").queryFunction(QueryFunction.EQ)
+                .parameter("ASD").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder(GNBCUCP_FUNCTION).topologyObjectType(TopologyObjectType.ENTITY)
+                .container(ContainerType.DECORATORS).leaf("gnbdu-function-model:intdata").queryFunction(QueryFunction.EQ)
+                .parameter("2").dataType(DataType.BIGINT).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        AndOrLogicalBlock alb1 = new AndLogicalBlock();
+        AndOrLogicalBlock alb2 = new AndLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+        alb2.setChildren(List.of(alb1, slb3));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"CD_decorators\" ->> 'gnbdu-function-model:location' like '%Stock%'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBCUCPFunction\".\"CD_decorators\" -> 'gnbdu-function-model:stringdata' = '\"ASD\"'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_GNBCUCPFunction\".\"CD_decorators\" -> 'gnbdu-function-model:intdata' = '2'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testConditions_relationshipDecorators() {
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.DECORATORS).leaf("gnbdu-function-model:location")
+                .queryFunction(QueryFunction.CONTAINS).parameter("Stock").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.DECORATORS).leaf("gnbdu-function-model:stringdata")
+                .queryFunction(QueryFunction.EQ).parameter("ASD").dataType(DataType.PRIMITIVE).build();
+
+        ScopeObject scopeObject3 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").topologyObjectType(
+                TopologyObjectType.RELATION).container(ContainerType.DECORATORS).leaf("gnbdu-function-model:intdata")
+                .queryFunction(QueryFunction.EQ).parameter("2").dataType(DataType.BIGINT).build();
+
+        LogicalBlock slb1 = new ScopeLogicalBlock(scopeObject1);
+        LogicalBlock slb2 = new ScopeLogicalBlock(scopeObject2);
+        LogicalBlock slb3 = new ScopeLogicalBlock(scopeObject3);
+
+        AndOrLogicalBlock alb1 = new AndLogicalBlock();
+        AndOrLogicalBlock alb2 = new AndLogicalBlock();
+        alb1.setChildren(List.of(slb1, slb2));
+        alb2.setChildren(List.of(alb1, slb3));
+
+        Condition actualCondition = alb2.getCondition();
+        // spotless:off
+        assertEquals(condition(
+            "\n" +
+                "  ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU\" ->> 'gnbdu-function-model:location' like '%Stock%'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" -> 'gnbdu-function-model:stringdata' = '\"ASD\"'\n" +
+                "  and ties_data.\"o-ran-smo-teiv-ran_NRSectorCarrier\".\"REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER\" -> 'gnbdu-function-model:intdata' = '2'\n")
+            .toString(), actualCondition.toString());
+        // spotless:on
+    }
+
+    @Test
+    void testGetJoinCondition() {
+        LogicalBlock slb1 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of("provided-nrCellDu"))
+                .build());
+
+        InnerFilterCriteria innerFilterCriteria1 = InnerFilterCriteria.builder().scope(slb1).build();
+
+        Pair<String, Field> pair1 = new ImmutablePair<>("ties_data.\"o-ran-smo-teiv-ran_NRCellDU\"", field(
+                "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\".\"REL_FK_provided-by-gnbduFunction\"" + "=" + "ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\""));
+
+        Assertions.assertEquals(new HashSet(Arrays.asList(pair1)), innerFilterCriteria1.builder().scope(slb1).build()
+                .getJoinCondition());
+
+        LogicalBlock slb2 = new ScopeLogicalBlock(ScopeObject.builder("AntennaCapability").topologyObjectType(
+                TopologyObjectType.ENTITY).container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "serving-antennaModule")).build());
+
+        InnerFilterCriteria innerFilterCriteria2 = InnerFilterCriteria.builder().scope(slb2).build();
+
+        Pair<String, Field> pair2 = new ImmutablePair<>("ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\"", field(
+                "ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\".\"bSide_AntennaCapability\"" + "=" + "ties_data.\"o-ran-smo-teiv-ran_AntennaCapability\".\"id\""));
+
+        Assertions.assertEquals(new HashSet(Arrays.asList(pair2)), innerFilterCriteria2.builder().scope(slb2).build()
+                .getJoinCondition());
+    }
+}
index ba35f10..bcfd4bb 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.innerlanguage;
 
-import java.util.Arrays;
+import static org.jooq.impl.DSL.condition;
+import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.table;
+
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.jooq.SelectField;
+import org.jooq.Table;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataValidator;
+import org.oran.smo.teiv.exposure.tiespath.refiner.BasePathRefinement;
+import org.oran.smo.teiv.exposure.tiespath.resolver.ScopeResolver;
+import org.oran.smo.teiv.exposure.tiespath.resolver.TargetResolver;
 import org.oran.smo.teiv.schema.DataType;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 
 class FilterCriteriaTest {
+
+    private static BasePathRefinement basePathRefinement;
+    private static ConsumerDataValidator consumerDataValidator;
+    private final TargetResolver targetResolver = new TargetResolver();
+    private final ScopeResolver scopeResolver = new ScopeResolver();
+
+    @BeforeAll
+    static void setUp() throws SchemaLoaderException {
+        new MockSchemaLoader().loadSchemaRegistry();
+        basePathRefinement = new BasePathRefinement(consumerDataValidator);
+    }
+
     @Test
     void testFilterCriteria() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        TargetObject targetObject = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).params(List
-                .of("gNBId")).build();
-        filterCriteria.setTargets(List.of(targetObject));
-        ScopeObject scopeObject = new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES, "gNBIDLength",
-                QueryFunction.EQ, "1", DataType.BIGINT);
-        ScopeLogicalBlock logicalBlock = new ScopeLogicalBlock(scopeObject);
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(null, null);
+        List<TargetObject> targetObjects = targetResolver.resolve("GNBDUFunction", "/attributes(gNBId)");
+        filterCriteria.setTargets(targetObjects);
+        LogicalBlock logicalBlock = scopeResolver.resolve("GNBDUFunction", "/attributes[@gNBIdLength=1]");
         filterCriteria.setScope(logicalBlock);
-
         Assertions.assertEquals(1, filterCriteria.getTargets().size());
-        Assertions.assertEquals("RAN_LOGICAL", filterCriteria.getDomain());
         Assertions.assertEquals(QueryFunction.EQ, ((ScopeLogicalBlock) filterCriteria.getScope()).getScopeObject()
                 .getQueryFunction());
+        Assertions.assertEquals("gNBIdLength", ((ScopeLogicalBlock) filterCriteria.getScope()).getScopeObject().getLeaf());
+        Assertions.assertEquals(ContainerType.ATTRIBUTES, ((ScopeLogicalBlock) filterCriteria.getScope()).getScopeObject()
+                .getContainer());
+
     }
 
     @Test
     void testGetTables() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        TargetObject targetObject = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).params(List
-                .of("gNBId", "gNBIdLength")).build();
-        filterCriteria.setTargets(Arrays.asList(targetObject));
-        OrLogicalBlock orLogicalBlock = new OrLogicalBlock();
-        ScopeObject scopeObject1 = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBIdLength",
-                QueryFunction.EQ, "1", DataType.BIGINT);
-        ScopeObject scopeObject2 = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBId", QueryFunction.EQ,
-                "8", DataType.BIGINT);
-        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(scopeObject1);
-        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(scopeObject2);
-        orLogicalBlock.setChildren(Arrays.asList(scopeLogicalBlock1, scopeLogicalBlock2));
-        filterCriteria.setScope(orLogicalBlock);
-
-        Set<SelectField> expected = new HashSet<>();
-        expected.add(null);
-        Assertions.assertEquals(expected, filterCriteria.getTables());
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(null, null);
+        List<TargetObject> targetObjects = targetResolver.resolve("GNBDUFunction", "/attributes(gNBId,gNBIdLength)");
+        filterCriteria.setTargets(targetObjects);
+        targetObjects.get(0).setTopologyObjectType(TopologyObjectType.ENTITY);
+        LogicalBlock logicalBlock = scopeResolver.resolve("GNBDUFunction", "/attributes[@gNBIdLength=1 or @gNBId=8]");
+        ((OrLogicalBlock) logicalBlock).getChildren().forEach(l -> ((ScopeLogicalBlock) l).getScopeObject()
+                .setTopologyObjectType(TopologyObjectType.ENTITY));
+        filterCriteria.setScope(logicalBlock);
+        basePathRefinement.resolveUndefinedTopologyObjectTypes(FilterCriteria.builder("RAN").filterCriteriaList(List.of(
+                filterCriteria)).build());
+
+        Set<Table> result = new HashSet<>();
+        result.add(table("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\""));
+
+        Assertions.assertEquals(result, filterCriteria.getTables());
+
+        InnerFilterCriteria filterCriteria2 = new InnerFilterCriteria(null, null);
+        List<TargetObject> targetObjects2 = targetResolver.resolve("GNBDUFUNCTION_PROVIDES_NRCELLDU", null);
+        filterCriteria2.setTargets(targetObjects2);
+        LogicalBlock logicalBlock2 = scopeResolver.resolve("NRCellDU", "/attributes[@nCI=12]");
+        filterCriteria2.setScope(logicalBlock2);
+        basePathRefinement.resolveUndefinedTopologyObjectTypes(FilterCriteria.builder("RAN").filterCriteriaList(List.of(
+                filterCriteria2)).build());
+
+        result.clear();
+
+        result.add(table("ties_data.\"o-ran-smo-teiv-ran_NRCellDU\""));
+
+        Assertions.assertEquals(result, filterCriteria2.getTables());
+
+        InnerFilterCriteria filterCriteria3 = new InnerFilterCriteria(null, null);
+        List<TargetObject> targetObjects3 = targetResolver.resolve("GNBDUFunction", "/attributes(gNBId,gNBIdLength)");
+        filterCriteria3.setTargets(targetObjects3);
+        LogicalBlock logicalBlock3 = scopeResolver.resolve("GNBDUFunction", "/attributes[@gNBIdLength=1 or @gNBId=8]");
+        filterCriteria3.setScope(logicalBlock3);
+
+        Assertions.assertThrows(TiesException.class, filterCriteria3::getTables);
+
     }
 
     @Test
     void testGetSelects() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-
-        TargetObject targetObject = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).params(List
-                .of("gNBId", "gNBIdLength")).build();
-        filterCriteria.setTargets(Arrays.asList(targetObject));
-
-        Set<SelectField> expected = new HashSet<>();
-        expected.add(null);
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(null, null);
+        List<TargetObject> targetObjects = targetResolver.resolve("GNBDUFunction", "/attributes(gNBId,gNBIdLength)");
+        targetObjects.get(0).setTopologyObjectType(TopologyObjectType.ENTITY);
+        filterCriteria.setTargets(targetObjects);
+        Map<SelectField, Map<SelectField, DataType>> expected = new HashMap<>();
+        expected.put(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), new HashMap<>());
+        expected.get(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id")).put(field(
+                        "ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"gNBId\"").as(
+                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), DataType.BIGINT);
+        expected.get(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id")).put(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\"")
+                        .as("o-ran-smo-teiv-ran:GNBDUFunction.id"), DataType.PRIMITIVE);
+        expected.get(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id")).put(field(
+                        "ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"gNBIdLength\"").as(
+                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBIdLength"), DataType.INTEGER);
         Assertions.assertEquals(expected, filterCriteria.getSelects());
     }
 
     @Test
     void testGetCondition() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        ScopeObject scopeObject = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, QueryFunction.EQ, "1",
-                DataType.BIGINT);
-        ScopeLogicalBlock scopeLogicalBlock = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scopeLogicalBlock);
-
-        Assertions.assertEquals(null, filterCriteria.getCondition());
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(null, null);
+        LogicalBlock logicalBlock = scopeResolver.resolve("GNBDUFunction", "/attributes[@gNBIdLength=1]");
+        filterCriteria.setScope(logicalBlock);
+        filterCriteria.setTargets(List.of());
+        basePathRefinement.resolveUndefinedTopologyObjectTypes(FilterCriteria.builder("RAN").filterCriteriaList(List.of(
+                filterCriteria)).build());
+        basePathRefinement.validateScopeParametersDataType(FilterCriteria.builder("RAN").filterCriteriaList(List.of(
+                filterCriteria)).build());
+        Assertions.assertEquals(condition(field("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"gNBIdLength\"").eq(1))
+                .toString(), filterCriteria.getCondition().toString());
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ScopeLogicalBlockTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/ScopeLogicalBlockTest.java
new file mode 100644 (file)
index 0000000..fdba4e9
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *  ============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.teiv.exposure.tiespath.innerlanguage;
+
+import static org.jooq.impl.DSL.table;
+import static org.junit.Assert.assertThrows;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jooq.Table;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.schema.DataType;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+
+class ScopeLogicalBlockTest {
+
+    @BeforeAll
+    static void setUp() throws SchemaLoaderException {
+        SchemaLoader mockedSchemaLoader = new MockSchemaLoader();
+        mockedSchemaLoader.loadSchemaRegistry();
+    }
+
+    @Test
+    void testGetTables() {
+
+        Set<Table> resultTables = new HashSet<>();
+
+        ScopeObject scopeObject = ScopeObject.builder("GNBDUFunction").container(ContainerType.ASSOCIATION).leaf("id")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+        scopeObject.setInnerContainer(Arrays.asList("provided-nrCellDu"));
+        scopeObject.setTopologyObjectType(TopologyObjectType.ENTITY);
+
+        ScopeObject scopeObject1 = ScopeObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).leaf(
+                "gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.INTEGER).build();
+        scopeObject1.setTopologyObjectType(TopologyObjectType.ENTITY);
+
+        ScopeObject scopeObject2 = ScopeObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("8").dataType(DataType.BIGINT).build();
+        scopeObject2.setTopologyObjectType(TopologyObjectType.ENTITY);
+
+        ScopeObject scopeObject3 = ScopeObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+        scopeObject3.setTopologyObjectType(TopologyObjectType.UNDEFINED);
+
+        ScopeObject scopeObject4 = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").container(ContainerType.ID)
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.PRIMITIVE).build();
+        scopeObject4.setTopologyObjectType(TopologyObjectType.RELATION);
+
+        ScopeObject scopeObject5 = ScopeObject.builder("GNBDUFunction").container(ContainerType.ASSOCIATION).leaf("id")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+        scopeObject5.setInnerContainer(Arrays.asList("managed-by-managedElement"));
+        scopeObject5.setTopologyObjectType(TopologyObjectType.ENTITY);
+
+        ScopeObject scopeObject6 = ScopeObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION").container(
+                ContainerType.ASSOCIATION).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1").dataType(
+                        DataType.PRIMITIVE).build();
+        scopeObject6.setInnerContainer(Arrays.asList("managed-by-managedElement"));
+        scopeObject6.setTopologyObjectType(TopologyObjectType.RELATION);
+
+        ScopeObject scopeObject7 = ScopeObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION").container(
+                ContainerType.ASSOCIATION).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1").dataType(
+                        DataType.PRIMITIVE).build();
+        scopeObject7.setInnerContainer(Arrays.asList("provided-by-gnbduFunction"));
+        scopeObject7.setTopologyObjectType(TopologyObjectType.RELATION);
+
+        ScopeLogicalBlock scopeLogicalBlock = new ScopeLogicalBlock(scopeObject);
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(scopeObject1);
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(scopeObject2);
+        ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(scopeObject3);
+        ScopeLogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(scopeObject4);
+        ScopeLogicalBlock scopeLogicalBlock5 = new ScopeLogicalBlock(scopeObject5);
+        ScopeLogicalBlock scopeLogicalBlock6 = new ScopeLogicalBlock(scopeObject6);
+        ScopeLogicalBlock scopeLogicalBlock7 = new ScopeLogicalBlock(scopeObject7);
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_NRCellDU\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock.getTables());
+        resultTables.clear();
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock1.getTables());
+        resultTables.clear();
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock2.getTables());
+        resultTables.clear();
+
+        assertThrows(TiesException.class, scopeLogicalBlock3::getTables);
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_NRCellDU\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock4.getTables());
+        resultTables.clear();
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock5.getTables());
+        resultTables.clear();
+
+        resultTables.add(table("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\""));
+        Assertions.assertEquals(resultTables, scopeLogicalBlock6.getTables());
+        resultTables.clear();
+
+        Assertions.assertThrows(TiesException.class, () -> scopeLogicalBlock7.getTables());
+    }
+
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/SelectBlockTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/innerlanguage/SelectBlockTest.java
new file mode 100644 (file)
index 0000000..d10e277
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  ============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.teiv.exposure.tiespath.innerlanguage;
+
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
+import static org.oran.smo.teiv.schema.DataType.*;
+import static org.jooq.impl.DSL.field;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+
+public class SelectBlockTest {
+
+    @BeforeAll
+    static void setup() throws SchemaLoaderException {
+        new MockSchemaLoader().loadSchemaRegistry();
+    }
+
+    @Test
+    void idInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.ID).topologyObjectType(
+                TopologyObjectType.ENTITY).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE)), filterCriteria.getSelects());
+    }
+
+    @Test
+    void attributesInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of("gNBDUId", "dUpLMNId")).container(
+                ContainerType.ATTRIBUTES).topologyObjectType(TopologyObjectType.ENTITY).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE, field("ties_data.\"GNBDUFunction\".\"gNBDUId\"")
+                                .as("o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId"), BIGINT, field(
+                                        "ties_data.\"GNBDUFunction\".\"dUpLMNId\"").as(
+                                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.dUpLMNId"), CONTAINER)),
+                filterCriteria.getSelects());
+    }
+
+    @Test
+    void allAttributesInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.ATTRIBUTES)
+                .topologyObjectType(TopologyObjectType.ENTITY).isAllParamQueried(true).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE, field("ties_data.\"GNBDUFunction\".\"gNBId\"")
+                                .as("o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), BIGINT, field(
+                                        "ties_data.\"GNBDUFunction\".\"gNBIdLength\"").as(
+                                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBIdLength"), INTEGER, field(
+                                                        "ties_data.\"GNBDUFunction\".\"dUpLMNId\"").as(
+                                                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.dUpLMNId"),
+                        CONTAINER, field("ties_data.\"GNBDUFunction\".\"gNBDUId\"").as(
+                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId"), BIGINT)), filterCriteria.getSelects());
+    }
+
+    @Test
+    void decoratorsInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.DECORATORS)
+                .topologyObjectType(TopologyObjectType.ENTITY).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE, field(
+                                "ties_data.\"GNBDUFunction\".\"CD_decorators\"").as(
+                                        "o-ran-smo-teiv-ran:GNBDUFunction.decorators"), CONTAINER)), filterCriteria
+                                                .getSelects());
+    }
+
+    @Test
+    void classifiersInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.CLASSIFIERS)
+                .topologyObjectType(TopologyObjectType.ENTITY).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE, field(
+                                "ties_data.\"GNBDUFunction\".\"CD_classifiers\"").as(
+                                        "o-ran-smo-teiv-ran:GNBDUFunction.classifiers"), CONTAINER)), filterCriteria
+                                                .getSelects());
+    }
+
+    @Test
+    void sourceIdInEntity() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.SOURCE_IDS)
+                .topologyObjectType(TopologyObjectType.ENTITY).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.id"), Map.of(field("ties_data.\"GNBDUFunction\".\"id\"").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), PRIMITIVE, field(
+                                "ties_data.\"GNBDUFunction\".\"CD_sourceIds\"").as(
+                                        "o-ran-smo-teiv-ran:GNBDUFunction.sourceIds"), CONTAINER)), filterCriteria
+                                                .getSelects());
+    }
+
+    @Test
+    void idInRelationship() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("SECTOR_GROUPS_ANTENNAMODULE").params(List.of()).container(ContainerType.ID)
+                .topologyObjectType(TopologyObjectType.RELATION).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                hashAlias("o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), Map.of(field(
+                        "ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"REL_FK_grouped-by-sector\"").as(hashAlias(
+                                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.aSide")),
+                        PRIMITIVE, field("ties_data.\"AntennaModule\".\"id\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.bSide")), PRIMITIVE)),
+                filterCriteria.getSelects());
+    }
+
+    @Test
+    void decoratorsInRelationship() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("SECTOR_GROUPS_ANTENNAMODULE").params(List.of()).container(
+                ContainerType.DECORATORS).topologyObjectType(TopologyObjectType.RELATION).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                hashAlias("o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), Map.of(field(
+                        "ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                                                hashAlias(
+                                                        "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.decorators")),
+                        CONTAINER, field("ties_data.\"AntennaModule\".\"REL_FK_grouped-by-sector\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.aSide")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"id\"").as(hashAlias(
+                                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.bSide")),
+                        PRIMITIVE)), filterCriteria.getSelects());
+    }
+
+    @Test
+    void classifiersInRelationship() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("SECTOR_GROUPS_ANTENNAMODULE").params(List.of()).container(
+                ContainerType.CLASSIFIERS).topologyObjectType(TopologyObjectType.RELATION).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                hashAlias("o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), Map.of(field(
+                        "ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE\"")
+                                                .as(hashAlias(
+                                                        "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.classifiers")),
+                        CONTAINER, field("ties_data.\"AntennaModule\".\"REL_FK_grouped-by-sector\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.aSide")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"id\"").as(hashAlias(
+                                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.bSide")),
+                        PRIMITIVE)), filterCriteria.getSelects());
+    }
+
+    @Test
+    void sourceIdInRelationship() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("SECTOR_GROUPS_ANTENNAMODULE").params(List.of()).container(
+                ContainerType.SOURCE_IDS).topologyObjectType(TopologyObjectType.RELATION).build());
+
+        Assertions.assertEquals(Map.of(field("ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                hashAlias("o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), Map.of(field(
+                        "ties_data.\"AntennaModule\".\"REL_ID_SECTOR_GROUPS_ANTENNAMODULE\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.id")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE\"").as(
+                                                hashAlias(
+                                                        "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.sourceIds")),
+                        CONTAINER, field("ties_data.\"AntennaModule\".\"REL_FK_grouped-by-sector\"").as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.aSide")), PRIMITIVE, field(
+                                        "ties_data.\"AntennaModule\".\"id\"").as(hashAlias(
+                                                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE.bSide")),
+                        PRIMITIVE)), filterCriteria.getSelects());
+    }
+
+    @Test
+    void wrongTopologyObjectType() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.CLASSIFIERS)
+                .topologyObjectType(TopologyObjectType.UNDEFINED).build());
+
+        Assertions.assertThrowsExactly(TiesException.class, filterCriteria::getSelects);
+    }
+
+    @Test
+    void wrongContainerType() {
+        List<TargetObject> targets = new ArrayList<>();
+        InnerFilterCriteria filterCriteria = new InnerFilterCriteria(targets, null);
+
+        targets.add(TargetObject.builder("GNBDUFunction").params(List.of()).container(ContainerType.ASSOCIATION)
+                .topologyObjectType(TopologyObjectType.ENTITY).build());
+
+        Assertions.assertThrowsExactly(TiesException.class, filterCriteria::getSelects);
+    }
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapperTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/refiner/AliasMapperTest.java
new file mode 100644 (file)
index 0000000..d83c1c7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  ============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.teiv.exposure.tiespath.refiner;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class AliasMapperTest {
+
+    @Test
+    void testAliasMapper() {
+        final String LONG_ALIAS = "this-is-a-very-long-alias-which-exceeds-the-sixty-three-characters";
+        //hashed alias is same as alias if less than 63 chars
+        final String hashedAlias1 = AliasMapper.hashAlias("alias");
+        assertEquals("alias", hashedAlias1);
+        //hashed alias is SHA-1 hash of alias
+        final String hashedAlias2 = AliasMapper.hashAlias(LONG_ALIAS);
+        assertEquals(40, hashedAlias2.length());
+        assertEquals("8CE1DE1724594D06F010A083831CA2B0A345F730", hashedAlias2);
+
+        //alias is same as hashed alias if less than 63 chars
+        assertEquals("alias", AliasMapper.getOriginalAlias("alias"));
+        //verify the retrieval of original alias from hashed alias
+        assertEquals(LONG_ALIAS, AliasMapper.getOriginalAlias("8CE1DE1724594D06F010A083831CA2B0A345F730"));
+    }
+
+}
index ca044db..cd77164 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.refiner;
 
+import static org.oran.smo.teiv.utils.TiesConstants.ID_COLUMN_NAME;
+import static org.oran.smo.teiv.utils.TiesConstants.ITEM;
+import static org.oran.smo.teiv.utils.TiesConstants.WILDCARD;
+import static org.mockito.Mockito.mock;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
-import org.apache.commons.lang3.NotImplementedException;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.EmptyLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.InnerFilterCriteria;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataValidator;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndOrLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
-import org.oran.smo.teiv.exposure.tiespath.innerlanguage.EmptyLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
@@ -41,331 +52,1265 @@ import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeLogicalBlock;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeObject;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TargetObject;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TopologyObjectType;
+import org.oran.smo.teiv.exposure.tiespath.resolver.ResolverDataType;
+import org.oran.smo.teiv.exposure.tiespath.resolver.ScopeResolver;
+import org.oran.smo.teiv.exposure.tiespath.resolver.TargetResolver;
 import org.oran.smo.teiv.schema.DataType;
 import org.oran.smo.teiv.schema.MockSchemaLoader;
 import org.oran.smo.teiv.schema.SchemaLoader;
 import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
 import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
 
-import org.junit.jupiter.api.BeforeAll;
+class BasePathRefinementTest {
 
-import static org.oran.smo.teiv.utils.TiesConstants.ITEMS;
+    private static final ConsumerDataValidator consumerDataValidator = mock(ConsumerDataValidator.class);
+    private static BasePathRefinement basePathRefinement;
+    private final TargetResolver targetResolver = new TargetResolver();
+    private final ScopeResolver scopeResolver = new ScopeResolver();
 
-class BasePathRefinementTest {
+    private static final String GNBDU_FUNCTION = "GNBDUFunction";
 
     @BeforeAll
     static void setUp() throws SchemaLoaderException {
         SchemaLoader mockedSchemaLoader = new MockSchemaLoader();
         mockedSchemaLoader.loadSchemaRegistry();
+        basePathRefinement = new BasePathRefinement(consumerDataValidator);
     }
 
     @Test
-    void testResolveWildCardObjectsInScopeAndTarget() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        Assertions.assertThrows(NotImplementedException.class, () -> BasePathRefinement
-                .resolveWildCardObjectsInScopeAndTarget(filterCriteria));
+    void testRefinementOrchestration() {
+        LogicalBlock logicalBlock = scopeResolver.process(null, "/attributes[@gNBCUName='someCUCPName']");
+        List<TargetObject> targets = targetResolver.resolve(null, "/GNBCUCPFunction/attributes");
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(targets).scope(logicalBlock).build())).resolvingTopologyObjectType(
+                        FilterCriteria.ResolvingTopologyObjectType.ENTITY).build();
+
+        basePathRefinement.refine(filterCriteria);
+
+        LogicalBlock expectedLogicalBlock = scopeResolver.process(null, "/attributes[@gNBCUName='someCUCPName']");
+        List<TargetObject> expectedTargets = targetResolver.resolve(null, "/GNBCUCPFunction/attributes");
+        FilterCriteria expectedFilterCriteria = FilterCriteria.builder("RAN").filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(expectedTargets).scope(expectedLogicalBlock).build())).resolvingTopologyObjectType(
+                        FilterCriteria.ResolvingTopologyObjectType.ENTITY).build();
+
+        ScopeObject expectedScopeObject = ((ScopeLogicalBlock) expectedLogicalBlock).getScopeObject();
+        expectedScopeObject.setTopologyObject("GNBCUCPFunction");
+        expectedScopeObject.setTopologyObjectType(TopologyObjectType.ENTITY);
+        expectedScopeObject.setContainer(ContainerType.ATTRIBUTES);
+        expectedScopeObject.setLeaf("gNBCUName");
+        expectedScopeObject.setQueryFunction(QueryFunction.EQ);
+        expectedScopeObject.setParameter("someCUCPName");
+        expectedScopeObject.setDataType(DataType.PRIMITIVE);
+
+        expectedTargets.get(0).setTopologyObjectType(TopologyObjectType.ENTITY);
+        expectedTargets.get(0).setAllParamQueried(true);
+
+        Assertions.assertEquals(expectedFilterCriteria, filterCriteria);
+    }
+
+    @Test
+    void processTopologyObjectsWithContainerTypeNull() {
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        LogicalBlock logicalBlock1 = scopeResolver.process(null, "/managed-by-managedElement[@id='me1']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock1).build()));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(filterCriteria);
+
+        ScopeObject scopeObjectResult1 = ScopeObject.builder(WILDCARD).container(ContainerType.ASSOCIATION).innerContainer(
+                List.of("managed-by-managedElement")).resolverDataType(ResolverDataType.STRING).queryFunction(
+                        QueryFunction.EQ).leaf(ID_COLUMN_NAME).parameter("me1").build();
+        Assertions.assertEquals(scopeObjectResult1, ((ScopeLogicalBlock) logicalBlock1).getScopeObject());
+
+        LogicalBlock logicalBlock2 = scopeResolver.process(GNBDU_FUNCTION, "/managed-by-managedElement");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock2).build()));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(filterCriteria);
+
+        ScopeObject scopeObjectResult2 = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ASSOCIATION)
+                .innerContainer(List.of("managed-by-managedElement")).resolverDataType(ResolverDataType.NOT_NULL)
+                .queryFunction(QueryFunction.NOT_NULL).build();
+        Assertions.assertEquals(scopeObjectResult2, ((ScopeLogicalBlock) logicalBlock2).getScopeObject());
+
+        LogicalBlock logicalBlock3 = scopeResolver.process(null, "/GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock3).build()));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(filterCriteria);
+
+        ScopeObject scopeObjectResult3 = ScopeObject.builder(WILDCARD).container(ContainerType.RELATION).innerContainer(List
+                .of("GNBDUFUNCTION_PROVIDES_NRCELLDU")).resolverDataType(ResolverDataType.NOT_NULL).queryFunction(
+                        QueryFunction.NOT_NULL).build();
+        Assertions.assertEquals(scopeObjectResult3, ((ScopeLogicalBlock) logicalBlock3).getScopeObject());
+
+        LogicalBlock logicalBlock4 = scopeResolver.process(null, "/GNBDUFunction[@id='gnbdu1']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock4).build()));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(filterCriteria);
+
+        ScopeObject scopeObjectResult4 = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ID).resolverDataType(
+                ResolverDataType.STRING).queryFunction(QueryFunction.EQ).parameter("gnbdu1").build();
+        Assertions.assertEquals(scopeObjectResult4, ((ScopeLogicalBlock) logicalBlock4).getScopeObject());
+
+        LogicalBlock logicalBlock5 = scopeResolver.process("NRCellDU", "/GNBDUFunction[@id='GNBDU_1']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock5).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement
+                .processTopologyObjectsWithContainerTypeNull(filterCriteria));
+
+        ScopeObject scopeObject = ScopeObject.builder(WILDCARD).container(null).build();
+        LogicalBlock logicalBlock6 = new ScopeLogicalBlock(scopeObject);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock6).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement
+                .processTopologyObjectsWithContainerTypeNull(filterCriteria));
+
+        try (MockedStatic<SchemaRegistry> utilities = Mockito.mockStatic(SchemaRegistry.class)) {
+            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN")).thenReturn(Arrays.asList(
+                    "RelationAndEntity"));
+            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN")).thenReturn(Arrays.asList(
+                    "RelationAndEntity"));
+            LogicalBlock logicalBlock7 = scopeResolver.process(null, "/RelationAndEntity[@id='relAndEnt1']");
+            filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock7).build()));
+
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement
+                    .processTopologyObjectsWithContainerTypeNull(filterCriteria));
+            utilities.when(() -> SchemaRegistry.getAssociationNamesByEntityName(GNBDU_FUNCTION)).thenReturn(Arrays.asList(
+                    "RelationAndAssociation"));
+            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN")).thenReturn(Arrays.asList(
+                    "RelationAndAssociation"));
+            LogicalBlock logicalBlock8 = scopeResolver.process(null, "/RelationAndAssociation[@id='relAndAssoc1']");
+            filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock8).build()));
+
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement
+                    .processTopologyObjectsWithContainerTypeNull(filterCriteria));
+        }
+
+        LogicalBlock logicalBlock9 = scopeResolver.process(null, "/NRCellDU/attributes[@nCI=12]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock9).build()));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(filterCriteria);
+
+        ScopeObject scopeObjectResult9 = ScopeObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES)
+                .resolverDataType(ResolverDataType.INTEGER).queryFunction(QueryFunction.EQ).leaf("nCI").parameter("12")
+                .build();
+        Assertions.assertEquals(scopeObjectResult9, ((ScopeLogicalBlock) logicalBlock9).getScopeObject());
+
+        LogicalBlock logicalBlock10 = scopeResolver.process(null, "/NRCellDU[@nCI=12]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock10).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement
+                .processTopologyObjectsWithContainerTypeNull(filterCriteria));
+
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_1() {
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().targets(targetResolver.resolve(null,
+                "/GNBDUFunction/attributes(gNBDUId); /GNBDUFunction/attributes(gNBId); /attributes(name)")).scope(
+                        EmptyLogicalBlock.getInstance()).build();
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveWildCardObjectsInScopeAndTarget(
+                filterCriteria, "RAN", FilterCriteria.ResolvingTopologyObjectType.ENTITY));
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_2() {
+        //root:GNBDUFunction
+        //Target: /attributes(gNBId); /attributes(dUpLMNId)
+        //Scope: /attribute[gNBIdLength = 2]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null,
+                "/GNBDUFunction/attributes(dUpLMNId); /GNBDUFunction/attributes(gNBId)"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/GNBDUFunction/attributes[@gNBIdLength=2]"));
+
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).leaf(
+                "gNBIdLength").queryFunction(QueryFunction.EQ).parameter("2").resolverDataType(ResolverDataType.INTEGER)
+                .build();
+        LogicalBlock scopeResult1 = new ScopeLogicalBlock(scopeObject1);
+
+        TargetObject targetObjectResult = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).params(
+                new ArrayList<>(Arrays.asList("dUpLMNId", "gNBId"))).build();
+        List<TargetObject> resultTargetObjects = new ArrayList<>();
+        resultTargetObjects.add(targetObjectResult);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects, filterCriteria.getTargets());
+        Assertions.assertEquals(scopeResult1, filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_3() {
+        //root:-
+        //Target:/attributes;/attributes(cellLocalId,nCI)
+        //Scope:/NRCellDU[nCI=12]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes;/attributes(cellLocalId,nCI)"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/NRCellDU/attributes[@nCI=12]"));
+
+        TargetObject targetObjectResult3_1 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).params(
+                new ArrayList<>(Arrays.asList("nCI", "cellLocalId"))).isAllParamQueried(true).build();
+        List<TargetObject> resultTargetObjects3_1 = new ArrayList<>();
+        resultTargetObjects3_1.add(targetObjectResult3_1);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects3_1, filterCriteria.getTargets());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_4() {
+        //root:-
+        //Target:/attributes;/attributes(cellLocalId)
+        //Scope:/attributes[nCI = 12]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes;/attributes(cellLocalId)"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@nCI=12]"));
+
+        TargetObject targetObjectResult4_1 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).params(
+                List.of("cellLocalId")).isAllParamQueried(true).build();
+        TargetObject targetObjectResult4_2 = TargetObject.builder("NRCellCU").container(ContainerType.ATTRIBUTES).params(
+                List.of("cellLocalId")).isAllParamQueried(true).build();
+        List<TargetObject> resultTargetObjects4_1 = new ArrayList<>();
+        resultTargetObjects4_1.add(targetObjectResult4_1);
+        resultTargetObjects4_1.add(targetObjectResult4_2);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects4_1, filterCriteria.getTargets());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_5() {
+        //root:-
+        //Target:-
+        //Scope:/attributes[gNBId = 6 and gNBIdLength = 1]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, null));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@gNBId = 6 and @gNBIdLength = 1]"));
+
+        ScopeLogicalBlock GNBCUUPFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder("GNBCUUPFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBDUFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBCUCPFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBCUUPFunctionPgNBIdLength = new ScopeLogicalBlock(ScopeObject.builder("GNBCUUPFunction")
+                .container(ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1")
+                .resolverDataType(ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBDUFunctionPgNBIdLength = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1")
+                .resolverDataType(ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBCUCPFunctionPgNBIdLength = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction")
+                .container(ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1")
+                .resolverDataType(ResolverDataType.INTEGER).build());
+
+        AndLogicalBlock GNBCUUPFunction = new AndLogicalBlock();
+        AndLogicalBlock GNBDUFunction = new AndLogicalBlock();
+        AndLogicalBlock GNBCUCPFunction = new AndLogicalBlock();
+
+        GNBCUCPFunction.getChildren().add(GNBCUCPFunctionPgNBId);
+        GNBCUCPFunction.getChildren().add(GNBCUCPFunctionPgNBIdLength);
+        GNBCUUPFunction.getChildren().add(GNBCUUPFunctionPgNBId);
+        GNBCUUPFunction.getChildren().add(GNBCUUPFunctionPgNBIdLength);
+        GNBDUFunction.getChildren().add(GNBDUFunctionPgNBId);
+        GNBDUFunction.getChildren().add(GNBDUFunctionPgNBIdLength);
+
+        OrLogicalBlock or1 = new OrLogicalBlock();
+        OrLogicalBlock or2 = new OrLogicalBlock();
+
+        or1.getChildren().add(or2);
+        or1.getChildren().add(GNBDUFunction);
+        or2.getChildren().add(GNBCUCPFunction);
+        or2.getChildren().add(GNBCUUPFunction);
+
+        TargetObject targetObjectResult5_1 = TargetObject.builder("GNBCUUPFunction").container(ContainerType.ID).build();
+        TargetObject targetObjectResult5_2 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ID).build();
+        TargetObject targetObjectResult5_3 = TargetObject.builder("GNBCUCPFunction").container(ContainerType.ID).build();
+        List<TargetObject> resultTargetObjects5_1 = new ArrayList<>();
+        resultTargetObjects5_1.add(targetObjectResult5_1);
+        resultTargetObjects5_1.add(targetObjectResult5_2);
+        resultTargetObjects5_1.add(targetObjectResult5_3);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+        Assertions.assertEquals(resultTargetObjects5_1, filterCriteria.getTargets());
+        Assertions.assertEquals(or1, filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_6() {
+        //root:-
+        //Target:/NRCellDU
+        //Scope:/attributes[@cellLocalId = 156]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/NRCellDU"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@cellLocalId = 156]"));
+
+        TargetObject targetObjectResult6_1 = TargetObject.builder("NRCellDU").container(ContainerType.ID).build();
+        List<TargetObject> resultTargetObjects6_1 = new ArrayList<>();
+        resultTargetObjects6_1.add(targetObjectResult6_1);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        ScopeObject scopeObjectResult6_1 = ScopeObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).leaf(
+                "cellLocalId").queryFunction(QueryFunction.EQ).parameter("156").resolverDataType(ResolverDataType.INTEGER)
+                .build();
+        LogicalBlock logicalBlockResult6_1 = new ScopeLogicalBlock(scopeObjectResult6_1);
+
+        Assertions.assertEquals(resultTargetObjects6_1, filterCriteria.getTargets());
+        Assertions.assertEquals(logicalBlockResult6_1, filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_7() {
+        //root:-
+        //Target:/attributes(gNBId);/attributes(nCI)
+        //Scope:-
+        //error no intersection
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes(gNBId);/attributes(nCI)"));
+        filterCriteria.setScope(scopeResolver.resolve(null, null));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveWildCardObjectsInScopeAndTarget(
+                filterCriteria, "RAN", FilterCriteria.ResolvingTopologyObjectType.ENTITY));
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_8() {
+        //root:-
+        //Target:/attributes(nCI)
+        //Scope:/attributes[gNBId = 6]
+        //error no intersection
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes(nCI)"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@gNBId = 6]"));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveWildCardObjectsInScopeAndTarget(
+                filterCriteria, "RAN", FilterCriteria.ResolvingTopologyObjectType.ENTITY));
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_9() {
+        //root:-
+        //Target:/attributes
+        //Scope:/attributes[cellLocalId = 178]; /attributes[nCI = 12]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@cellLocalId = 178]; /attributes[@nCI = 12]"));
+
+        ScopeLogicalBlock NRCellDUCellLocalId = new ScopeLogicalBlock(ScopeObject.builder("NRCellDU").container(
+                ContainerType.ATTRIBUTES).leaf("cellLocalId").queryFunction(QueryFunction.EQ).parameter("178")
+                .resolverDataType(ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock NRCellCUCellLocalId = new ScopeLogicalBlock(ScopeObject.builder("NRCellCU").container(
+                ContainerType.ATTRIBUTES).leaf("cellLocalId").queryFunction(QueryFunction.EQ).parameter("178")
+                .resolverDataType(ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock NRCellDUnCI = new ScopeLogicalBlock(ScopeObject.builder("NRCellDU").container(
+                ContainerType.ATTRIBUTES).leaf("nCI").queryFunction(QueryFunction.EQ).parameter("12").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock NRCellCUnCI = new ScopeLogicalBlock(ScopeObject.builder("NRCellCU").container(
+                ContainerType.ATTRIBUTES).leaf("nCI").queryFunction(QueryFunction.EQ).parameter("12").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+
+        AndLogicalBlock NRCellDU = new AndLogicalBlock();
+        NRCellDU.getChildren().add(NRCellDUnCI);
+        NRCellDU.getChildren().add(NRCellDUCellLocalId);
+
+        AndLogicalBlock NRCellCU = new AndLogicalBlock();
+        NRCellCU.getChildren().add(NRCellCUnCI);
+        NRCellCU.getChildren().add(NRCellCUCellLocalId);
+
+        OrLogicalBlock or = new OrLogicalBlock();
+        or.getChildren().add(NRCellCU);
+        or.getChildren().add(NRCellDU);
+
+        TargetObject targetObjectResult9_1 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).isAllParamQueried(true).build();
+        TargetObject targetObjectResult9_2 = TargetObject.builder("NRCellCU").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).isAllParamQueried(true).build();
+
+        List<TargetObject> resultTargetObjects9_1 = new ArrayList<>();
+        resultTargetObjects9_1.add(targetObjectResult9_1);
+        resultTargetObjects9_1.add(targetObjectResult9_2);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects9_1, filterCriteria.getTargets());
+        Assertions.assertEquals(or, filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_10() {
+        //root:-
+        //Target:/attributes
+        //Scope:/attributes[nCI = 12]; /attributes[gNBId = 6]
+        //error no intersection in scope
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/attributes[@nCI = 12]; /attributes[@gNBId = 6]"));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveWildCardObjectsInScopeAndTarget(
+                filterCriteria, "RAN", FilterCriteria.ResolvingTopologyObjectType.ENTITY));
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_11() {
+        //root:-
+        //Target:/attributes, /id
+        //Scope:/[id = "testId"]; /attributes[gNBId = 6]
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/attributes; /id"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/id[@id = \"testId\"]; /attributes[@gNBId = 6]"));
+
+        ScopeLogicalBlock GNBCUUPFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder("GNBCUUPFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBDUFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBCUCPFunctionPgNBId = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gNBId").queryFunction(QueryFunction.EQ).parameter("6").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock GNBCUUPFunctionPid = new ScopeLogicalBlock(ScopeObject.builder("GNBCUUPFunction").container(
+                ContainerType.ID).queryFunction(QueryFunction.EQ).parameter("testId").resolverDataType(
+                        ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBDUFunctionPid = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ID).queryFunction(QueryFunction.EQ).parameter("testId").resolverDataType(
+                        ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBCUCPFunctionPid = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ID).queryFunction(QueryFunction.EQ).parameter("testId").resolverDataType(
+                        ResolverDataType.STRING).build());
+
+        AndLogicalBlock GNBCUUPFunction = new AndLogicalBlock();
+        GNBCUUPFunction.getChildren().add(GNBCUUPFunctionPgNBId);
+        GNBCUUPFunction.getChildren().add(GNBCUUPFunctionPid);
+
+        AndLogicalBlock GNBDUFunction = new AndLogicalBlock();
+        GNBDUFunction.getChildren().add(GNBDUFunctionPgNBId);
+        GNBDUFunction.getChildren().add(GNBDUFunctionPid);
+
+        AndLogicalBlock GNBCUCPFunction = new AndLogicalBlock();
+        GNBCUCPFunction.getChildren().add(GNBCUCPFunctionPgNBId);
+        GNBCUCPFunction.getChildren().add(GNBCUCPFunctionPid);
+
+        OrLogicalBlock or1 = new OrLogicalBlock();
+        OrLogicalBlock or2 = new OrLogicalBlock();
+
+        or1.getChildren().add(or2);
+        or1.getChildren().add(GNBDUFunction);
+        or2.getChildren().add(GNBCUCPFunction);
+        or2.getChildren().add(GNBCUUPFunction);
+
+        TargetObject targetObjectResult11_1 = TargetObject.builder("GNBCUUPFunction").container(ContainerType.ID).build();
+        TargetObject targetObjectResult11_2 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ID).build();
+        TargetObject targetObjectResult11_3 = TargetObject.builder("GNBCUCPFunction").container(ContainerType.ID).build();
+        TargetObject targetObjectResult11_4 = TargetObject.builder("GNBCUUPFunction").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        TargetObject targetObjectResult11_5 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        TargetObject targetObjectResult11_6 = TargetObject.builder("GNBCUCPFunction").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        List<TargetObject> resultTargetObjects11_1 = new ArrayList<>();
+        resultTargetObjects11_1.add(targetObjectResult11_4);
+        resultTargetObjects11_1.add(targetObjectResult11_5);
+        resultTargetObjects11_1.add(targetObjectResult11_6);
+        resultTargetObjects11_1.add(targetObjectResult11_1);
+        resultTargetObjects11_1.add(targetObjectResult11_2);
+        resultTargetObjects11_1.add(targetObjectResult11_3);
+
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects11_1, filterCriteria.getTargets());
+        Assertions.assertEquals(or1, filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_12() {
+        //root:-
+        //Target: /attributes
+        //Scope: /managed-by-managedElement[id = "me1"]
+        InnerFilterCriteria filterCriteria2 = InnerFilterCriteria.builder().build();
+        filterCriteria2.setTargets(targetResolver.resolve(null, "/attributes"));
+        filterCriteria2.setScope(scopeResolver.resolve(null, "/managed-by-managedElement[@id = \"me1\"]"));
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("OAM").filterCriteriaList(List
+                .of(filterCriteria2)).build());
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveWildCardObjectsInScopeAndTarget(
+                filterCriteria2, "OAM", FilterCriteria.ResolvingTopologyObjectType.ENTITY));
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_13() {
+        //root:-
+        //Target: /attributes
+        //Scope: /managed-by-managedElement[id = "me1"]
+        InnerFilterCriteria filterCriteria2 = InnerFilterCriteria.builder().build();
+        filterCriteria2.setTargets(targetResolver.resolve(null, "/attributes"));
+        filterCriteria2.setScope(scopeResolver.resolve(null, "/managed-by-managedElement[@id = \"me1\"]"));
+
+        TargetObject targetObjectResult13_1 = TargetObject.builder("GNBCUUPFunction").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        TargetObject targetObjectResult13_2 = TargetObject.builder("ENodeBFunction").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        TargetObject targetObjectResult13_3 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        TargetObject targetObjectResult13_4 = TargetObject.builder("GNBCUCPFunction").container(ContainerType.ATTRIBUTES)
+                .isAllParamQueried(true).build();
+        List<TargetObject> resultTargetObjectsResult13_1 = new ArrayList<>();
+        resultTargetObjectsResult13_1.add(targetObjectResult13_1);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_2);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_3);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_4);
+
+        ScopeLogicalBlock GNBCUUPFunction = new ScopeLogicalBlock(ScopeObject.builder("GNBCUUPFunction").container(
+                ContainerType.ASSOCIATION).innerContainer(List.of("managed-by-managedElement")).leaf("id").queryFunction(
+                        QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock ENodeBFunction = new ScopeLogicalBlock(ScopeObject.builder("ENodeBFunction").container(
+                ContainerType.ASSOCIATION).innerContainer(List.of("managed-by-managedElement")).leaf("id").queryFunction(
+                        QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBDUFunction = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ASSOCIATION).innerContainer(List.of("managed-by-managedElement")).leaf("id").queryFunction(
+                        QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBCUCPFunction = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ASSOCIATION).innerContainer(List.of("managed-by-managedElement")).leaf("id").queryFunction(
+                        QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+
+        AndOrLogicalBlock or1 = new OrLogicalBlock();
+        AndOrLogicalBlock or2 = new OrLogicalBlock();
+        AndOrLogicalBlock or3 = new OrLogicalBlock();
+
+        or3.getChildren().add(ENodeBFunction);
+        or3.getChildren().add(GNBCUCPFunction);
+        or2.getChildren().add(or3);
+        or2.getChildren().add(GNBCUUPFunction);
+        or1.getChildren().add(or2);
+        or1.getChildren().add(GNBDUFunction);
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("RAN").filterCriteriaList(List
+                .of(filterCriteria2)).build());
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria2, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjectsResult13_1, filterCriteria2.getTargets());
+        Assertions.assertEquals(or1, filterCriteria2.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_14() {
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, null));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/GNBDUFunction[@id = \"testId\"]"));
+
+        TargetObject targetObjectResult9_1 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ID)
+                .isAllParamQueried(false).build();
+
+        List<TargetObject> resultTargetObjects9_1 = new ArrayList<>();
+        resultTargetObjects9_1.add(targetObjectResult9_1);
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("RAN").filterCriteriaList(List
+                .of(filterCriteria)).build());
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.ENTITY);
+
+        Assertions.assertEquals(resultTargetObjects9_1, filterCriteria.getTargets());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_15() {
+        InnerFilterCriteria filterCriteria = InnerFilterCriteria.builder().build();
+        filterCriteria.setTargets(targetResolver.resolve(null, "/GNBDUFUNCTION_PROVIDES_NRCELLDU"));
+        filterCriteria.setScope(scopeResolver.resolve(null, "/id[text() = \"testId\"]"));
+
+        ScopeObject scopeObject = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").container(ContainerType.ID)
+                .parameter("testId").queryFunction(QueryFunction.EQ).resolverDataType(ResolverDataType.STRING).build();
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("RAN").filterCriteriaList(List
+                .of(filterCriteria)).build());
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP);
+
+        Assertions.assertEquals(new ScopeLogicalBlock(scopeObject), filterCriteria.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_16() {
+        //root:-
+        //Target: /decorators
+        //Scope: /managed-by-managedElement[id = "me1"]
+        InnerFilterCriteria filterCriteria2 = InnerFilterCriteria.builder().build();
+        filterCriteria2.setTargets(targetResolver.resolve(null,
+                "/MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION/decorators; /MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/decorators"));
+        filterCriteria2.setScope(scopeResolver.resolve(null, "/managed-by-managedElement[@id = \"me1\"]"));
+
+        TargetObject targetObjectResult13_1 = TargetObject.builder("MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        TargetObject targetObjectResult13_2 = TargetObject.builder("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        List<TargetObject> resultTargetObjectsResult13_1 = new ArrayList<>();
+        resultTargetObjectsResult13_1.add(targetObjectResult13_1);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_2);
+
+        ScopeLogicalBlock GNBCUCPFunction = new ScopeLogicalBlock(ScopeObject.builder(
+                "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION").container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock ENodeBFunction = new ScopeLogicalBlock(ScopeObject.builder(
+                "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION").container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+
+        AndOrLogicalBlock or1 = new OrLogicalBlock();
+
+        or1.getChildren().add(GNBCUCPFunction);
+        or1.getChildren().add(ENodeBFunction);
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("RAN").filterCriteriaList(List
+                .of(filterCriteria2)).build());
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria2, "RAN",
+                FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP);
+
+        Assertions.assertEquals(resultTargetObjectsResult13_1, filterCriteria2.getTargets());
+        Assertions.assertEquals(or1, filterCriteria2.getScope());
+    }
+
+    @Test
+    void testResolveWildCardObjectsInScopeAndTarget_17() {
+        //root:-
+        //Target: /decorators
+        //Scope: /managed-by-managedElement[id = "me1"]
+        InnerFilterCriteria filterCriteria2 = InnerFilterCriteria.builder().build();
+        filterCriteria2.setTargets(targetResolver.resolve(null, "/decorators"));
+        filterCriteria2.setScope(scopeResolver.resolve(null, "/managed-by-managedElement[@id = \"me1\"]"));
+
+        TargetObject targetObjectResult13_1 = TargetObject.builder("MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        TargetObject targetObjectResult13_2 = TargetObject.builder("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        TargetObject targetObjectResult13_3 = TargetObject.builder("MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        TargetObject targetObjectResult13_4 = TargetObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION").container(
+                ContainerType.DECORATORS).build();
+        List<TargetObject> resultTargetObjectsResult13_1 = new ArrayList<>();
+        resultTargetObjectsResult13_1.add(targetObjectResult13_1);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_2);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_3);
+        resultTargetObjectsResult13_1.add(targetObjectResult13_4);
+
+        ScopeLogicalBlock GNBCUUPFunction = new ScopeLogicalBlock(ScopeObject.builder(
+                "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION").container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock ENodeBFunction = new ScopeLogicalBlock(ScopeObject.builder(
+                "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION").container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBDUFunction = new ScopeLogicalBlock(ScopeObject.builder("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION")
+                .container(ContainerType.ASSOCIATION).innerContainer(List.of("managed-by-managedElement")).leaf("id")
+                .queryFunction(QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock GNBCUCPFunction = new ScopeLogicalBlock(ScopeObject.builder(
+                "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION").container(ContainerType.ASSOCIATION).innerContainer(List.of(
+                        "managed-by-managedElement")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+
+        AndOrLogicalBlock or1 = new OrLogicalBlock();
+        AndOrLogicalBlock or2 = new OrLogicalBlock();
+        AndOrLogicalBlock or3 = new OrLogicalBlock();
+
+        or3.getChildren().add(ENodeBFunction);
+        or3.getChildren().add(GNBCUCPFunction);
+        or2.getChildren().add(or3);
+        or2.getChildren().add(GNBCUUPFunction);
+        or1.getChildren().add(or2);
+        or1.getChildren().add(GNBDUFunction);
+
+        basePathRefinement.processTopologyObjectsWithContainerTypeNull(FilterCriteria.builder("REL_OAM_RAN")
+                .filterCriteriaList(List.of(filterCriteria2)).build());
+        basePathRefinement.resolveWildCardObjectsInScopeAndTarget(filterCriteria2, "REL_OAM_RAN",
+                FilterCriteria.ResolvingTopologyObjectType.RELATIONSHIP);
+
+        Assertions.assertEquals(resultTargetObjectsResult13_1, filterCriteria2.getTargets());
+        Assertions.assertEquals(or1, filterCriteria2.getScope());
     }
 
     @Test
     void testResolveUndefinedTopologyObjects_Entity() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        TargetObject targetObject = TargetObject.builder("GNBDUFunction").build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject)));
-        ScopeObject scopeObject = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBId", QueryFunction.EQ, "1",
-                DataType.BIGINT);
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        TargetObject targetObject = TargetObject.builder(GNBDU_FUNCTION).build();
+        ScopeObject scopeObject = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
         LogicalBlock scope = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scope);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject))).scope(scope).build()));
 
         try (MockedStatic<SchemaRegistry> utilities = Mockito.mockStatic(SchemaRegistry.class)) {
-            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
-                    "GNBDUFunction", "NRCellDU"));
-            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
+            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN")).thenReturn(Arrays.asList(GNBDU_FUNCTION,
+                    "NRCellDU"));
+            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN")).thenReturn(Arrays.asList(
                     "GNBDUFUNCTION_PROVIDES_NRCELLDU"));
 
-            BasePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
+            basePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
 
-            Assertions.assertEquals(TopologyObjectType.ENTITY, filterCriteria.getTargets().get(0).getTopologyObjectType());
-            Assertions.assertEquals(TopologyObjectType.ENTITY, ((ScopeLogicalBlock) filterCriteria.getScope())
-                    .getScopeObject().getTopologyObjectType());
+            Assertions.assertEquals(TopologyObjectType.ENTITY, filterCriteria.getFilterCriteriaList().get(0).getTargets()
+                    .get(0).getTopologyObjectType());
+            Assertions.assertEquals(TopologyObjectType.ENTITY, ((ScopeLogicalBlock) filterCriteria.getFilterCriteriaList()
+                    .get(0).getScope()).getScopeObject().getTopologyObjectType());
 
-            filterCriteria.setScope(EmptyLogicalBlock.getInstance());
+            filterCriteria.getFilterCriteriaList().get(0).setScope(EmptyLogicalBlock.getInstance());
             targetObject.setTopologyObjectType(TopologyObjectType.UNDEFINED);
 
-            BasePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
+            basePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
 
-            Assertions.assertEquals(TopologyObjectType.ENTITY, filterCriteria.getTargets().get(0).getTopologyObjectType());
+            Assertions.assertEquals(TopologyObjectType.ENTITY, filterCriteria.getFilterCriteriaList().get(0).getTargets()
+                    .get(0).getTopologyObjectType());
         }
     }
 
     @Test
     void testResolveUndefinedTopologyObjects_Relation() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
         TargetObject targetObject = TargetObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject)));
-        ScopeObject scopeObject = new ScopeObject("GNBDUFUNCTION_PROVIDES_NRCELLDU", ContainerType.ID, QueryFunction.EQ,
-                "1", DataType.PRIMITIVE);
+        ScopeObject scopeObject = ScopeObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").container(ContainerType.ID)
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.PRIMITIVE).build();
         LogicalBlock scope = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scope);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject))).scope(scope).build()));
 
         try (MockedStatic<SchemaRegistry> utilities = Mockito.mockStatic(SchemaRegistry.class)) {
-            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
-                    "GNBDUFunction", "NRCellDU"));
-            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
+            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN")).thenReturn(Arrays.asList(GNBDU_FUNCTION,
+                    "NRCellDU"));
+            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN")).thenReturn(Arrays.asList(
                     "GNBDUFUNCTION_PROVIDES_NRCELLDU"));
 
-            BasePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
+            basePathRefinement.resolveUndefinedTopologyObjectTypes(filterCriteria);
 
-            Assertions.assertEquals(TopologyObjectType.RELATION, filterCriteria.getTargets().get(0)
-                    .getTopologyObjectType());
-            Assertions.assertEquals(TopologyObjectType.RELATION, ((ScopeLogicalBlock) filterCriteria.getScope())
-                    .getScopeObject().getTopologyObjectType());
+            Assertions.assertEquals(TopologyObjectType.RELATION, filterCriteria.getFilterCriteriaList().get(0).getTargets()
+                    .get(0).getTopologyObjectType());
+            Assertions.assertEquals(TopologyObjectType.RELATION, ((ScopeLogicalBlock) filterCriteria.getFilterCriteriaList()
+                    .get(0).getScope()).getScopeObject().getTopologyObjectType());
         }
     }
 
     @Test
     void testResolveUndefinedTopologyObjects_InvalidTargetAndScope() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
         TargetObject targetObject = TargetObject.builder("InvalidObject").build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject)));
-        ScopeObject scopeObject = new ScopeObject("InvalidObject", ContainerType.ATTRIBUTES, "gNBId", QueryFunction.EQ, "1",
-                DataType.BIGINT);
+        ScopeObject scopeObject = ScopeObject.builder("InvalidObject").container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
         LogicalBlock scope = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scope);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject))).scope(scope).build()));
 
         try (MockedStatic<SchemaRegistry> utilities = Mockito.mockStatic(SchemaRegistry.class)) {
-            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
-                    "GNBDUFunction", "NRCellDU", "EntityAndRelation"));
-            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN_LOGICAL")).thenReturn(Arrays.asList(
+            utilities.when(() -> SchemaRegistry.getEntityNamesByDomain("RAN")).thenReturn(Arrays.asList(GNBDU_FUNCTION,
+                    "NRCellDU", "EntityAndRelation"));
+            utilities.when(() -> SchemaRegistry.getRelationNamesByDomain("RAN")).thenReturn(Arrays.asList(
                     "GNBDUFUNCTION_PROVIDES_NRCELLDU", "EntityAndRelation"));
             // Error thrown because of invalid topology object in targetFilter
-            Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.resolveUndefinedTopologyObjectTypes(
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveUndefinedTopologyObjectTypes(
                     filterCriteria));
 
-            targetObject.setTopologyObject("GNBDUFunction");
+            targetObject.setTopologyObject(GNBDU_FUNCTION);
 
             // Error thrown because of invalid topology object in scopeFilter
-            Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.resolveUndefinedTopologyObjectTypes(
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveUndefinedTopologyObjectTypes(
                     filterCriteria));
 
             scopeObject.setTopologyObject("EntityAndRelation");
 
             // Error thrown because of topology object type is ambiguous
-            Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.resolveUndefinedTopologyObjectTypes(
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveUndefinedTopologyObjectTypes(
                     filterCriteria));
 
             targetObject.setTopologyObjectType(TopologyObjectType.UNDEFINED);
             targetObject.setTopologyObject("EntityAndRelation");
 
             // Error thrown because of topology object type is ambiguous
-            Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.resolveUndefinedTopologyObjectTypes(
+            Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.resolveUndefinedTopologyObjectTypes(
                     filterCriteria));
         }
     }
 
     @Test
     void testValidateContainers() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
 
-        TargetObject targetObject0 = TargetObject.builder("GNBDUFunction").container(ContainerType.ID).params(
+        TargetObject targetObject0 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ID).params(
                 new ArrayList<>(Arrays.asList("gNBId"))).build();
         targetObject0.setTopologyObjectType(TopologyObjectType.ENTITY);
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject0)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject0))).build()));
 
         // Reason: container:ID, params is not empty
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
-        TargetObject targetObject1 = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).params(
+        TargetObject targetObject1 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).params(
                 new ArrayList<>(Arrays.asList("gNBId", "gNBIdLength", "notValidAttribute1", "notValidAttribute2"))).build();
         targetObject1.setTopologyObjectType(TopologyObjectType.ENTITY);
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject1)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(List.of(targetObject1))
+                .build()));
+
+        ScopeObject scopeObject = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
 
-        ScopeObject scopeObject = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBId", QueryFunction.EQ, "1",
-                DataType.BIGINT);
         scopeObject.setTopologyObjectType(TopologyObjectType.ENTITY);
         LogicalBlock scopeLogicalBlock = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scopeLogicalBlock);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1))).scope(scopeLogicalBlock).build()));
 
         // Reason: invalid attributes in ENTITY type targetObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         TargetObject targetObject2 = TargetObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").container(
                 ContainerType.ATTRIBUTES).topologyObjectType(TopologyObjectType.RELATION).params(new ArrayList<>(Arrays
                         .asList("notValidAttribute1", "notValidAttribute2"))).build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject2)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject2))).scope(scopeLogicalBlock).build()));
 
         // Reason: invalid attributes in RELATION type targetObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setLeaf("notValidAttribute");
 
-        TargetObject targetObject3 = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES)
+        TargetObject targetObject3 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES)
                 .topologyObjectType(TopologyObjectType.ENTITY).params(new ArrayList<>(Arrays.asList("gNBId",
                         "gNBIdLength"))).build();
         targetObject3.setTopologyObjectType(TopologyObjectType.ENTITY);
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject3)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject3))).scope(scopeLogicalBlock).build()));
 
         // Reason: invalid attributes in ENTITY type scopeObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setLeaf("gNBId");
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
 
-        TargetObject targetObject4 = TargetObject.builder("GNBDUFunction").container(ContainerType.SOURCE_IDS)
+        TargetObject targetObject4 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.SOURCE_IDS)
                 .topologyObjectType(TopologyObjectType.ENTITY).params(new ArrayList<>(Arrays.asList("gNBId"))).build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject4)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject4))).scope(scopeLogicalBlock).build()));
 
         // Reason: invalid source id param for ENTITY type targetObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         targetObject4.setParams(Collections.emptyList());
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
 
         TargetObject targetObject5 = TargetObject.builder("GNBDUFUNCTION_PROVIDES_NRCELLDU").container(
                 ContainerType.SOURCE_IDS).topologyObjectType(TopologyObjectType.RELATION).params(new ArrayList<>(Arrays
                         .asList("InvalidSourceIdParam"))).build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject5)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject5))).scope(scopeLogicalBlock).build()));
 
         // Reason: invalid source id param for RELATION type targetObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
-        targetObject5.setParams(new ArrayList<>(Arrays.asList(ITEMS)));
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        targetObject5.setParams(new ArrayList<>(Arrays.asList(ITEM)));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
     }
 
     @Test
     void testValidateContainers_Associations() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        ScopeObject scopeObject = new ScopeObject("GNBDUFunction", ContainerType.ASSOCIATION, "nCI", QueryFunction.EQ, "1",
-                DataType.BIGINT);
-        scopeObject.setInnerContainer(Arrays.asList("provided-by-gnbduFunction"));
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        ScopeObject scopeObject = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ASSOCIATION).leaf("nCI")
+                .queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+        scopeObject.setInnerContainer(Arrays.asList("provided-nrCellDu"));
         scopeObject.setTopologyObjectType(TopologyObjectType.ENTITY);
         LogicalBlock scopeLogicalBlock = new ScopeLogicalBlock(scopeObject);
-        filterCriteria.setScope(scopeLogicalBlock);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(List.of()).scope(
+                scopeLogicalBlock).build()));
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setLeaf(null);
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setLeaf("invalid");
 
         // Reason: invalid leaf for scopeObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setLeaf("nCI");
         scopeObject.setInnerContainer(Arrays.asList("invalid-association"));
 
         // Reason: invalid association added in innerContainer list for ENTITY type scopeObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setInnerContainer(Collections.emptyList());
 
         // Reason: no association name added in innerContainer list for scopeObject in case of association containerType
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setTopologyObject("GNBDUFUNCTION_PROVIDES_NRCELLDU");
         scopeObject.setTopologyObjectType(TopologyObjectType.RELATION);
-        scopeObject.setInnerContainer(Arrays.asList("provided-by-gnbduFunction"));
+        scopeObject.setInnerContainer(Arrays.asList("provided-nrCellDu"));
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setTopologyObjectType(TopologyObjectType.UNDEFINED);
 
         // Reason: cannot validate container for UNDEFINED type topologyObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
         scopeObject.setTopologyObjectType(TopologyObjectType.RELATION);
         scopeObject.setInnerContainer(Arrays.asList("invalid-association"));
 
         // Reason: invalid association added in innerContainer list for RELATION type scopeObject
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.validateContainers(filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateContainers(filterCriteria));
 
     }
 
     @Test
     void testValidateScopeParametersDataType() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        Assertions.assertThrows(NotImplementedException.class, () -> BasePathRefinement.validateScopeParametersDataType(
+        // for gNBId attribute the BIGINT dataType is set
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        LogicalBlock logicalBlock1 = scopeResolver.process(GNBDU_FUNCTION, "/attributes[@gNBId=21]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock1).build()));
+
+        basePathRefinement.validateScopeParametersDataType(filterCriteria);
+        Assertions.assertEquals(DataType.BIGINT, ((ScopeLogicalBlock) logicalBlock1).getScopeObject().getDataType());
+
+        // error reason: for gNBId attribute string value is not accepted
+        LogicalBlock logicalBlock2 = scopeResolver.process(GNBDU_FUNCTION, "/attributes[@gNBId='abc']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock2).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // error reason: id value should be entered as string (' ')
+        LogicalBlock logicalBlock3 = scopeResolver.process(GNBDU_FUNCTION, "/GNBDUFunction[@id=1]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock3).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // scopeFilter: /managed-by-managedElement[@id='me1'] -> dataType is set to PRIMITIVE
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).innerContainer(
+                new ArrayList<>(Arrays.asList("managed-by-managedElement"))).container(ContainerType.ASSOCIATION)
+                .topologyObjectType(TopologyObjectType.ENTITY).queryFunction(QueryFunction.EQ).leaf(ID_COLUMN_NAME)
+                .parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(scopeLogicalBlock1).build()));
+
+        basePathRefinement.validateScopeParametersDataType(filterCriteria);
+
+        Assertions.assertEquals(DataType.PRIMITIVE, scopeLogicalBlock1.getScopeObject().getDataType());
+
+        // error reason: scopeFilter: /managed-by-managedElement[@id=1] -> ResolverDataType is INTEGER, but in case of id it should be STRING
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).innerContainer(
+                new ArrayList<>(Arrays.asList("managed-by-managedElement"))).container(ContainerType.ASSOCIATION)
+                .topologyObjectType(TopologyObjectType.ENTITY).queryFunction(QueryFunction.EQ).leaf(ID_COLUMN_NAME)
+                .parameter("1").resolverDataType(ResolverDataType.INTEGER).build());
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(scopeLogicalBlock2).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // error reason: scopeFilter: /provided-nrCellDu[@cellLocalId=1] -> only id can be queried for associations
+        ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).innerContainer(
+                new ArrayList<>(Arrays.asList("provided-nrCellDu"))).container(ContainerType.ASSOCIATION)
+                .topologyObjectType(TopologyObjectType.ENTITY).queryFunction(QueryFunction.EQ).leaf("cellLocalId")
+                .parameter("1").resolverDataType(ResolverDataType.INTEGER).build());
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(scopeLogicalBlock3).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // for id the PRIMITIVE dataType is set
+        LogicalBlock logicalBlock4 = scopeResolver.process(GNBDU_FUNCTION, "/GNBDUFunction[@id='gnbdu1']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock4).build()));
+
+        basePathRefinement.validateScopeParametersDataType(filterCriteria);
+        Assertions.assertEquals(DataType.PRIMITIVE, ((ScopeLogicalBlock) logicalBlock4).getScopeObject().getDataType());
+
+        // error reason: for id INTEGER ResolverDataType is not accepted
+        LogicalBlock logicalBlock5 = scopeResolver.process(GNBDU_FUNCTION, "/GNBDUFunction[@id=1]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock5).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // error reason: for gNBCUName attribute INTEGER ResolverDataType is not accepted
+        LogicalBlock logicalBlock6 = scopeResolver.process("GNBCUCPFunction", "/attributes[@gNBCUName=1]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock6).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        // for sourceIds container PRIMITIVE dataType is set
+        LogicalBlock logicalBlock7 = scopeResolver.process(GNBDU_FUNCTION, "/sourceIds[@items = 'someSourceId']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock7).build()));
+
+        basePathRefinement.validateScopeParametersDataType(filterCriteria);
+
+        Assertions.assertEquals(DataType.PRIMITIVE, scopeLogicalBlock1.getScopeObject().getDataType());
+
+        // error reason: for sourceIds container INTEGER dataType is not accepted
+        LogicalBlock logicalBlock8 = scopeResolver.process(GNBDU_FUNCTION, "/sourceIds[@items = 1]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock8).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
                 filterCriteria));
+
+        // for decorators container PRIMITIVE dataType is accepted
+        LogicalBlock logicalBlock9 = scopeResolver.process(GNBDU_FUNCTION, "/decorators[@module-x:stringdata = 'ORAN']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock9).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
+
+        // for decorators container INTEGER dataType is accepted
+        LogicalBlock logicalBlock10 = scopeResolver.process(GNBDU_FUNCTION, "/decorators[@module-x:intdata = 2]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock10).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
+
+        LogicalBlock logicalBlock11 = scopeResolver.process(GNBDU_FUNCTION,
+                "/decorators[contains(@gnbdu-function-model:location, 'Stock')]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock11).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
+
+        //For classifiers container PRIMITIVE dataType is accepted
+        LogicalBlock logicalBlock12 = scopeResolver.process(GNBDU_FUNCTION,
+                "/classifiers[@item = 'gnbdu-function-model:Rural']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock12).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
+
+        //For classifiers container INTEGER dataType is NOT accepted
+        LogicalBlock logicalBlock13 = scopeResolver.process(GNBDU_FUNCTION, "/classifiers[@item = 23 ]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock13).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateScopeParametersDataType(
+                filterCriteria));
+
+        //for complex attribute INTEGER is accepted
+        LogicalBlock logicalBlock14 = scopeResolver.process(GNBDU_FUNCTION, "/attributes/dUpLMNId[@mnc = 2]");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock14).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
+
+        //for complex attribute PRIMITIVE is accepted
+        LogicalBlock logicalBlock15 = scopeResolver.process(GNBDU_FUNCTION, "/attributes/dUpLMNId[@mnc = 'some value']");
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(logicalBlock15).build()));
+
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.validateScopeParametersDataType(filterCriteria));
     }
 
     @Test
     void testCheckIfTargetMatchesWithScope() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        TargetObject targetObject1 = TargetObject.builder("GNBDUFunction").container(ContainerType.ATTRIBUTES).params(List
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        TargetObject targetObject1 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).params(List
                 .of("gNBId", "gNBIdLength")).build();
         TargetObject targetObject2 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).params(List.of(
                 "nCI")).build();
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject1, targetObject2)));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1, targetObject2))).build()));
 
         OrLogicalBlock orLogicalBlock1 = new OrLogicalBlock();
-        ScopeObject scopeObject1 = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBIdLength",
-                QueryFunction.EQ, "1", DataType.BIGINT);
-        ScopeObject scopeObject2 = new ScopeObject("GNBDUFunction", ContainerType.ATTRIBUTES, "gNBId", QueryFunction.EQ,
-                "8", DataType.BIGINT);
+
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).leaf(
+                "gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1").dataType(DataType.BIGINT).build();
+        ScopeObject scopeObject2 = ScopeObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).leaf("gNBId")
+                .queryFunction(QueryFunction.EQ).parameter("8").dataType(DataType.BIGINT).build();
 
         ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(scopeObject1);
         ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(scopeObject2);
         orLogicalBlock1.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock1, scopeLogicalBlock2)));
-        filterCriteria.setScope(orLogicalBlock1);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1, targetObject2))).scope(orLogicalBlock1).build()));
 
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.checkIfTargetMatchesWithScope(
-                filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.checkIfTargetMatchesWithScope(
+                filterCriteria.getFilterCriteriaList().get(0), filterCriteria.getDomain()));
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1))).scope(orLogicalBlock1).build()));
 
-        filterCriteria.setTargets(new ArrayList<>(Arrays.asList(targetObject1)));
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.checkIfTargetMatchesWithScope(filterCriteria
+                .getFilterCriteriaList().get(0), filterCriteria.getDomain()));
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.checkIfTargetMatchesWithScope(filterCriteria));
+        ScopeObject scopeObject3 = ScopeObject.builder("NRSectorCarrier").container(ContainerType.ATTRIBUTES).leaf(
+                "arfcnUL").queryFunction(QueryFunction.EQ).parameter("8").dataType(DataType.BIGINT).build();
 
-        ScopeObject scopeObject3 = new ScopeObject("NRSectorCarrier", ContainerType.ATTRIBUTES, "arfcnUL", QueryFunction.EQ,
-                "8", DataType.BIGINT);
         ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(scopeObject3);
-        filterCriteria.setScope(scopeLogicalBlock3);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1))).scope(scopeLogicalBlock3).build()));
 
-        Assertions.assertThrows(TiesPathException.class, () -> BasePathRefinement.checkIfTargetMatchesWithScope(
-                filterCriteria));
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.checkIfTargetMatchesWithScope(
+                filterCriteria.getFilterCriteriaList().get(0), filterCriteria.getDomain()));
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(Collections.emptyList()).scope(
+                scopeLogicalBlock3).build()));
 
-        filterCriteria.setTargets(Collections.emptyList());
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.checkIfTargetMatchesWithScope(filterCriteria
+                .getFilterCriteriaList().get(0), filterCriteria.getDomain()));
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.checkIfTargetMatchesWithScope(filterCriteria));
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(Collections.emptyList()).scope(
+                EmptyLogicalBlock.getInstance()).build()));
 
-        filterCriteria.setScope(EmptyLogicalBlock.getInstance());
+        Assertions.assertDoesNotThrow(() -> basePathRefinement.checkIfTargetMatchesWithScope(filterCriteria
+                .getFilterCriteriaList().get(0), filterCriteria.getDomain()));
 
-        Assertions.assertDoesNotThrow(() -> BasePathRefinement.checkIfTargetMatchesWithScope(filterCriteria));
+    }
 
+    @Test
+    void testSplitFilterCriteria() {
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        TargetObject targetObject1 = TargetObject.builder(GNBDU_FUNCTION).container(ContainerType.ATTRIBUTES).params(List
+                .of("gNBId", "gNBIdLength")).build();
+        TargetObject targetObject2 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).params(List.of(
+                "nCI")).build();
+        TargetObject targetObject3 = TargetObject.builder("NRCellDU").container(ContainerType.ATTRIBUTES).params(List.of(
+                "nRPCI")).build();
+        TargetObject targetObject4 = TargetObject.builder("EUtranCell").container(ContainerType.ATTRIBUTES).params(List.of(
+                "earFcn", "fdn")).isAllParamQueried(true).build();
+
+        ScopeObject scopeObject1 = ScopeObject.builder(GNBDU_FUNCTION).leaf("leaf1").build();
+        ScopeObject scopeObject2 = ScopeObject.builder("NRCellDU").leaf("leaf1").build();
+        ScopeObject scopeObject3 = ScopeObject.builder("EUtranCell").leaf("leaf1").build();
+        ScopeObject scopeObject4 = ScopeObject.builder(GNBDU_FUNCTION).leaf("leaf2").build();
+        ScopeObject scopeObject5 = ScopeObject.builder("NRCellDU").leaf("leaf2").build();
+        ScopeObject scopeObject6 = ScopeObject.builder("EUtranCell").leaf("leaf2").build();
+
+        OrLogicalBlock or1 = new OrLogicalBlock();
+        AndLogicalBlock and1 = new AndLogicalBlock();
+        AndLogicalBlock and2 = new AndLogicalBlock();
+        OrLogicalBlock or2 = new OrLogicalBlock();
+        OrLogicalBlock or3 = new OrLogicalBlock();
+
+        or1.getChildren().add(or2);
+        or1.getChildren().add(and1);
+        and1.getChildren().add(and2);
+        and2.getChildren().add(or3);
+        or2.getChildren().add(new ScopeLogicalBlock(scopeObject1));
+        or2.getChildren().add(new ScopeLogicalBlock(scopeObject2));
+        and1.getChildren().add(new ScopeLogicalBlock(scopeObject3));
+        and2.getChildren().add(new ScopeLogicalBlock(scopeObject4));
+        or3.getChildren().add(new ScopeLogicalBlock(scopeObject5));
+        or3.getChildren().add(new ScopeLogicalBlock(scopeObject6));
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().targets(new ArrayList<>(Arrays.asList(
+                targetObject1, targetObject2, targetObject3, targetObject4))).scope(or1).build()));
+
+        basePathRefinement.splitFilterCriteria(filterCriteria);
+
+        OrLogicalBlock fc1or1 = new OrLogicalBlock();
+
+        fc1or1.getChildren().add(new ScopeLogicalBlock(scopeObject1));
+        fc1or1.getChildren().add(new ScopeLogicalBlock(scopeObject4));
+
+        OrLogicalBlock fc2or1 = new OrLogicalBlock();
+
+        fc2or1.getChildren().add(new ScopeLogicalBlock(scopeObject2));
+        fc2or1.getChildren().add(new ScopeLogicalBlock(scopeObject5));
+
+        AndLogicalBlock fc3and1 = new AndLogicalBlock();
+        fc3and1.getChildren().add(new ScopeLogicalBlock(scopeObject6));
+        fc3and1.getChildren().add(new ScopeLogicalBlock(scopeObject3));
+
+        InnerFilterCriteria innerFilterCriteria1 = InnerFilterCriteria.builder().targets(List.of(targetObject1)).scope(
+                fc1or1).build();
+        InnerFilterCriteria innerFilterCriteria2 = InnerFilterCriteria.builder().targets(List.of(targetObject2,
+                targetObject3)).scope(fc2or1).build();
+        InnerFilterCriteria innerFilterCriteria3 = InnerFilterCriteria.builder().targets(List.of(targetObject4)).scope(
+                fc3and1).build();
+
+        Assertions.assertEquals(Set.of(innerFilterCriteria1, innerFilterCriteria2, innerFilterCriteria3), new HashSet<>(
+                filterCriteria.getFilterCriteriaList()));
     }
 
     @Test
     void testValidateQuery() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
-        Assertions.assertThrows(NotImplementedException.class, () -> BasePathRefinement.validateQuery(filterCriteria));
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(null);
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder("NRCellDU").build());
+        ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(ScopeObject.builder("NRSectorCarrier").build());
+        ScopeLogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(null);
+        ScopeLogicalBlock scopeLogicalBlock5 = new ScopeLogicalBlock(null);
+        ScopeLogicalBlock scopeLogicalBlock6 = new ScopeLogicalBlock(null);
+        AndOrLogicalBlock orLogicalBlock1 = new OrLogicalBlock();
+        AndOrLogicalBlock orLogicalBlock2 = new OrLogicalBlock();
+        AndOrLogicalBlock orLogicalBlock3 = new OrLogicalBlock();
+        AndOrLogicalBlock andLogicalBlock1 = new AndLogicalBlock();
+        AndOrLogicalBlock andLogicalBlock2 = new AndLogicalBlock();
+
+        orLogicalBlock1.setChildren(new ArrayList<>(Arrays.asList(orLogicalBlock2, andLogicalBlock1)));
+        orLogicalBlock2.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock1, andLogicalBlock2)));
+        andLogicalBlock2.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock2, scopeLogicalBlock3)));
+        andLogicalBlock1.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock4, orLogicalBlock3)));
+        orLogicalBlock3.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock5, scopeLogicalBlock6)));
+
+        scopeLogicalBlock1.setValid(false);
+        scopeLogicalBlock4.setValid(false);
+        scopeLogicalBlock6.setValid(false);
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(orLogicalBlock1).build()));
+
+        basePathRefinement.validateQuery(filterCriteria);
+
+        Assertions.assertEquals(andLogicalBlock2, filterCriteria.getFilterCriteriaList().get(0).getScope());
+
+        ScopeLogicalBlock scopeLogicalBlock2_1 = new ScopeLogicalBlock(null);
+        ScopeLogicalBlock scopeLogicalBlock2_2 = new ScopeLogicalBlock(null);
+        AndOrLogicalBlock andLogicalBlock2_1 = new AndLogicalBlock();
+
+        scopeLogicalBlock2_1.setValid(false);
+
+        andLogicalBlock2_1.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock2_1, scopeLogicalBlock2_2)));
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(andLogicalBlock2_1).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateQuery(filterCriteria));
+
+        ScopeLogicalBlock scopeLogicalBlock3_1 = new ScopeLogicalBlock(null);
+        ScopeLogicalBlock scopeLogicalBlock3_2 = new ScopeLogicalBlock(null);
+        AndOrLogicalBlock orLogicalBlock3_1 = new OrLogicalBlock();
+
+        scopeLogicalBlock3_2.setValid(false);
+        scopeLogicalBlock3_1.setValid(false);
+
+        orLogicalBlock3_1.setChildren(new ArrayList<>(Arrays.asList(scopeLogicalBlock3_1, scopeLogicalBlock3_2)));
+
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(orLogicalBlock3_1).build()));
+
+        Assertions.assertThrows(TiesPathException.class, () -> basePathRefinement.validateQuery(filterCriteria));
     }
 
     @Test
     void testRunOnTree() {
-        FilterCriteria filterCriteria = new FilterCriteria("RAN_LOGICAL");
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").build();
         OrLogicalBlock orLogicalBlock = new OrLogicalBlock();
-        filterCriteria.setScope(orLogicalBlock);
+        filterCriteria.setFilterCriteriaList(List.of(InnerFilterCriteria.builder().scope(orLogicalBlock).build()));
         OrLogicalBlock orLogicalBlockChild1 = new OrLogicalBlock();
         OrLogicalBlock orLogicalBlockChild2 = new OrLogicalBlock();
 
-        LogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES,
-                "gNBIdLength", QueryFunction.EQ, "1", DataType.BIGINT));
-        LogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES,
-                "gNBIdLength", QueryFunction.EQ, "2", DataType.BIGINT));
-        LogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES,
-                "gNBIdLength", QueryFunction.EQ, "3", DataType.BIGINT));
-        LogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES,
-                "gNBIdLength", QueryFunction.EQ, "4", DataType.BIGINT));
+        LogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("1").dataType(
+                        DataType.BIGINT).build());
+        LogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("2").dataType(
+                        DataType.BIGINT).build());
+        LogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("3").dataType(
+                        DataType.BIGINT).build());
+        LogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(ScopeObject.builder(GNBDU_FUNCTION).container(
+                ContainerType.ATTRIBUTES).leaf("gNBIdLength").queryFunction(QueryFunction.EQ).parameter("4").dataType(
+                        DataType.BIGINT).build());
 
         orLogicalBlockChild1.setChildren(Arrays.asList(scopeLogicalBlock1, scopeLogicalBlock2));
         orLogicalBlockChild2.setChildren(Arrays.asList(scopeLogicalBlock3, scopeLogicalBlock4));
         orLogicalBlock.setChildren(Arrays.asList(orLogicalBlockChild1, orLogicalBlockChild2));
 
-        BasePathRefinement.runOnTree(orLogicalBlock, filterCriteria.getDomain(), (ScopeLogicalBlock lb, String domain) -> lb
+        basePathRefinement.runOnTree(orLogicalBlock, filterCriteria.getDomain(), (ScopeLogicalBlock lb, String domain) -> lb
                 .getScopeObject().setParameter("0"));
 
         Assertions.assertEquals("0", ((ScopeLogicalBlock) scopeLogicalBlock1).getScopeObject().getParameter());
index 95eaecf..4051be4 100644 (file)
  */
 package org.oran.smo.teiv.exposure.tiespath.refiner;
 
+import java.util.List;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.InnerFilterCriteria;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.QueryFunction;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeLogicalBlock;
-import org.oran.smo.teiv.exposure.tiespath.innerlanguage.FilterCriteria;
 import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeObject;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TargetObject;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.TopologyObjectType;
 import org.oran.smo.teiv.schema.DataType;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.apache.commons.lang3.NotImplementedException;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 
-public class PathToJooqRefinementTest {
-    @Test
-    void toJooqTest() {
-        Assertions.assertThrows(NotImplementedException.class, () -> PathToJooqRefinement.toJooq(new FilterCriteria(
-                "RAN_LOGICAL")));
+class PathToJooqRefinementTest {
+
+    @BeforeAll
+    static void setUp() throws SchemaLoaderException {
+        new MockSchemaLoader().loadSchemaRegistry();
     }
 
     @Test
-    void logicalBlockToJooqTest() {
-        ScopeObject scopeObject = new ScopeObject("GNDBUFunction", ContainerType.ATTRIBUTES, "gNBIdLength",
-                QueryFunction.EQ, "1", DataType.BIGINT);
-        Assertions.assertThrows(NotImplementedException.class, () -> PathToJooqRefinement.logicalBlockToJooq(
-                new ScopeLogicalBlock(scopeObject)));
+    void basicToJooqTest() {
+        FilterCriteria filterCriteria = FilterCriteria.builder("RAN").filterCriteriaList(List.of(InnerFilterCriteria
+                .builder().targets(List.of(TargetObject.builder("GNBDUFunction").topologyObjectType(
+                        TopologyObjectType.ENTITY).container(ContainerType.ATTRIBUTES).params(List.of("gNBDUId")).build()))
+                .scope(new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").topologyObjectType(
+                        TopologyObjectType.ENTITY).container(ContainerType.ID).dataType(DataType.PRIMITIVE).parameter("123")
+                        .queryFunction(QueryFunction.EQ).build())).build())).build();
+
+        //spotless:off
+        Assertions.assertEquals("(\n" +
+                "  select\n" +
+                "    null \"o-ran-smo-teiv-ran:GNBDUFunction.id\",\n" +
+                "    null::bigint \"o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId\",\n" +
+                "    (\n" +
+                "      select count(*)\n" +
+                "      from (\n" +
+                "        select ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" \"o-ran-smo-teiv-ran:GNBDUFunction.id\"\n" +
+                "        from ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\"\n" +
+                "        where ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" = '123'\n" +
+                "      ) \"alias_87147237\"\n" +
+                "    ) \"count\"\n" +
+                ")\n" +
+                "union all (\n" +
+                "  select\n" +
+                "    \"o-ran-smo-teiv-ran:GNBDUFunction.id\",\n" +
+                "    \"o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId\",\n" +
+                "    null \"count\"\n" +
+                "  from (\n" +
+                "    select\n" +
+                "      ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" \"o-ran-smo-teiv-ran:GNBDUFunction.id\",\n" +
+                "      ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"gNBDUId\" \"o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId\"\n" +
+                "    from ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\"\n" +
+                "    where ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\".\"id\" = '123'\n" +
+                "    order by \"o-ran-smo-teiv-ran:GNBDUFunction.id\" asc\n" +
+                "  ) \"alias_49572850\"\n" +
+                "  limit 100\n" +
+                "  offset 0\n" +
+                ")", PathToJooqRefinement.toJooq(filterCriteria,0,100).toString());
+        //spotless:on
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolverTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/tiespath/resolver/ScopeResolverTest.java
new file mode 100644 (file)
index 0000000..72badc0
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ *  ============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.teiv.exposure.tiespath.resolver;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.AndOrLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ContainerType;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.EmptyLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.LogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.OrLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.QueryFunction;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeLogicalBlock;
+import org.oran.smo.teiv.exposure.tiespath.innerlanguage.ScopeObject;
+import org.oran.smo.teiv.utils.query.exception.TiesPathException;
+
+class ScopeResolverTest {
+
+    private final ScopeResolver scopeResolver = new ScopeResolver();
+
+    @Test
+    void testEmptyScope() {
+        LogicalBlock expected = EmptyLogicalBlock.getInstance();
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, null);
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void resolveScopeWithMultipleTokensWithSameContainer() {
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gnBId").queryFunction(QueryFunction.EQ).parameter("1").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("date").queryFunction(QueryFunction.EQ).parameter("2").resolverDataType(
+                        ResolverDataType.STRING).build());
+        ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("refs").queryFunction(QueryFunction.EQ).parameter("12341").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(ScopeObject.builder("*").container(
+                ContainerType.ATTRIBUTES).leaf("fdn").queryFunction(QueryFunction.CONTAINS).parameter("GNBDUFunction=10")
+                .resolverDataType(ResolverDataType.STRING).build());
+        AndOrLogicalBlock logicalBlock1 = new AndLogicalBlock();
+        AndOrLogicalBlock logicalBlock2 = new OrLogicalBlock();
+        AndOrLogicalBlock logicalBlock3 = new AndLogicalBlock();
+        logicalBlock1.addChild(scopeLogicalBlock1);
+        logicalBlock1.addChild(scopeLogicalBlock2);
+        logicalBlock2.addChild(logicalBlock1);
+        logicalBlock2.addChild(scopeLogicalBlock3);
+        logicalBlock3.addChild(scopeLogicalBlock4);
+        logicalBlock3.addChild(logicalBlock2);
+        final LogicalBlock resolverLB = scopeResolver.resolve(null,
+                "/GNBDUFunction/attributes[@gnBId = 1 and @date = \"2\" or @refs = 12341];/attributes[contains(@fdn,\"'GNBDUFunction=10'\")]");
+        Assertions.assertEquals(logicalBlock3, resolverLB);
+    }
+
+    @Test
+    void resolveScopeWithMultipleTokensWithDifferentContainers() {
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("gnBId").queryFunction(QueryFunction.EQ).parameter("1").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("date").queryFunction(QueryFunction.EQ).parameter("2").resolverDataType(
+                        ResolverDataType.STRING).build());
+        ScopeLogicalBlock scopeLogicalBlock3 = new ScopeLogicalBlock(ScopeObject.builder("GNBDUFunction").container(
+                ContainerType.ATTRIBUTES).leaf("refs").queryFunction(QueryFunction.EQ).parameter("12341").resolverDataType(
+                        ResolverDataType.INTEGER).build());
+        ScopeLogicalBlock scopeLogicalBlock4 = new ScopeLogicalBlock(ScopeObject.builder("*").container(
+                ContainerType.DECORATORS).leaf("vendor").queryFunction(QueryFunction.CONTAINS).parameter("ORAN")
+                .resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock scopeLogicalBlock5 = new ScopeLogicalBlock(ScopeObject.builder("*").container(
+                ContainerType.CLASSIFIERS).leaf("item").queryFunction(QueryFunction.EQ).parameter("cmHandle")
+                .resolverDataType(ResolverDataType.STRING).build());
+        ScopeLogicalBlock scopeLogicalBlock6 = new ScopeLogicalBlock(ScopeObject.builder("*").container(
+                ContainerType.SOURCE_IDS).leaf("item").queryFunction(QueryFunction.EQ).parameter("fdn1").resolverDataType(
+                        ResolverDataType.STRING).build());
+        AndOrLogicalBlock logicalBlock1 = new AndLogicalBlock();
+        AndOrLogicalBlock logicalBlock2 = new OrLogicalBlock();
+        AndOrLogicalBlock logicalBlock3 = new OrLogicalBlock();
+        AndOrLogicalBlock logicalBlock4 = new AndLogicalBlock();
+        AndOrLogicalBlock logicalBlock5 = new OrLogicalBlock();
+        logicalBlock1.addChild(scopeLogicalBlock1);
+        logicalBlock1.addChild(scopeLogicalBlock2);
+        logicalBlock2.addChild(logicalBlock1);
+        logicalBlock2.addChild(scopeLogicalBlock3);
+        logicalBlock3.addChild(logicalBlock2);
+        logicalBlock3.addChild(scopeLogicalBlock4);
+        logicalBlock4.addChild(scopeLogicalBlock5);
+        logicalBlock4.addChild(logicalBlock3);
+        logicalBlock5.addChild(scopeLogicalBlock6);
+        logicalBlock5.addChild(logicalBlock4);
+
+        final LogicalBlock resolverLB = scopeResolver.resolve(null,
+                "/decorators[contains(@vendor, 'ORAN')]|/GNBDUFunction/attributes[@gnBId = 1 and @date = '2' or @refs = 12341] ; " + "/classifiers[@item = 'cmHandle']| /sourceIds[@item = 'fdn1']");
+        Assertions.assertEquals(logicalBlock5, resolverLB,
+                "If in test failure contents are identical  then check if AndLB/OrLB are used appropriately");
+    }
+
+    @Test
+    void testRelationshipInScope() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ManagedElement").container(null)
+                .innerContainer(List.of("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION")).leaf(null).queryFunction(
+                        QueryFunction.NOT_NULL).parameter(null).resolverDataType(ResolverDataType.NOT_NULL).build());
+        final LogicalBlock logicalBlock = scopeResolver.resolve("ManagedElement", "/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
+        Assertions.assertEquals(expected, logicalBlock);
+    }
+
+    @Test
+    void testNoLeavesInScope() {
+        ScopeLogicalBlock scopeLogicalBlock1 = new ScopeLogicalBlock(ScopeObject.builder("ENodeBFunction").container(null)
+                .innerContainer(List.of("managed-by-managedObject")).leaf(null).queryFunction(QueryFunction.NOT_NULL)
+                .parameter(null).resolverDataType(ResolverDataType.NOT_NULL).build());
+        ScopeLogicalBlock scopeLogicalBlock2 = new ScopeLogicalBlock(ScopeObject.builder(null).container(null)
+                .innerContainer(List.of("managed-by-managedObject")).leaf("id").queryFunction(QueryFunction.EQ).parameter(
+                        "me1").resolverDataType(ResolverDataType.STRING).build());
+        AndOrLogicalBlock logicalBlock = new AndLogicalBlock();
+        logicalBlock.addChild(scopeLogicalBlock1);
+        logicalBlock.addChild(scopeLogicalBlock2);
+        final LogicalBlock actualLogicalBlock = scopeResolver.resolve(null,
+                "/managed-by-managedObject[@id='me1']; /ENodeBFunction/managed-by-managedObject");
+        Assertions.assertEquals(logicalBlock, actualLogicalBlock);
+    }
+
+    @Test
+    void testResolveAssociationWithoutRootObjectInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder(null).container(null).innerContainer(List.of(
+                "managed-by-managedObject")).leaf("id").queryFunction(QueryFunction.EQ).parameter("me1").resolverDataType(
+                        ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, "/managed-by-managedObject[@id='me1']");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testEqualTextFunction() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("*").container(ContainerType.ID).leaf(null)
+                .queryFunction(QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, "/id[text()='me1']");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testContainsTxtFunctionCondition() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("*").container(ContainerType.ID).leaf(null)
+                .queryFunction(QueryFunction.CONTAINS).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, "/id[contains(text(),'me1')]");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testExceptionWhenTextConditionUsedOnOtherThanID() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> scopeResolver.resolve(null,
+                "/ManagedElement[text()='me1']"));
+        assertEquals("text() is supported for ID only", thrown.getDetails());
+    }
+
+    @Test
+    void testResolveWithRootObjectAndAssociationInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ENodeBFunction").container(null)
+                .innerContainer(List.of("managed-by-managedObject")).leaf("id").queryFunction(QueryFunction.EQ).parameter(
+                        "me1").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve("ENodeBFunction", "/managed-by-managedObject[@id='me1']");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testResolveWithRootObjectAndEntityInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ManagedElement").container(null)
+                .innerContainer(List.of("GNBDUFunction")).leaf("id").queryFunction(QueryFunction.CONTAINS).parameter("me1")
+                .resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve("ManagedElement", "/GNBDUFunction[contains(@id,'me1')]");
+        Assertions.assertEquals(expected, resolvedScope);
+
+    }
+
+    @Test
+    void testResolveObjectWithTopologyObjectInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ManagedElement").container(ContainerType.ID)
+                .queryFunction(QueryFunction.EQ).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve("ManagedElement", "/ManagedElement[@id='me1']");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testResolveComplexAttributeInScopeFilter() {
+        //Without root object & Entity type provided in the container
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ATTRIBUTES).innerContainer(List.of("pLMNId")).leaf("mcc").queryFunction(QueryFunction.EQ)
+                .parameter("01").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, "/GNBCUCPFunction/attributes/pLMNId[@mcc='01']");
+        Assertions.assertEquals(expected, resolvedScope);
+
+        //Without root object & Entity type not provided
+        ScopeLogicalBlock expected1 = new ScopeLogicalBlock(ScopeObject.builder(null).container(ContainerType.ATTRIBUTES)
+                .innerContainer(List.of("pLMNId")).leaf("mcc").queryFunction(QueryFunction.EQ).parameter("01")
+                .resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope1 = scopeResolver.resolve(null, "/attributes/pLMNId[@mcc='01']");
+        Assertions.assertEquals(expected1, resolvedScope1);
+
+        //With root object & Entity type provided in the container
+        ScopeLogicalBlock expected2 = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ATTRIBUTES).innerContainer(List.of("pLMNId")).leaf("mcc").queryFunction(QueryFunction.EQ)
+                .parameter("01").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope2 = scopeResolver.resolve("GNBCUCPFunction",
+                "/GNBCUCPFunction/attributes/pLMNId[@mcc='01']");
+        Assertions.assertEquals(expected2, resolvedScope2);
+
+        //With root object & Entity type not provided
+        ScopeLogicalBlock expected3 = new ScopeLogicalBlock(ScopeObject.builder("GNBCUCPFunction").container(
+                ContainerType.ATTRIBUTES).innerContainer(List.of("pLMNId")).leaf("mcc").queryFunction(QueryFunction.EQ)
+                .parameter("01").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope3 = scopeResolver.resolve("GNBCUCPFunction", "/attributes/pLMNId[@mcc='01']");
+        Assertions.assertEquals(expected3, resolvedScope3);
+
+        //With root object & wrong Entity type not provided
+        final TiesPathException exception = assertThrows(TiesPathException.class, () -> scopeResolver.resolve(
+                "GNBCUCPFunction", "/GNBDUFunction/attributes/pLMNId[@mcc='01']"));
+        Assertions.assertEquals("Target/Scope filter can only contain Root Object types mentioned in the path parameter",
+                exception.getDetails());
+    }
+
+    @Test
+    void testExceptionWithTopologyObjectInScopeFilterWhichDoesNotHaveValidContainerTypeInLeaf() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> scopeResolver.resolve("ManagedElement",
+                "/ManagedElement[@id1='me1']"));
+        assertEquals("id1 is not a valid leaf for topology object: ManagedElement", thrown.getDetails());
+    }
+
+    @Test
+    void testExceptionWithScopeFilterLeafButNoCondition() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> scopeResolver.resolve("ManagedElement",
+                "/GNBDUFunction(fdn))"));
+        assertEquals("Parameter without any condition is not supported in scope filter", thrown.getDetails());
+    }
+
+    @Test
+    void testSameRootObjectAndContainerNameButNonMatchingContainerTypeInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ManagedElement").container(ContainerType.ID)
+                .queryFunction(QueryFunction.CONTAINS).parameter("me1").resolverDataType(ResolverDataType.STRING).build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve("ManagedElement", "/ManagedElement[contains(@id,'me1')]");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testWithNoRootObjectAndNonMatchingContainerTypeInScopeFilter() {
+        ScopeLogicalBlock expected = new ScopeLogicalBlock(ScopeObject.builder("ManagedElement").container(null)
+                .queryFunction(QueryFunction.CONTAINS).parameter("me1").resolverDataType(ResolverDataType.STRING)
+                .innerContainer(List.of("attr")).leaf("id").build());
+        final LogicalBlock resolvedScope = scopeResolver.resolve(null, "/ManagedElement/attr[contains(@id,'me1')]");
+        Assertions.assertEquals(expected, resolvedScope);
+    }
+
+    @Test
+    void testWithNonMatchingRootObjectInScopeFilter() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> scopeResolver.resolve("GNBDUFunction",
+                "/ManagedElement/attr[contains(@id,'me1')]"));
+        assertEquals("Target/Scope filter can only contain Root Object types mentioned in the path parameter", thrown
+                .getDetails());
+    }
+
+}
index 6807f32..5e3d4b6 100644 (file)
@@ -34,19 +34,19 @@ import org.oran.smo.teiv.utils.query.exception.TiesPathException;
 
 class TargetResolverTest {
 
-    private TargetResolver targetResolver = new TargetResolver();
+    private final TargetResolver targetResolver = new TargetResolver();
 
     @Test
     void testIdOnlyWhenTopologyObjectInRootObjectType() {
         List<TargetObject> expectedObject = List.of(TargetObject.builder("GNBDUFunction").build());
 
-        Assertions.assertEquals(expectedObject, targetResolver.resolve("GNBDUFunction", ""));
+        Assertions.assertEquals(expectedObject, targetResolver.resolve("GNBDUFunction", null));
     }
 
     @Test
     void testIdOnlyWhenTopologyObjectAndContainerInTargetOnlyTest() {
         List<TargetObject> expectedObject = List.of(TargetObject.builder("ENodeBFunction").build());
-        Assertions.assertEquals(expectedObject, targetResolver.resolve("", "/ENodeBFunction/id"));
+        Assertions.assertEquals(expectedObject, targetResolver.resolve(null, "/ENodeBFunction/id"));
     }
 
     @Test
@@ -65,15 +65,15 @@ class TargetResolverTest {
 
     @Test
     void testExceptionWhenTopologyObjectInTargetWithParamButNoMatchingContainer() {
-        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("",
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
                 "/GNBDUFunction(fdn, enbId)"));
         assertEquals("Attributes cannot be associated at this level", thrown.getDetails());
     }
 
     @Test
     void testEmptyTargetAndRootObjectType() {
-        List<TargetObject> expectedObject = List.of(TargetObject.builder("*" + "").build());
-        Assertions.assertEquals(expectedObject, targetResolver.resolve("", ""));
+        List<TargetObject> expectedObject = List.of(TargetObject.builder("*").build());
+        Assertions.assertEquals(expectedObject, targetResolver.resolve(null, null));
     }
 
     @Test
@@ -86,7 +86,7 @@ class TargetResolverTest {
     @Test
     void testAllAttributesWithEmptyRootObject() {
         List<TargetObject> expectedObject = List.of(TargetObject.builder("*").container(ContainerType.ATTRIBUTES).build());
-        Assertions.assertEquals(expectedObject, targetResolver.resolve("", "/attributes"));
+        Assertions.assertEquals(expectedObject, targetResolver.resolve(null, "/attributes"));
     }
 
     @Test
@@ -98,6 +98,13 @@ class TargetResolverTest {
 
     }
 
+    @Test
+    void testAttributesOnSourceIds() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
+                "/GNBDUFunction/sourceIds(fdn, enbId)"));
+        assertEquals("Parameters are not supported for sourceIds in target filter", thrown.getDetails());
+    }
+
     @Test
     void testLogicalANDWithTwoDifferentContainersTypes() {
         List<TargetObject> expectedObject = List.of(TargetObject.builder("GNBDUFunction").container(
@@ -108,36 +115,41 @@ class TargetResolverTest {
     }
 
     @Test
-    void testLogicalANDWithTwoDifferentContainersTypesWithAttributes() {
+    void testLogicalANDWithTwoDifferentContainersTypesOneWithParams() {
         List<TargetObject> expectedObject = List.of(TargetObject.builder("GNBDUFunction").container(
                 ContainerType.ATTRIBUTES).params(List.of("fdn", "enbId")).build(), TargetObject.builder("GNBDUFunction")
-                        .container(ContainerType.DECORATORS).params(List.of("module-x:location", "module-y:vendor"))
-                        .build());
-        Assertions.assertEquals(expectedObject, targetResolver.resolve("",
-                "/GNBDUFunction/attributes(fdn, enbId);" + "/GNBDUFunction/decorators(module-x:location,module-y:vendor)"));
+                        .container(ContainerType.DECORATORS).build());
+        Assertions.assertEquals(expectedObject, targetResolver.resolve(null,
+                "/GNBDUFunction/attributes(fdn, enbId);" + "/GNBDUFunction/decorators"));
+    }
+
+    @Test
+    void testExceptionWithParamOnDecorators() {
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
+                "/GNBDUFunction/attributes(fdn, enbId); /GNBDUFunction/decorators(module-x:location,module-y:vendor)"));
+        assertEquals("Parameters are not supported for decorators in target filter", thrown.getDetails());
     }
 
     @Test
     void testExceptionWithMoreThanTwoLevel() {
-        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("",
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
                 "/GNBDUFunction/NRCellDU/attributes"));
         assertEquals("More than two level deep path is not allowed", thrown.getDetails());
     }
 
     @Test
     void testExceptionWithPipeInTargetFilter() {
-        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("",
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
                 "/GNBDUFunction/attributes(fdn, enbId)|/GNBDUFunction/classifiers"));
         assertEquals("OR (|) is not supported for target filter", thrown.getDetails());
     }
 
-    /* ToDo Below test will be activated when scopeFilter work is done
-       @Test
+    @Test
     void testExceptionWithScopeFilterInTargetFilter() {
         TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("GNBDUFunction",
-                "/GNBDUFunction/attributes[@gNBIdLength=3]"));
-        assertEquals("Condition of parameter(s) is not supported for target filter", thrown.getDetails());
-    }*/
+                "/GNBDUFunction/attributes[@gNBIdLength=3 or @abc=5 ]"));
+        assertEquals("Parameter condition is not supported in target filter", thrown.getDetails());
+    }
 
     @Test
     void testTargetWithoutSlash() {
@@ -158,14 +170,21 @@ class TargetResolverTest {
     void testDifferentTopologyObjectInTargetFilterWithAttributesAndRootObjectType() {
         TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("GNBDUFunction",
                 "/ENodeBFunction/attributes"));
-        assertEquals("Target filter can only contain Root Object types mentioned in the path parameter", thrown
+        assertEquals("Target/Scope filter can only contain Root Object types mentioned in the path parameter", thrown
                 .getDetails());
     }
 
     @Test
     void testEmptyRootObjectTypeWithOneOfTheWrongTargetToken() {
-        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve("",
+        TiesPathException thrown = assertThrows(TiesPathException.class, () -> targetResolver.resolve(null,
                 "/GNBDUFunction/attributes(fdn, enbId);/GNBDUFunction/NRCellDU/attributes"));
         assertEquals("More than two level deep path is not allowed", thrown.getDetails());
     }
+
+    @Test
+    void testTargetResolverWithTwoObjects() {
+        List<TargetObject> expectedObject = List.of(TargetObject.builder("GNBDUFunction").build(), TargetObject.builder(
+                "ENodeBFunction").build());
+        Assertions.assertEquals(expectedObject, targetResolver.resolve(null, "/GNBDUFunction; /ENodeBFunction"));
+    }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/exposure/utils/PaginationUtilTest.java b/teiv/src/test/java/org/oran/smo/teiv/exposure/utils/PaginationUtilTest.java
new file mode 100644 (file)
index 0000000..f014237
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  ============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.teiv.exposure.utils;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.api.model.OranTeivHref;
+import org.oran.smo.teiv.exception.TiesException;
+
+class PaginationUtilTest {
+    private static final RequestDetails requestDetails = RequestDetails.builder().basePath("/test").queryParam("q1", "val2")
+            .offset(2).limit(5).build();
+
+    @Test
+    void testGetViableLimit() {
+        //offset and limit are less than totalCount
+        final int limit1 = PaginationUtil.getViableLimit(0, 5, 10);
+        assertEquals(5, limit1);
+
+        //offset is less than totalCount and limit is greater than totalCount
+        final int limit2 = PaginationUtil.getViableLimit(0, 5, 3);
+        assertEquals(3, limit2);
+
+        //totalCount is 0
+        final int limit3 = PaginationUtil.getViableLimit(0, 5, 0);
+        assertEquals(0, limit3);
+
+        //offset is greater than totalCount
+        TiesException exception = assertThrows(TiesException.class, () -> PaginationUtil.getViableLimit(15, 5, 10));
+        assertEquals("Offset cannot be larger than 9", exception.getDetails());
+    }
+
+    @Test
+    void firstHref() {
+        final OranTeivHref actual = PaginationUtil.firstHref(requestDetails);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=0&limit=5&q1=val2").build(), actual);
+    }
+
+    @Test
+    void prevHref() {
+        //totalCount < limit
+        final OranTeivHref actual1 = PaginationUtil.prevHref(requestDetails, 3);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=0&limit=5&q1=val2").build(), actual1);
+
+        //totalCount = limit
+        final OranTeivHref actual2 = PaginationUtil.prevHref(requestDetails, 5);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=0&limit=5&q1=val2").build(), actual2);
+
+        //totalCount > limit
+        final OranTeivHref actual3 = PaginationUtil.prevHref(requestDetails, 10);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=0&limit=5&q1=val2").build(), actual3);
+    }
+
+    @Test
+    void selfHref() {
+        final OranTeivHref actual = PaginationUtil.selfHref(requestDetails);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=2&limit=5&q1=val2").build(), actual);
+    }
+
+    @Test
+    void nextHref() {
+        //totalCount < limit
+        final OranTeivHref actual1 = PaginationUtil.nextHref(requestDetails, 3);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=2&limit=5&q1=val2").build(), actual1);
+
+        //totalCount = limit
+        final OranTeivHref actual2 = PaginationUtil.nextHref(requestDetails, 5);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=2&limit=5&q1=val2").build(), actual2);
+
+        //totalCount > limit
+        final OranTeivHref actual3 = PaginationUtil.nextHref(requestDetails, 10);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=7&limit=5&q1=val2").build(), actual3);
+    }
+
+    @Test
+    void lastHref() {
+        //totalCount < limit
+        final OranTeivHref actual = PaginationUtil.lastHref(requestDetails, 3);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=2&limit=5&q1=val2").build(), actual);
+
+        //totalCount = limit
+        final OranTeivHref actual1 = PaginationUtil.lastHref(requestDetails, 5);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=2&limit=5&q1=val2").build(), actual1);
+
+        //totalCount > limit
+        final OranTeivHref actual2 = PaginationUtil.lastHref(requestDetails, 10);
+
+        assertEquals(OranTeivHref.builder().href("/test?offset=7&limit=5&q1=val2").build(), actual2);
+    }
+}
index 2acc630..9b4ba46 100644 (file)
@@ -25,7 +25,6 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.schema.SchemaLoader;
 import org.oran.smo.teiv.schema.SchemaLoaderException;
 import org.oran.smo.teiv.schema.MockSchemaLoader;
 
@@ -35,7 +34,7 @@ class RequestValidatorTest {
 
     @BeforeAll
     static void setUp() throws SchemaLoaderException {
-        SchemaLoader mockSchemaLoader = new MockSchemaLoader();
+        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
         mockSchemaLoader.loadSchemaRegistry();
         requestValidator = new RequestValidator();
     }
@@ -74,15 +73,4 @@ class RequestValidatorTest {
                 "ANTENNAMODULE_INSTALLED_AT_SITE", "RAN"));
     }
 
-    @Test
-    void testValidateFiltersForRelationships() {
-        Assertions.assertDoesNotThrow(() -> requestValidator.validateFiltersForRelationships(null, null));
-        Assertions.assertDoesNotThrow(() -> requestValidator.validateFiltersForRelationships(null,
-                "/GNBDUFunction/attributes[contains (@fdn, \"Hungary\")]"));
-        Assertions.assertThrowsExactly(TiesException.class, () -> requestValidator.validateFiltersForRelationships(
-                "/attributes", "/GNBDUFunction/attributes[contains (@fdn, \"Hungary\")]"));
-        Assertions.assertThrowsExactly(TiesException.class, () -> requestValidator.validateFiltersForRelationships(null,
-                "/attributes[contains (@fdn, \"Hungary\")]"));
-    }
-
 }
index f97d05f..c6d9b22 100644 (file)
@@ -76,7 +76,7 @@ import jakarta.annotation.PostConstruct;
 @Configuration
 @SpringBootTest
 @ActiveProfiles({ "test", "ingestion" })
-public class IngestionOperationValidatorTest {
+class IngestionOperationValidatorTest {
     public static TestPostgresqlContainer postgresqlContainer = TestPostgresqlContainer.getInstance();
 
     @Autowired
@@ -128,26 +128,28 @@ public class IngestionOperationValidatorTest {
         //MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM is a 0..1 to 1 relationship
         List<Entity> entities = generateEntities(MAXIMUM_CARDINALITY_CASE.ONE_ONE);
         List<Relationship> relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-oam-to-cloud", "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM",
-                "rel_1", "ManagedElement_1", "CloudNativeSystem_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-oam-to-cloud", "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM",
-                "rel_2", "ManagedElement_2", "CloudNativeSystem_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-oam-to-cloud",
+                "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "rel_1", "ManagedElement_1", "CloudNativeSystem_1", List
+                        .of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-oam-to-cloud",
+                "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "rel_2", "ManagedElement_2", "CloudNativeSystem_1", List
+                        .of()));
         ParsedCloudEventData parsedCloudEventData = new ParsedCloudEventData(entities, relationships);
         //It's expected to fail, because the CloudNativeSystem_1 entity would be connected to 2 ManagedElement instances
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData));
 
         //The whole transaction is rolled back. Neither the entities nor the relationships are persisted.
-        assertEmptyTable("ties_data.\"ManagedElement\"");
-        assertEmptyTable("ties_data.\"CloudNativeSystem\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
+        assertEmptyTable("ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
 
         //Remove the extra relationship that caused the cardinality violation. Successfully insert the others.
         Relationship redundantRelationship = relationships.remove(1);
         ParsedCloudEventData parsedCloudEventData2 = new ParsedCloudEventData(entities, relationships);
         assertEquals(entities.size() + relationships.size(), tiesDbOperations.executeEntityAndRelationshipMergeOperations(
                 parsedCloudEventData2).size());
-        verify(spiedDbServiceForValidation).acquireEntityInstanceExclusiveLock("ties_data.\"CloudNativeSystem\"",
-                "CloudNativeSystem_1");
+        verify(spiedDbServiceForValidation).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"", "CloudNativeSystem_1");
 
         //Try to insert an extra relationship. It's expected to fail, because the CloudNativeSystem_1 entity already has the maximum number of relationships.
         ParsedCloudEventData parsedCloudEventData3 = new ParsedCloudEventData(List.of(), List.of(redundantRelationship));
@@ -160,30 +162,30 @@ public class IngestionOperationValidatorTest {
         // TESTENTITYA_USES_TESTENTITYB is a 0..1 to 0..2 relationship
         List<Entity> entities = generateEntities(MAXIMUM_CARDINALITY_CASE.ONE_CONST);
         List<Relationship> relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_USES_TESTENTITYB", "rel_1", "TestEntityA_1",
-                "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_USES_TESTENTITYB", "rel_2", "TestEntityA_1",
-                "TestEntityB_2", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_USES_TESTENTITYB", "rel_3", "TestEntityA_1",
-                "TestEntityB_3", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_USES_TESTENTITYB", "rel_1",
+                "TestEntityA_1", "TestEntityB_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_USES_TESTENTITYB", "rel_2",
+                "TestEntityA_1", "TestEntityB_2", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_USES_TESTENTITYB", "rel_3",
+                "TestEntityA_1", "TestEntityB_3", List.of()));
         ParsedCloudEventData parsedCloudEventData = new ParsedCloudEventData(entities, relationships);
         //It's expected to fail, because the TestEntityA_1 entity would be connected to 3 TestEntityB instances
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData));
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityA\"",
-                "TestEntityA_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"", "TestEntityA_1");
 
         //The whole transaction is rolled back. Neither the entities nor the relationships are persisted.
-        assertEmptyTable("ties_data.\"TestEntityA\"");
-        assertEmptyTable("ties_data.\"TestEntityB\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"");
 
         //Remove the extra relationship that caused the cardinality violation. Successfully insert the others.
         Relationship redundantRelationship = relationships.remove(2);
         ParsedCloudEventData parsedCloudEventData2 = new ParsedCloudEventData(entities, relationships);
         assertEquals(entities.size() + relationships.size(), tiesDbOperations.executeEntityAndRelationshipMergeOperations(
                 parsedCloudEventData2).size());
-        verify(spiedDbServiceForValidation, times(2)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityA\"",
-                "TestEntityA_1");
+        verify(spiedDbServiceForValidation, times(2)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"", "TestEntityA_1");
         verify(spiedDbServiceForValidation, times(2)).executeValidationQuery(any(), any(), any(), any(Long.class));
         verifyNoMoreInteractions(spiedDbServiceForValidation);
 
@@ -191,55 +193,55 @@ public class IngestionOperationValidatorTest {
         ParsedCloudEventData parsedCloudEventData3 = new ParsedCloudEventData(List.of(), List.of(redundantRelationship));
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData3));
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityA\"",
-                "TestEntityA_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"", "TestEntityA_1");
     }
 
     @Test
-    void maximumCardinalityViolationConstToConstRelationship() throws InvalidFieldInYangDataException {
+    void maximumCardinalityViolationConstToConstRelationship() {
         // TESTENTITYA_PROVIDES_TESTENTITYB is a 0..2 to 0..3 relationship
         List<Entity> entities = generateEntities(MAXIMUM_CARDINALITY_CASE.CONST_CONST);
         List<Relationship> relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_1",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_1",
                 "TestEntityA_1", "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_2",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_2",
                 "TestEntityA_1", "TestEntityB_2", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_3",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_3",
                 "TestEntityA_1", "TestEntityB_3", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_4",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_4",
                 "TestEntityA_1", "TestEntityB_4", List.of()));
         ParsedCloudEventData parsedCloudEventData = new ParsedCloudEventData(entities, relationships);
         //It's expected to fail, because the TestEntityA_1 entity would be connected to 4 TestEntityB instances
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData));
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_1");
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityA\"",
-                "TestEntityA_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"", "TestEntityA_1");
 
         //The whole transaction is rolled back. Neither the entities nor the relationships are persisted.
-        assertEmptyTable("ties_data.\"TestEntityA\"");
-        assertEmptyTable("ties_data.\"TestEntityB\"");
-        assertEmptyTable("ties_data.\"TESTENTITYA_PROVIDES_TESTENTITYB\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"");
+        assertEmptyTable("ties_data.\"73936e503f137d82d1422c0f08c66c7ff8b90209\"");
 
         //Test the other side's cardinality as well
         relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_1",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_1",
                 "TestEntityA_1", "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_2",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_2",
                 "TestEntityA_2", "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_3",
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_PROVIDES_TESTENTITYB", "rel_3",
                 "TestEntityA_3", "TestEntityB_1", List.of()));
 
         ParsedCloudEventData parsedCloudEventData2 = new ParsedCloudEventData(entities, relationships);
         //It's expected to fail, because the TestEntityB_1 entity would be connected to 3 TestEntityA instances
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData2));
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_1");
-        assertEmptyTable("ties_data.\"TestEntityA\"");
-        assertEmptyTable("ties_data.\"TestEntityB\"");
-        assertEmptyTable("ties_data.\"TESTENTITYA_PROVIDES_TESTENTITYB\"");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_1");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"");
+        assertEmptyTable("ties_data.\"73936e503f137d82d1422c0f08c66c7ff8b90209\"");
     }
 
     @Test
@@ -247,51 +249,50 @@ public class IngestionOperationValidatorTest {
         // TESTENTITYA_GROUPS_TESTENTITYB is a 0..2 to 0..n relationship
         List<Entity> entities = generateEntities(MAXIMUM_CARDINALITY_CASE.CONST_INFINITE);
         List<Relationship> relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_1", "TestEntityA_1",
-                "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_2", "TestEntityA_2",
-                "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_3", "TestEntityA_3",
-                "TestEntityB_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_1",
+                "TestEntityA_1", "TestEntityB_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_2",
+                "TestEntityA_2", "TestEntityB_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_3",
+                "TestEntityA_3", "TestEntityB_1", List.of()));
         ParsedCloudEventData parsedCloudEventData = new ParsedCloudEventData(entities, relationships);
         //It's expected to fail, because the TestEntityB_1 entity would be connected to 3 TestEntityB instances
         assertThrows(MaximumCardinalityViolationException.class, () -> tiesDbOperations
                 .executeEntityAndRelationshipMergeOperations(parsedCloudEventData));
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_1");
 
         //The whole transaction is rolled back. Neither the entities nor the relationships are persisted.
-        assertEmptyTable("ties_data.\"TestEntityA\"");
-        assertEmptyTable("ties_data.\"TestEntityB\"");
-        assertEmptyTable("ties_data.\"TESTENTITYA_GROUPS_TESTENTITYB\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityA\"");
+        assertEmptyTable("ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"");
+        assertEmptyTable("ties_data.\"70003c8082751e1832e7bc5c0d83db6d22c4fcdc\"");
 
         //Test the other side's cardinality
-        entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_2", Map.of(), List.of()));
-        entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_3", Map.of(), List.of()));
+        entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_2", Map.of(), List.of()));
+        entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_3", Map.of(), List.of()));
         relationships = new ArrayList<>();
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_1", "TestEntityA_1",
-                "TestEntityB_1", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_2", "TestEntityA_1",
-                "TestEntityB_2", List.of()));
-        relationships.add(new Relationship("o-ran-smo-teiv-ran", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_3", "TestEntityA_1",
-                "TestEntityB_3", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_1",
+                "TestEntityA_1", "TestEntityB_1", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_2",
+                "TestEntityA_1", "TestEntityB_2", List.of()));
+        relationships.add(new Relationship("o-ran-smo-teiv-ran-logical", "TESTENTITYA_GROUPS_TESTENTITYB", "rel_3",
+                "TestEntityA_1", "TestEntityB_3", List.of()));
         ParsedCloudEventData parsedCloudEventData2 = new ParsedCloudEventData(entities, relationships);
         assertEquals(entities.size() + relationships.size(), tiesDbOperations.executeEntityAndRelationshipMergeOperations(
                 parsedCloudEventData2).size());
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_1");
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_2");
-        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock("ties_data.\"TestEntityB\"",
-                "TestEntityB_3");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_1");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_2");
+        verify(spiedDbServiceForValidation, times(1)).acquireEntityInstanceExclusiveLock(
+                "ties_data.\"o-ran-smo-teiv-ran-logical_TestEntityB\"", "TestEntityB_3");
         verify(spiedDbServiceForValidation, times(3)).executeValidationQuery(any(), any(), any(), any(Long.class));
         verifyNoMoreInteractions(spiedDbServiceForValidation);
     }
 
     @ParameterizedTest
     @CsvSource({ "5, 5, A_SIDE", "3, 3, B_SIDE" })
-    void unsupportedStorageLocation(int aSideMax, int bSideMax, RelationshipDataLocation location)
-            throws InvalidFieldInYangDataException {
+    void unsupportedStorageLocation(int aSideMax, int bSideMax, RelationshipDataLocation location) {
         try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
             Relationship relationship = new Relationship("", "relation_type", "id", "a", "b", List.of());
             RelationType relationType = RelationType.builder().aSideAssociation(Association.builder().maxCardinality(
@@ -305,7 +306,7 @@ public class IngestionOperationValidatorTest {
     }
 
     @Test
-    void determineMaxCardinalityCase() throws InvalidFieldInYangDataException {
+    void determineMaxCardinalityCase() {
         assertThrows(IllegalArgumentException.class, () -> IngestionOperationValidator.determineMaxCardinalityCase(0, 0));
         assertThrows(IllegalArgumentException.class, () -> IngestionOperationValidator.determineMaxCardinalityCase(-1, 0));
         assertThrows(IllegalArgumentException.class, () -> IngestionOperationValidator.determineMaxCardinalityCase(0, -1));
@@ -339,23 +340,23 @@ public class IngestionOperationValidatorTest {
         List<Entity> entities = new ArrayList<>();
         switch (cardinalityCase) {
             case ONE_ONE:
-                entities.add(new Entity("o-ran-smo-teiv-oam", "ManagedElement", "ManagedElement_1", Map.of("fdn", "fdn1"),
-                        List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-oam", "ManagedElement", "ManagedElement_2", Map.of("fdn", "fdn2"),
-                        List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-cloud", "CloudNativeSystem", "CloudNativeSystem_1", Map.of("name",
-                        "name1"), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-cloud", "CloudNativeSystem", "CloudNativeSystem_2", Map.of("name",
-                        "name2"), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-oam", "ManagedElement", "ManagedElement_1", Map.of("fdn",
+                        "fdn1"), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-oam", "ManagedElement", "ManagedElement_2", Map.of("fdn",
+                        "fdn2"), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-cloud", "CloudNativeSystem", "CloudNativeSystem_1", Map.of(
+                        "name", "name1"), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-cloud", "CloudNativeSystem", "CloudNativeSystem_2", Map.of(
+                        "name", "name2"), List.of()));
                 break;
             default:
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityA", "TestEntityA_1", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityA", "TestEntityA_2", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityA", "TestEntityA_3", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_1", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_2", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_3", Map.of(), List.of()));
-                entities.add(new Entity("o-ran-smo-teiv-ran", "TestEntityB", "TestEntityB_4", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityA", "TestEntityA_1", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityA", "TestEntityA_2", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityA", "TestEntityA_3", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_1", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_2", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_3", Map.of(), List.of()));
+                entities.add(new Entity("o-ran-smo-teiv-ran-logical", "TestEntityB", "TestEntityB_4", Map.of(), List.of()));
                 break;
         }
         return entities;
index df5cc07..5d2d8f6 100644 (file)
@@ -44,7 +44,10 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ActiveProfiles;
 
+import io.cloudevents.CloudEvent;
+
 import org.oran.smo.teiv.CustomMetrics;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
 import org.oran.smo.teiv.schema.SchemaLoader;
 import org.oran.smo.teiv.schema.SchemaLoaderException;
 import org.oran.smo.teiv.service.TiesDbService;
@@ -54,9 +57,6 @@ import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
 import org.oran.smo.teiv.startup.SchemaHandler;
 import org.oran.smo.teiv.utils.CloudEventTestUtil;
 
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import io.cloudevents.CloudEvent;
-
 @SpringBootTest
 @ActiveProfiles({ "test", "ingestion" })
 class CreateTopologyProcessorTest {
@@ -80,9 +80,9 @@ class CreateTopologyProcessorTest {
     }
 
     @Test
-    void testCreateCloudNativeApplicationEntity1() {
+    void testCreateGNBDUFunctionEntity1() {
         CloudEvent event = CloudEventTestUtil.getCloudEvent("create", "{}");
-        String entityType = "CloudNativeApplication";
+        String entityType = "GNBDUFunction";
         Map<String, Object> yangParserOutputMapBSide = new HashMap<>();
         Entity entity = new Entity("", entityType, "cloud_id_1", yangParserOutputMapBSide, List.of());
 
@@ -99,7 +99,7 @@ class CreateTopologyProcessorTest {
     @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
     void testInvalidAttribute() {
         CloudEvent event = CloudEventTestUtil.getCloudEvent("create", "{}");
-        String entityType = "CloudNativeApplication";
+        String entityType = "NFDeployment";
         Map<String, Object> yangParserOutputMap = new HashMap<>();
         yangParserOutputMap.put("invalidfield", "value1");
         Entity entity = new Entity("", entityType, "id1", yangParserOutputMap, List.of());
index 5ecdd44..6e14176 100644 (file)
  */
 package org.oran.smo.teiv.listener;
 
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.service.TiesDbService;
-import org.oran.smo.teiv.service.cloudevent.CloudEventParser;
-import org.oran.smo.teiv.service.cloudevent.data.Entity;
-import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
-import org.oran.smo.teiv.startup.SchemaHandler;
-import org.oran.smo.teiv.utils.CloudEventTestUtil;
-import io.cloudevents.CloudEvent;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -39,12 +40,17 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.context.ActiveProfiles;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import io.cloudevents.CloudEvent;
 
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+import org.oran.smo.teiv.service.TiesDbService;
+import org.oran.smo.teiv.service.cloudevent.CloudEventParser;
+import org.oran.smo.teiv.service.cloudevent.data.Entity;
+import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
+import org.oran.smo.teiv.startup.SchemaHandler;
+import org.oran.smo.teiv.utils.CloudEventTestUtil;
 
 @SpringBootTest
 @ActiveProfiles({ "test", "ingestion" })
@@ -69,7 +75,7 @@ class DeleteTopologyProcessorTest {
     @Test
     void testDeleteCloudNativeApplicationEntity1() {
         CloudEvent event = CloudEventTestUtil.getCloudEvent("delete", "{}");
-        String entityType = "CloudNativeApplication";
+        String entityType = "NFDeployment";
         Map<String, Object> yangParserOutputMapBSide = new HashMap<>();
         Entity entity = new Entity("", entityType, "cloud_id_1", yangParserOutputMapBSide, List.of());
 
index 28151ad..1cdc2ce 100644 (file)
@@ -33,8 +33,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.oran.smo.teiv.CustomMetrics;
-
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -43,20 +41,21 @@ import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ActiveProfiles;
 
-import org.oran.smo.teiv.schema.SchemaLoader;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.startup.SchemaHandler;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
 import io.cloudevents.CloudEvent;
 
+import org.oran.smo.teiv.CustomMetrics;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 import org.oran.smo.teiv.service.TiesDbService;
 import org.oran.smo.teiv.service.cloudevent.CloudEventParser;
 import org.oran.smo.teiv.service.cloudevent.data.Entity;
 import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
+import org.oran.smo.teiv.startup.SchemaHandler;
 import org.oran.smo.teiv.utils.CloudEventTestUtil;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
 
 @SpringBootTest
 @ActiveProfiles({ "test", "ingestion" })
@@ -82,9 +81,9 @@ class MergeTopologyProcessorTest {
     }
 
     @Test
-    void testMergeCloudNativeApplicationEntity1() {
+    void testMergeGNBDUFunctionEntity1() {
         CloudEvent event = CloudEventTestUtil.getCloudEvent("merge", "{}");
-        String entityType = "CloudNativeApplication";
+        String entityType = "GNBDUFunction";
         Map<String, Object> yangParserOutputMapBSide = new HashMap<>();
         Entity entity = new Entity("", entityType, "cloud_id_1", yangParserOutputMapBSide, List.of());
 
@@ -101,7 +100,7 @@ class MergeTopologyProcessorTest {
     @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
     void testInvalidAttribute() {
         CloudEvent event = CloudEventTestUtil.getCloudEvent("merge", "{}");
-        String entityType = "CloudNativeApplication";
+        String entityType = "NFDeployment";
         Map<String, Object> yangParserOutputMap = new HashMap<>();
         yangParserOutputMap.put("invalidfield", "value1");
         Entity entity = new Entity("", entityType, "id1", yangParserOutputMap, List.of());
index 1d285ae..2ce5d04 100644 (file)
@@ -23,20 +23,34 @@ package org.oran.smo.teiv.listener;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
 
+import java.lang.reflect.Field;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
+import org.jooq.DSLContext;
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.oran.smo.teiv.service.models.OperationResult;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -44,26 +58,31 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ActiveProfiles;
 
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+
 import org.oran.smo.teiv.CustomMetrics;
+import org.oran.smo.teiv.schema.BidiDbNameMapper;
 import org.oran.smo.teiv.schema.EntityType;
 import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.service.TiesDbOperations;
 import org.oran.smo.teiv.service.TiesDbService;
 import org.oran.smo.teiv.startup.SchemaHandler;
-import io.cloudevents.CloudEvent;
-import io.cloudevents.core.builder.CloudEventBuilder;
 
 @SpringBootTest
 @AutoConfigureJson
 @ActiveProfiles({ "test", "ingestion" })
 class SourceEntityDeleteTopologyProcessorTest {
+
     @Autowired
     private SourceEntityDeleteTopologyProcessor sourceEntityDeleteTopologyProcessor;
-
     @Autowired
     CustomMetrics metrics;
     @MockBean
     private TiesDbService tiesDbService;
     @MockBean
+    private TiesDbOperations tiesDbOperations;
+    @MockBean
     private SchemaHandler schemaHandler;
 
     @Test
@@ -111,17 +130,17 @@ class SourceEntityDeleteTopologyProcessorTest {
     void testSourceEntityDeleteUponRuntimeExceptionDuringDeletion() {
         //given
         try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
-            EntityType entityType = Mockito.mock(EntityType.class);
+            EntityType entityType = mock(EntityType.class);
             CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
                     .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
                     .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
                             "{\"type\":\"cmHandle\",\"value\":\"abc\"}".getBytes(StandardCharsets.UTF_8)).build();
-            mockedSchemaRegistry.when(SchemaRegistry::getEntityTypesWithCmId).thenReturn(List.of(entityType));
+            mockedSchemaRegistry.when(SchemaRegistry::getEntityTypes).thenReturn(List.of(entityType));
             doThrow(new RuntimeException()).when(tiesDbService).execute(anyList());
             //when
             assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
             //then
-            mockedSchemaRegistry.verify(SchemaRegistry::getEntityTypesWithCmId, times(1));
+            mockedSchemaRegistry.verify(SchemaRegistry::getEntityTypes, times(1));
             verify(tiesDbService, times(1)).execute(anyList());
 
             assertEquals(1, metrics.getNumSuccessfullyParsedSourceEntityDeleteCloudEvents().count());
@@ -133,4 +152,57 @@ class SourceEntityDeleteTopologyProcessorTest {
             assertEquals(0, metrics.getCloudEventSourceEntityDeletePersistTime().count());
         }
     }
+
+    @Test
+    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+    void testSourceEntityDelete() throws NoSuchFieldException {
+        //given
+        try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
+            DSLContext stream = mock(DSLContext.class);
+            CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
+                    .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
+                    .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
+                            "{\"type\":\"cmHandle\",\"value\":\"395221E080CCF0FD1924103B15873814\"}".getBytes(
+                                    StandardCharsets.UTF_8)).build();
+
+            Map<String, String> mockNameMap = new HashMap<>();
+            mockNameMap.put("GNBDUFunction", "GNBDUFunction");
+            Field nameMapField = BidiDbNameMapper.class.getDeclaredField("nameMap");
+            nameMapField.setAccessible(true);
+            nameMapField.set(null, mockNameMap);
+
+            OperationResult mockOperationResult = mock(OperationResult.class);
+            EntityType gnbduFunction = EntityType.builder().name("GNBDUFunction").build();
+            when(SchemaRegistry.getEntityTypes()).thenReturn(List.of(gnbduFunction));
+            when(tiesDbOperations.selectByCmHandleFormSourceIds(any(), anyString(), anyString())).thenReturn(List.of(
+                    "result1"));
+            when(tiesDbOperations.deleteEntity(any(), any(), anyString())).thenReturn(List.of(mockOperationResult));
+            doAnswer(new Answer<Void>() {
+                @Override
+                public Void answer(InvocationOnMock invocation) {
+                    List<Consumer<DSLContext>> consumers = invocation.getArgument(0);
+                    consumers.forEach(consumer -> {
+                        consumer.accept(stream);
+                    });
+                    return null;
+                }
+            }).when(tiesDbService).execute(anyList());
+            //when
+            assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
+            //then
+            mockedSchemaRegistry.verify(SchemaRegistry::getEntityTypes, times(1));
+            verify(tiesDbService, atLeastOnce()).execute(anyList());
+            verify(tiesDbOperations, atLeastOnce()).selectByCmHandleFormSourceIds(any(), anyString(), anyString());
+            verify(tiesDbOperations, atLeastOnce()).deleteEntity(any(), any(), anyString());
+
+            assertEquals(1, metrics.getNumSuccessfullyParsedSourceEntityDeleteCloudEvents().count());
+            assertEquals(0, metrics.getNumUnsuccessfullyParsedSourceEntityDeleteCloudEvents().count());
+            assertEquals(1, metrics.getNumSuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
+            assertEquals(0, metrics.getNumUnsuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
+            assertEquals(1, metrics.getCloudEventSourceEntityDeleteParseTime().count());
+            assertEquals(1, metrics.getCloudEventSourceEntityDeletePersistTime().count());
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1Test.java b/teiv/src/test/java/org/oran/smo/teiv/listener/SourceEntityDeleteTopologyProcessorV1Test.java
deleted file mode 100644 (file)
index 08818dc..0000000
+++ /dev/null
@@ -1,196 +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 org.oran.smo.teiv.listener;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
-
-import java.lang.reflect.Field;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-import org.jooq.DSLContext;
-import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.service.models.OperationResult;
-import org.oran.smo.teiv.schema.BidiDbNameMapper;
-import org.oran.smo.teiv.schema.EntityType;
-import org.oran.smo.teiv.schema.SchemaRegistry;
-import org.oran.smo.teiv.service.TiesDbOperations;
-import org.oran.smo.teiv.service.TiesDbService;
-import org.oran.smo.teiv.startup.SchemaHandler;
-import io.cloudevents.CloudEvent;
-import io.cloudevents.core.builder.CloudEventBuilder;
-
-@SpringBootTest(properties = "feature_flags.use_alternate_delete_logic=true")
-@AutoConfigureJson
-@ActiveProfiles({ "test", "ingestion" })
-class SourceEntityDeleteTopologyProcessorV1Test {
-
-    @Autowired
-    private SourceEntityDeleteTopologyProcessorV1 sourceEntityDeleteTopologyProcessor;
-    @Autowired
-    CustomMetrics metrics;
-    @MockBean
-    private TiesDbService tiesDbService;
-    @MockBean
-    private TiesDbOperations tiesDbOperations;
-    @MockBean
-    private SchemaHandler schemaHandler;
-
-    @Test
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
-    void testSourceEntityDeleteWithInvalidEventData() {
-        //given
-        try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
-            CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
-                    .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
-                    .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
-                            "{\"type\":\"cmHandle\",\"invalid\":\"abc\"}".getBytes(StandardCharsets.UTF_8)).build();
-            //when
-            assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
-            //then
-            mockedSchemaRegistry.verifyNoInteractions();
-            verifyNoInteractions(tiesDbService);
-
-            assertEquals(0, metrics.getNumSuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(1, metrics.getNumUnsuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumSuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumUnsuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getCloudEventSourceEntityDeleteParseTime().count());
-            assertEquals(0, metrics.getCloudEventSourceEntityDeletePersistTime().count());
-        }
-    }
-
-    @Test
-    void testSourceEntityDeleteWithUnsupportedEntityType() {
-        //given
-        try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
-            CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
-                    .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
-                    .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
-                            "{\"type\":\"unsupported-type\",\"value\":\"abc\"}".getBytes(StandardCharsets.UTF_8)).build();
-            //when
-            assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
-            //then
-            mockedSchemaRegistry.verifyNoInteractions();
-            verifyNoInteractions(tiesDbService);
-        }
-    }
-
-    @Test
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
-    void testSourceEntityDeleteUponRuntimeExceptionDuringDeletion() {
-        //given
-        try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
-            EntityType entityType = Mockito.mock(EntityType.class);
-            CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
-                    .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
-                    .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
-                            "{\"type\":\"cmHandle\",\"value\":\"abc\"}".getBytes(StandardCharsets.UTF_8)).build();
-            mockedSchemaRegistry.when(SchemaRegistry::getEntityTypes).thenReturn(List.of(entityType));
-            doThrow(new RuntimeException()).when(tiesDbService).execute(anyList());
-            //when
-            assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
-            //then
-            mockedSchemaRegistry.verify(SchemaRegistry::getEntityTypes, times(1));
-            verify(tiesDbService, times(1)).execute(anyList());
-
-            assertEquals(1, metrics.getNumSuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumUnsuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumSuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(1, metrics.getNumUnsuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(1, metrics.getCloudEventSourceEntityDeleteParseTime().count());
-            assertTrue(metrics.getCloudEventSourceEntityDeleteParseTime().totalTime(TimeUnit.NANOSECONDS) > 0);
-            assertEquals(0, metrics.getCloudEventSourceEntityDeletePersistTime().count());
-        }
-    }
-
-    @Test
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
-    void testSourceEntityDelete() throws NoSuchFieldException {
-        //given
-        try (MockedStatic<SchemaRegistry> mockedSchemaRegistry = Mockito.mockStatic(SchemaRegistry.class)) {
-            DSLContext stream = mock(DSLContext.class);
-            CloudEvent event = CloudEventBuilder.v1().withId("test-id").withType("ran-logical.source-entity-delete")
-                    .withSource(URI.create("http://localhost:8080/test-source")).withDataContentType("application/json")
-                    .withDataSchema(URI.create("http://localhost:8080/schema/v1/source-entity-delete")).withData(
-                            "{\"type\":\"cmHandle\",\"value\":\"395221E080CCF0FD1924103B15873814\"}".getBytes(
-                                    StandardCharsets.UTF_8)).build();
-
-            Map<String, String> mockNameMap = new HashMap<>();
-            mockNameMap.put("GNBDUFunction", "GNBDUFunction");
-            Field nameMapField = BidiDbNameMapper.class.getDeclaredField("nameMap");
-            nameMapField.setAccessible(true);
-            nameMapField.set(null, mockNameMap);
-
-            OperationResult mockOperationResult = mock(OperationResult.class);
-            EntityType gnbduFunction = EntityType.builder().name("GNBDUFunction").build();
-            when(SchemaRegistry.getEntityTypes()).thenReturn(List.of(gnbduFunction));
-            when(tiesDbOperations.selectByCmHandleFormSourceIds(any(), anyString(), anyString())).thenReturn(List.of(
-                    "result1"));
-            when(tiesDbOperations.deleteEntity(any(), any(), anyString())).thenReturn(List.of(mockOperationResult));
-            doAnswer(new Answer<Void>() {
-                @Override
-                public Void answer(InvocationOnMock invocation) throws Throwable {
-                    List<Consumer<DSLContext>> consumers = invocation.getArgument(0);
-                    consumers.forEach(consumer -> {
-                        consumer.accept(stream);
-                    });
-                    return null;
-                }
-            }).when(tiesDbService).execute(anyList());
-            //when
-            assertDoesNotThrow(() -> sourceEntityDeleteTopologyProcessor.process(event, "messageKey"));
-            //then
-            mockedSchemaRegistry.verify(SchemaRegistry::getEntityTypes, times(1));
-            verify(tiesDbService, atLeastOnce()).execute(anyList());
-            verify(tiesDbOperations, atLeastOnce()).selectByCmHandleFormSourceIds(any(), anyString(), anyString());
-            verify(tiesDbOperations, atLeastOnce()).deleteEntity(any(), any(), anyString());
-
-            assertEquals(1, metrics.getNumSuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumUnsuccessfullyParsedSourceEntityDeleteCloudEvents().count());
-            assertEquals(1, metrics.getNumSuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(0, metrics.getNumUnsuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
-            assertEquals(1, metrics.getCloudEventSourceEntityDeleteParseTime().count());
-            assertEquals(1, metrics.getCloudEventSourceEntityDeletePersistTime().count());
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
index 3bc66ca..c4dd0ac 100644 (file)
  */
 package org.oran.smo.teiv.schema;
 
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.impl.DataPersistanceServiceImpl;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataRepositoryImpl;
+
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
@@ -35,15 +34,15 @@ import static org.mockito.Mockito.when;
 
 public class ConsumerDataCacheTest {
 
-    private static final DataPersistanceService dataPersistanceService = mock(DataPersistanceServiceImpl.class);
-    private final ConsumerDataCache underTest = new ConsumerDataCache(dataPersistanceService);
+    private static final ConsumerDataRepositoryImpl DATA_REPOSITORY = mock(ConsumerDataRepositoryImpl.class);
+    private final ConsumerDataCache underTest = new ConsumerDataCache(DATA_REPOSITORY);
 
     @BeforeAll
     static void beforeAll() {
-        when(dataPersistanceService.loadClassifiers()).thenReturn(Set.of("gnbdu-function-model:Rural",
+        when(DATA_REPOSITORY.loadClassifiers()).thenReturn(Set.of("gnbdu-function-model:Rural",
                 "gnbcucp-gnbcuup-model:Weekend"));
-        when(dataPersistanceService.loadDecorators()).thenReturn(Map.of("gnbdu-function-model:location", DataType.PRIMITIVE,
-                "gnbcucp-gnbcuup-model:metadata", DataType.CONTAINER));
+        when(DATA_REPOSITORY.loadDecorators()).thenReturn(Map.of("gnbdu-function-model:location", YangDataTypes.STRING,
+                "gnbcucp-gnbcuup-model:metadata", YangDataTypes.BOOLEAN));
     }
 
     @Test
@@ -62,7 +61,7 @@ public class ConsumerDataCacheTest {
 
     @Test
     void testGetDecorators() {
-        assertEquals(Map.of("gnbdu-function-model:location", DataType.PRIMITIVE, "gnbcucp-gnbcuup-model:metadata",
-                DataType.CONTAINER), underTest.getDecorators());
+        assertEquals(Map.of("gnbdu-function-model:location", YangDataTypes.STRING, "gnbcucp-gnbcuup-model:metadata",
+                YangDataTypes.BOOLEAN), underTest.getDecorators());
     }
 }
index 026a08e..8ebc1d4 100644 (file)
  */
 package org.oran.smo.teiv.schema;
 
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.oran.smo.teiv.exposure.spi.Module;
 
 import static org.oran.smo.teiv.schema.DataType.BIGINT;
 import static org.oran.smo.teiv.schema.DataType.CONTAINER;
 import static org.oran.smo.teiv.schema.DataType.DECIMAL;
 import static org.oran.smo.teiv.schema.DataType.GEOGRAPHIC;
+import static org.oran.smo.teiv.schema.DataType.INTEGER;
 import static org.oran.smo.teiv.schema.DataType.PRIMITIVE;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.A_SIDE;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
+import static org.oran.smo.teiv.utils.TiesConstants.TEIV_DOMAIN;
 
 public class MockSchemaLoader extends SchemaLoader {
 
     @Override
     protected void loadBidiDbNameMapper() {
-
         Map<String, String> hashedNames = new HashMap<>();
-        hashedNames.put("GNBDUFunction", "GNBDUFunction");
-        hashedNames.put("GNBCUUPFunction", "GNBCUUPFunction");
-        hashedNames.put("NRCellDU", "NRCellDU");
-        hashedNames.put("NRSectorCarrier", "NRSectorCarrier");
-        hashedNames.put("CloudNativeApplication", "CloudNativeApplication");
-        hashedNames.put("AntennaCapability", "AntennaCapability");
-        hashedNames.put("Sector", "Sector");
-        hashedNames.put("AntennaModule", "AntennaModule");
-
-        hashedNames.put("ANTENNAMODULE_INSTALLED_AT_SITE", "ANTENNAMODULE_INSTALLED_AT_SITE");
-        hashedNames.put("GNBDUFUNCTION_PROVIDES_NRCELLDU", "GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        hashedNames.put("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
-        hashedNames.put("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        hashedNames.put("NRSECTORCARRIER_USES_ANTENNACAPABILITY", "NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-        hashedNames.put("SECTOR_GROUPS_ANTENNAMODULE", "SECTOR_GROUPS_ANTENNAMODULE");
-        hashedNames.put("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-
-        hashedNames.put("id", "id");
-        hashedNames.put("fdn", "fdn");
-        hashedNames.put("cmId", "cmId");
-        hashedNames.put("CD_sourceIds", "CD_sourceIds");
-
-        // GNBDUFUNCTION
-        hashedNames.put("dUpLMNId", "dUpLMNId");
-        hashedNames.put("gNBIdLength", "gNBIdLength");
-        hashedNames.put("gNBId", "gNBId");
-        hashedNames.put("gNBDUId", "gNBDUId");
-        hashedNames.put("REL_FK_managed-by-managedElement", "REL_FK_managed-by-managedElement");
-        hashedNames.put("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-
-        //NRCELLDU
-        hashedNames.put("nCI", "nCI");
-        hashedNames.put("cellLocalId", "cellLocalId");
-        hashedNames.put("nRPCI", "nRPCI");
-        hashedNames.put("nRTAC", "nRTAC");
-        hashedNames.put("REL_FK_grouped-by-sector", "REL_FK_grouped-by-sector");
-        hashedNames.put("REL_ID_SECTOR_GROUPS_NRCELLDU", "REL_ID_SECTOR_GROUPS_NRCELLDU");
-        hashedNames.put("REL_FK_provided-by-gnbduFunction", "REL_FK_provided-by-gnbduFunction");
-        hashedNames.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        hashedNames.put("REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU");
-
-        //NrSectorCarrier
-        hashedNames.put("frequencyDL", "frequencyDL");
-        hashedNames.put("frequencyUL", "frequencyUL");
-        hashedNames.put("arfcnUL", "arfcnUL");
-        hashedNames.put("essScLocalId", "essScLocalId");
-        hashedNames.put("arfcnDL", "arfcnDL");
-        hashedNames.put("REL_FK_used-by-nrCellDu", "REL_FK_used-by-nrCellDu");
-        hashedNames.put("REL_ID_NRCELLDU_USES_NRSECTORCARRIER", "REL_ID_NRCELLDU_USES_NRSECTORCARRIER");
-        hashedNames.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
-        hashedNames.put("REL_FK_used-antennaCapability", "REL_FK_used-antennaCapability");
-        hashedNames.put("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY", "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-
-        //CloudNativeApplication
-        hashedNames.put("name", "name");
-        hashedNames.put("REL_FK_realised-managedElement", "REL_FK_realised-managedElement");
-        hashedNames.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        hashedNames.put("REL_FK_comprised-by-cloudNativeSystem", "REL_FK_comprised-by-cloudNativeSystem");
-        hashedNames.put("REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION",
-                "REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION");
-        hashedNames.put("REL_FK_deployed-on-namespace", "REL_FK_deployed-on-namespace");
-        hashedNames.put("REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE",
-                "REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE");
-
-        //AntennaCapability
-        hashedNames.put("nRFqBands", "nRFqBands");
-        hashedNames.put("eUtranFqBands", "eUtranFqBands");
-        hashedNames.put("geranFqBands", "geranFqBands");
-        hashedNames.put("REL_FK_used-by-lteSectorCarrier", "REL_FK_used-by-lteSectorCarrier");
-
-        //Sector
-        hashedNames.put("sectorId", "sectorId");
-        hashedNames.put("azimuth", "azimuth");
-
-        //AntennaModule
-        hashedNames.put("positionWithinSector", "positionWithinSector");
-        hashedNames.put("antennaModelNumber", "antennaModelNumber");
-        hashedNames.put("electricalAntennaTilt", "electricalAntennaTilt");
-        hashedNames.put("mechanicalAntennaTilt", "mechanicalAntennaTilt");
-        hashedNames.put("totalTilt", "totalTilt");
-        hashedNames.put("mechanicalAntennaBearing", "mechanicalAntennaBearing");
-        hashedNames.put("REL_ID_SECTOR_GROUPS_ANTENNAMODULE", "REL_ID_SECTOR_GROUPS_ANTENNAMODULE");
-        hashedNames.put("REL_FK_installed-at-site", "REL_FK_installed-at-site");
-        hashedNames.put("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE");
-
-        //GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION
-        hashedNames.put("aSide_GNBDUFunction", "aSide_GNBDUFunction");
-        hashedNames.put("bSide_CloudNativeApplication", "bSide_CloudNativeApplication");
-
-        //ANTENNAMODULE_REALISED_BY_ANTENNAMODULE
-        hashedNames.put("aSide_AntennaModule", "aSide_AntennaModule");
-        hashedNames.put("bSide_AntennaModule", "bSide_AntennaModule");
-
         Map<String, String> reverseHashedNames = new HashMap<>();
-        reverseHashedNames.put("GNBDUFunction", "GNBDUFunction");
-        reverseHashedNames.put("GNBCUUPFunction", "GNBCUUPFunction");
-        reverseHashedNames.put("NRCellDU", "NRCellDU");
-        reverseHashedNames.put("NRSectorCarrier", "NRSectorCarrier");
-        reverseHashedNames.put("CloudNativeApplication", "CloudNativeApplication");
-        reverseHashedNames.put("AntennaCapability", "AntennaCapability");
-        reverseHashedNames.put("Sector", "Sector");
-        reverseHashedNames.put("AntennaModule", "AntennaModule");
-
-        reverseHashedNames.put("ANTENNAMODULE_INSTALLED_AT_SITE", "ANTENNAMODULE_INSTALLED_AT_SITE");
-        reverseHashedNames.put("GNBDUFUNCTION_PROVIDES_NRCELLDU", "GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        reverseHashedNames.put("GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
-        reverseHashedNames.put("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        reverseHashedNames.put("NRSECTORCARRIER_USES_ANTENNACAPABILITY", "NRSECTORCARRIER_USES_ANTENNACAPABILITY");
-        reverseHashedNames.put("SECTOR_GROUPS_ANTENNAMODULE", "SECTOR_GROUPS_ANTENNAMODULE");
-        reverseHashedNames.put("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-
-        reverseHashedNames.put("id", "id");
-        reverseHashedNames.put("fdn", "fdn");
-        reverseHashedNames.put("cmId", "cmId");
-        reverseHashedNames.put("CD_sourceIds", "CD_sourceIds");
-
-        // GNBDUFUNCTION
-        reverseHashedNames.put("dUpLMNId", "dUpLMNId");
-        reverseHashedNames.put("gNBIdLength", "gNBIdLength");
-        reverseHashedNames.put("gNBId", "gNBId");
-        reverseHashedNames.put("gNBDUId", "gNBDUId");
-        reverseHashedNames.put("REL_FK_managed-by-managedElement", "REL_FK_managed-by-managedElement");
-        reverseHashedNames.put("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION",
-                "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-
-        //NRCELLDU
-        reverseHashedNames.put("nCI", "nCI");
-        reverseHashedNames.put("cellLocalId", "cellLocalId");
-        reverseHashedNames.put("nRPCI", "nRPCI");
-        reverseHashedNames.put("nRTAC", "nRTAC");
-        reverseHashedNames.put("REL_FK_grouped-by-sector", "REL_FK_grouped-by-sector");
-        reverseHashedNames.put("REL_ID_SECTOR_GROUPS_NRCELLDU", "REL_ID_SECTOR_GROUPS_NRCELLDU");
-        reverseHashedNames.put("REL_FK_provided-by-gnbduFunction", "REL_FK_provided-by-gnbduFunction");
-        reverseHashedNames.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU");
-        reverseHashedNames.put("REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU");
-
-        //NrSectorCarrier
-        reverseHashedNames.put("frequencyDL", "frequencyDL");
-        reverseHashedNames.put("frequencyUL", "frequencyUL");
-        reverseHashedNames.put("arfcnUL", "arfcnUL");
-        reverseHashedNames.put("essScLocalId", "essScLocalId");
-        reverseHashedNames.put("arfcnDL", "arfcnDL");
-        reverseHashedNames.put("REL_FK_used-by-nrCellDu", "REL_FK_used-by-nrCellDu");
-        reverseHashedNames.put("REL_ID_NRCELLDU_USES_NRSECTORCARRIER", "REL_ID_NRCELLDU_USES_NRSECTORCARRIER");
-        reverseHashedNames.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
-                "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
-        reverseHashedNames.put("REL_FK_used-antennaCapability", "REL_FK_used-antennaCapability");
-        reverseHashedNames.put("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY",
-                "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY");
 
-        //CloudNativeApplication
-        reverseHashedNames.put("name", "name");
-        reverseHashedNames.put("REL_FK_realised-managedElement", "REL_FK_realised-managedElement");
-        reverseHashedNames.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        reverseHashedNames.put("REL_FK_comprised-by-cloudNativeSystem", "REL_FK_comprised-by-cloudNativeSystem");
-        reverseHashedNames.put("REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION",
-                "REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION");
-        reverseHashedNames.put("REL_FK_deployed-on-namespace", "REL_FK_deployed-on-namespace");
-        reverseHashedNames.put("REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE",
-                "REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE");
-
-        //AntennaCapability
-        reverseHashedNames.put("nRFqBands", "nRFqBands");
-        reverseHashedNames.put("eUtranFqBands", "eUtranFqBands");
-        reverseHashedNames.put("geranFqBands", "geranFqBands");
-        reverseHashedNames.put("REL_FK_used-by-lteSectorCarrier", "REL_FK_used-by-lteSectorCarrier");
-
-        //Sector
-        reverseHashedNames.put("sectorId", "sectorId");
-        reverseHashedNames.put("azimuth", "azimuth");
-
-        //AntennaModule
-        reverseHashedNames.put("positionWithinSector", "positionWithinSector");
-        reverseHashedNames.put("antennaModelNumber", "antennaModelNumber");
-        reverseHashedNames.put("electricalAntennaTilt", "electricalAntennaTilt");
-        reverseHashedNames.put("mechanicalAntennaTilt", "mechanicalAntennaTilt");
-        reverseHashedNames.put("totalTilt", "totalTilt");
-        reverseHashedNames.put("mechanicalAntennaBearing", "mechanicalAntennaBearing");
-        reverseHashedNames.put("REL_ID_SECTOR_GROUPS_ANTENNAMODULE", "REL_ID_SECTOR_GROUPS_ANTENNAMODULE");
-        reverseHashedNames.put("REL_FK_installed-at-site", "REL_FK_installed-at-site");
-        reverseHashedNames.put("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE");
-
-        //GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION
-        reverseHashedNames.put("aSide_GNBDUFunction", "aSide_GNBDUFunction");
-        reverseHashedNames.put("bSide_CloudNativeApplication", "bSide_CloudNativeApplication");
-
-        //ANTENNAMODULE_REALISED_BY_ANTENNAMODULE
-        reverseHashedNames.put("aSide_AntennaModule", "aSide_AntennaModule");
-        reverseHashedNames.put("bSide_AntennaModule", "bSide_AntennaModule");
+        List<List<String>> hashInfo = extractModelInfoFromSqlFile("hash_info");
+        hashInfo.forEach(l -> {
+            hashedNames.put(l.get(0), l.get(1));
+            reverseHashedNames.put(l.get(1), l.get(0));
+        });
 
         BidiDbNameMapper.initialize(hashedNames, reverseHashedNames);
     }
 
     @Override
     protected void loadModules() {
-        Module ranLogicalModule = Module.builder().name("o-ran-smo-teiv-ran").namespace("urn:o-ran:smo-teiv-ran").domain(
-                "RAN").build();
-
-        Module ranEquipmentModule = Module.builder().name("o-ran-smo-teiv-equipment").namespace(
-                "urn:o-ran:smo-teiv-equipment").domain("EQUIPMENT").build();
+        List<Module> modules = new ArrayList<>();
+
+        List<List<String>> moduleReference = extractModelInfoFromSqlFile("module_reference");
+        moduleReference.forEach(l -> {
+            String domain = l.get(2);
+            if (domain.equals("\\N")) {
+                domain = null;
+            }
+
+            String name = l.get(0);
+            String namespace = l.get(1);
+            String content = l.get(5);
+            final Module.ModuleBuilder moduleBuilder = Module.builder().name(name).namespace(namespace).domain(domain)
+                    .content(content);
+            final String includedModuleNames = l.get(3).replaceAll("[\\[\\]\"\\s]", "");
+            if (!includedModuleNames.isEmpty()) {
+                moduleBuilder.includedModuleNames(List.of(includedModuleNames.split(","))).build();
+            }
+            modules.add(moduleBuilder.build());
+        });
 
-        Module ranCloudModule = Module.builder().name("o-ran-smo-teiv-cloud").namespace("urn:o-ran:smo-teiv-cloud").domain(
-                "CLOUD").build();
-
-        Module ranLogicalToEquipmentModule = Module.builder().name("o-ran-smo-teiv-equipment-to-ran").namespace(
-                "urn:o-ran:smo-teiv-equipment-to-ran").domain("EQUIPMENT_TO_RAN").includedModuleName("o-ran-smo-teiv-ran")
-                .includedModuleName("o-ran-smo-teiv-equipment").build();
-
-        Module ranLogicalToCloudModule = Module.builder().name("o-ran-smo-teiv-cloud-to-ran").namespace(
-                "urn:o-ran:smo-teiv-cloud-to-ran").domain("CLOUD_TO_RAN").includedModuleName("o-ran-smo-teiv-ran")
-                .includedModuleName("o-ran-smo-teiv-cloud").build();
-
-        Module ranOamModule = Module.builder().name("o-ran-smo-teiv-oam").namespace("urn:o-ran:smo-teiv-oam").domain("OAM")
-                .build();
-
-        Module ranOamToLogicalModule = Module.builder().name("o-ran-smo-teiv-oam-to-ran").namespace(
-                "urn:o-ran:smo-teiv-oam-to-ran").domain("OAM_TO_RAN").includedModuleName("o-ran-smo-teiv-oam")
-                .includedModuleName("o-ran-smo-teiv-ran").build();
-
-        Module ranOamToCloudModule = Module.builder().name("o-ran-smo-teiv-oam-to-cloud").namespace(
-                "urn:o-ran:smo-teiv-oam-to-cloud").domain("OAM_TO_CLOUD").includedModuleName("o-ran-smo-teiv-oam")
-                .includedModuleName("o-ran-smo-teiv-cloud").build();
-
-        List<Module> modules = List.of(ranLogicalModule, ranEquipmentModule, ranCloudModule, ranLogicalToEquipmentModule,
-                ranLogicalToCloudModule, ranOamModule, ranOamToLogicalModule, ranOamToCloudModule);
         Map<String, Module> moduleMap = new HashMap<>();
         modules.forEach(module -> moduleMap.put(module.getName(), module));
+        moduleMap.put(TEIV_DOMAIN, Module.builder().name(TEIV_DOMAIN).namespace(TEIV_DOMAIN).domain(TEIV_DOMAIN)
+                .includedModuleNames(moduleMap.keySet()).build());
         SchemaRegistry.initializeModules(moduleMap);
     }
 
     @Override
     protected void loadEntityTypes() {
-        EntityType gnbduFunction = EntityType.builder().name("GNBDUFunction").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-ran")).fields(getGnbduFunctionFields()).build();
-        EntityType gnbcuupFunction = EntityType.builder().name("GNBCUUPFunction").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-ran")).fields(getGnbcuupFunctionFields()).build();
-
-        EntityType nrCellDU = EntityType.builder().name("NRCellDU").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-ran")).fields(getNrCellDuFields()).build();
-
-        EntityType nrSectorCarrier = EntityType.builder().name("NRSectorCarrier").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-ran")).fields(getNrSectorCarrierFields()).build();
-
-        EntityType gNBCUCPFunction = EntityType.builder().name("GNBCUCPFunction").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-cloud-to-ran")).fields(getGNBCUCPFunctionFields()).build();
-
-        EntityType managedElement = EntityType.builder().name("ManagedElement").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-oam")).fields(getManagedElementFields()).build();
-
-        EntityType cloudNativeApplication = EntityType.builder().name("CloudNativeApplication").module(SchemaRegistry
-                .getModuleByName("o-ran-smo-teiv-cloud")).fields(getCloudNativeApplicationFields()).build();
+        List<EntityType> entityTypes = new ArrayList<>();
 
-        EntityType antennaCapability = EntityType.builder().name("AntennaCapability").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-ran")).fields(getAntennaCapabilityFields()).build();
+        List<List<String>> entityInfo = extractModelInfoFromSqlFile("entity_info");
+        entityInfo.forEach(l -> {
+            String storedAt = l.get(0);
+            String name = l.get(1);
+            String moduleReferenceName = l.get(2);
+            entityTypes.add(EntityType.builder().name(name).tableName(storedAt).module(SchemaRegistry.getModuleByName(
+                    moduleReferenceName)).fields(extractDataFieldsFromSqlFile(storedAt)).build());
+        });
 
-        EntityType sector = EntityType.builder().name("Sector").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-equipment-to-ran")).fields(getSectorFields()).build();
-
-        EntityType antennaModule = EntityType.builder().name("AntennaModule").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-equipment")).fields(getAntennaModuleFields()).build();
-
-        EntityType site = EntityType.builder().name("Site").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-equipment")).fields(getSiteFields()).build();
-
-        EntityType cloudSite = EntityType.builder().name("CloudSite").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-cloud")).fields(getCloudSiteFields()).build();
-
-        EntityType nodeCluster = EntityType.builder().name("NodeCluster").module(SchemaRegistry.getModuleByName(
-                "o-ran-smo-teiv-cloud")).fields(getNodeClusterFields()).build();
-
-        List<EntityType> entityTypes = List.of(gnbduFunction, gnbcuupFunction, nrCellDU, nrSectorCarrier, gNBCUCPFunction,
-                managedElement, cloudNativeApplication, antennaCapability, sector, antennaModule, site, cloudSite,
-                nodeCluster);
-        Map<String, EntityType> entityTypeMap = new HashMap<>();
-        entityTypes.forEach(entityType -> entityTypeMap.put(entityType.getName(), entityType));
-        SchemaRegistry.initializeEntityTypes(entityTypeMap);
+        SchemaRegistry.initializeEntityTypes(entityTypes);
     }
 
     @Override
     protected void loadRelationTypes() {
-
-        RelationType antennaModuleInstalledAtSite = RelationType.builder().name("ANTENNAMODULE_INSTALLED_AT_SITE")
-                .aSideAssociation(getRelationshipAssociation("installed-at-site", 0, 9223372036854775807L)).aSide(
-                        SchemaRegistry.getEntityTypeByName("AntennaModule")).bSideAssociation(getRelationshipAssociation(
-                                "installed-antennaModule", 0, 1)).bSide(SchemaRegistry.getEntityTypeByName("Site"))
-                .connectsSameEntity(false).relationshipStorageLocation(A_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-equipment")).build();
-
-        RelationType gnbduFunctionProvidesNrcelldu = RelationType.builder().name("GNBDUFUNCTION_PROVIDES_NRCELLDU")
-                .aSideAssociation(getRelationshipAssociation("provided-nrCellDu", 1, 1)).aSide(SchemaRegistry
-                        .getEntityTypeByName("GNBDUFunction")).bSideAssociation(getRelationshipAssociation(
-                                "provided-by-gnbduFunction", 0, 9223372036854775807L)).bSide(SchemaRegistry
-                                        .getEntityTypeByName("NRCellDU")).connectsSameEntity(false)
-                .relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName("o-ran-smo-teiv-ran")).build();
-
-        RelationType gnbduFunctionProvidesNrsectorcarrier = RelationType.builder().name(
-                "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").aSideAssociation(getRelationshipAssociation(
-                        "provided-nrSectorCarrier", 1, 1)).aSide(SchemaRegistry.getEntityTypeByName("GNBDUFunction"))
-                .bSideAssociation(getRelationshipAssociation("provided-by-gnbduFunction", 0, 9223372036854775807L)).bSide(
-                        SchemaRegistry.getEntityTypeByName("NRSectorCarrier")).connectsSameEntity(false)
-                .relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName("o-ran-smo-teiv-ran")).build();
-
-        RelationType gnbduFunctionRealisedByCloudnativeapplication = RelationType.builder().name(
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION").aSideAssociation(getRelationshipAssociation(
-                        "realised-by-cloudNativeApplication", 0, 9223372036854775807L)).aSide(SchemaRegistry
-                                .getEntityTypeByName("GNBDUFunction")).bSideAssociation(getRelationshipAssociation(
-                                        "realised-gnbduFunction", 0, 9223372036854775807L)).bSide(SchemaRegistry
-                                                .getEntityTypeByName("CloudNativeApplication")).connectsSameEntity(false)
-                .relationshipStorageLocation(RELATION).module(SchemaRegistry.getModuleByName("o-ran-smo-teiv-cloud-to-ran"))
-                .build();
-
-        RelationType nrSectorcarrierUsesAntennacapability = RelationType.builder().name(
-                "NRSECTORCARRIER_USES_ANTENNACAPABILITY").aSideAssociation(getRelationshipAssociation(
-                        "used-antennaCapability", 0, 9223372036854775807L)).aSide(SchemaRegistry.getEntityTypeByName(
-                                "NRSectorCarrier")).bSideAssociation(getRelationshipAssociation("used-by-nrSectorCarrier",
-                                        0, 1)).bSide(SchemaRegistry.getEntityTypeByName("AntennaCapability"))
-                .connectsSameEntity(false).relationshipStorageLocation(A_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-ran")).build();
-
-        RelationType sectorGroupsAntennamodule = RelationType.builder().name("SECTOR_GROUPS_ANTENNAMODULE")
-                .aSideAssociation(getRelationshipAssociation("grouped-antennaModule", 0, 1)).aSide(SchemaRegistry
-                        .getEntityTypeByName("Sector")).bSideAssociation(getRelationshipAssociation("grouped-by-sector", 0,
-                                9223372036854775807L)).bSide(SchemaRegistry.getEntityTypeByName("AntennaModule"))
-                .connectsSameEntity(false).relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-equipment-to-ran")).build();
-
-        RelationType sectorGroupsNrcelldu = RelationType.builder().name("SECTOR_GROUPS_NRCELLDU").aSideAssociation(
-                getRelationshipAssociation("grouped-nrCellDu", 0, 1)).aSide(SchemaRegistry.getEntityTypeByName("Sector"))
-                .bSideAssociation(getRelationshipAssociation("grouped-by-sector", 0, 9223372036854775807L)).bSide(
-                        SchemaRegistry.getEntityTypeByName("NRCellDU")).connectsSameEntity(false)
-                .relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-equipment-to-ran")).build();
-
-        RelationType nrCellDuUsesNrSectorcarrier = RelationType.builder().name("NRCELLDU_USES_NRSECTORCARRIER")
-                .aSideAssociation(getRelationshipAssociation("used-nrSectorCarrier", 0, 1)).aSide(SchemaRegistry
-                        .getEntityTypeByName("NRCellDU")).bSideAssociation(getRelationshipAssociation("used-by-nrCellDu", 0,
-                                9223372036854775807L)).bSide(SchemaRegistry.getEntityTypeByName("NRSectorCarrier"))
-                .connectsSameEntity(false).relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-ran")).build();
-
-        RelationType managedElementManagesGNBCUCPFunction = RelationType.builder().name(
-                "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION").aSideAssociation(getRelationshipAssociation(
-                        "managed-gnbcucpFunction", 1, 1)).aSide(SchemaRegistry.getEntityTypeByName("ManagedElement"))
-                .bSideAssociation(getRelationshipAssociation("managed-by-managedElement", 0, 9223372036854775807L)).bSide(
-                        SchemaRegistry.getEntityTypeByName("GNBCUCPFunction")).connectsSameEntity(false)
-                .relationshipStorageLocation(B_SIDE).module(SchemaRegistry.getModuleByName("o-ran-smo-teiv-oam-to-ran"))
-                .build();
-
-        RelationType nodeClusterLocatedAtCloudSite = RelationType.builder().name("NODECLUSTER_LOCATED_AT_CLOUDSITE")
-                .aSideAssociation(getRelationshipAssociation("located-at-cloudSite", 0, 9223372036854775807L)).aSide(
-                        SchemaRegistry.getEntityTypeByName("NodeCluster")).bSideAssociation(getRelationshipAssociation(
-                                "location-of-nodeCluster", 1, 1)).bSide(SchemaRegistry.getEntityTypeByName("CloudSite"))
-                .connectsSameEntity(false).relationshipStorageLocation(A_SIDE).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-cloud")).build();
-
-        RelationType antennaModuleRealisedByAntennaModule = RelationType.builder().name(
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE").aSideAssociation(getRelationshipAssociation(
-                        "realised-by-antennaModule", 0, 9223372036854775807L)).aSide(SchemaRegistry.getEntityTypeByName(
-                                "AntennaModule")).bSideAssociation(getRelationshipAssociation("realised-antennaModule", 0,
-                                        9223372036854775807L)).bSide(SchemaRegistry.getEntityTypeByName("AntennaModule"))
-                .connectsSameEntity(true).relationshipStorageLocation(RELATION).module(SchemaRegistry.getModuleByName(
-                        "o-ran-smo-teiv-equipment")).build();
-
-        List<RelationType> relationTypes = List.of(gnbduFunctionProvidesNrcelldu, gnbduFunctionProvidesNrsectorcarrier,
-                gnbduFunctionRealisedByCloudnativeapplication, nrSectorcarrierUsesAntennacapability,
-                sectorGroupsAntennamodule, sectorGroupsNrcelldu, nrCellDuUsesNrSectorcarrier,
-                managedElementManagesGNBCUCPFunction, nodeClusterLocatedAtCloudSite, antennaModuleInstalledAtSite,
-                antennaModuleRealisedByAntennaModule);
-        Map<String, RelationType> relationTypeMap = new HashMap<>();
-        relationTypes.forEach(relationType -> relationTypeMap.put(relationType.getName(), relationType));
-        SchemaRegistry.initializeRelationTypes(relationTypeMap);
-    }
-
-    private Map<String, DataType> getGnbduFunctionFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("gNBDUId", BIGINT);
-        fields.put("gNBId", BIGINT);
-        fields.put("gNBIdLength", BIGINT);
-        fields.put("dUpLMNId", CONTAINER);
-        fields.put("id", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("REL_FK_managed-by-managedElement", PRIMITIVE);
-        fields.put("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getGnbcuupFunctionFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("gNBId", BIGINT);
-        fields.put("gNBIdLength", BIGINT);
-        fields.put("id", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("REL_FK_managed-by-managedElement", PRIMITIVE);
-        fields.put("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getNrCellDuFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("fdn", PRIMITIVE);
-        fields.put("nCI", BIGINT);
-        fields.put("cellLocalId", BIGINT);
-        fields.put("id", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("nRPCI", BIGINT);
-        fields.put("nRTAC", BIGINT);
-        fields.put("REL_FK_grouped-by-sector", PRIMITIVE);
-        fields.put("REL_ID_SECTOR_GROUPS_NRCELLDU", PRIMITIVE);
-        fields.put("REL_FK_provided-by-gnbduFunction", PRIMITIVE);
-        fields.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getNrSectorCarrierFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("frequencyDL", BIGINT);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("frequencyUL", BIGINT);
-        fields.put("arfcnUL", BIGINT);
-        fields.put("id", PRIMITIVE);
-        fields.put("essScLocalId", BIGINT);
-        fields.put("cmId", CONTAINER);
-        fields.put("arfcnDL", BIGINT);
-        fields.put("REL_FK_used-by-nrCellDu", PRIMITIVE);
-        fields.put("REL_ID_NRCELLDU_USES_NRSECTORCARRIER", PRIMITIVE);
-        fields.put("REL_FK_provided-by-gnbduFunction", PRIMITIVE);
-        fields.put("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", PRIMITIVE);
-        fields.put("REL_FK_used-antennaCapability", PRIMITIVE);
-        fields.put("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getCloudNativeApplicationFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("name", PRIMITIVE);
-        fields.put("REL_FK_realised-managedElement", PRIMITIVE);
-        fields.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", PRIMITIVE);
-        fields.put("REL_FK_comprised-by-cloudNativeSystem", PRIMITIVE);
-        fields.put("REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getAntennaCapabilityFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("nRFqBands", CONTAINER);
-        fields.put("id", PRIMITIVE);
-        fields.put("eUtranFqBands", CONTAINER);
-        fields.put("cmId", CONTAINER);
-        fields.put("geranFqBands", CONTAINER);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("REL_FK_used-by-lteSectorCarrier", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getSectorFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("sectorId", BIGINT);
-        fields.put("id", PRIMITIVE);
-        fields.put("azimuth", DECIMAL);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getAntennaModuleFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("positionWithinSector", PRIMITIVE);
-        fields.put("antennaModelNumber", PRIMITIVE);
-        fields.put("electricalAntennaTilt", BIGINT);
-        fields.put("mechanicalAntennaTilt", BIGINT);
-        fields.put("totalTilt", BIGINT);
-        fields.put("id", PRIMITIVE);
-        fields.put("mechanicalAntennaBearing", BIGINT);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("REL_FK_grouped-by-sector", PRIMITIVE);
-        fields.put("REL_ID_SECTOR_GROUPS_ANTENNAMODULE", PRIMITIVE);
-        fields.put("REL_FK_installed-at-site", PRIMITIVE);
-        fields.put("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getSiteFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("name", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getCloudSiteFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("name", PRIMITIVE);
-        fields.put("geo-location", GEOGRAPHIC);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getNodeClusterFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("name", PRIMITIVE);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getManagedElementFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("cmId", CONTAINER);
-        fields.put("REL_FK_deployed-as-cloudNativeSystem", PRIMITIVE);
-        fields.put("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", CONTAINER);
-
-        return fields;
-    }
-
-    private Map<String, DataType> getGNBCUCPFunctionFields() {
-        Map<String, DataType> fields = new HashMap<>();
-        fields.put("id", PRIMITIVE);
-        fields.put("fdn", PRIMITIVE);
-        fields.put("pLMNId", CONTAINER);
-        fields.put("gNBCUName", PRIMITIVE);
-        fields.put("gNBId", BIGINT);
-        fields.put("cmId", CONTAINER);
-        fields.put("gNBIdLength", BIGINT);
-        fields.put("REL_FK_managed-by-managedElement", PRIMITIVE);
-        fields.put("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION", CONTAINER);
-
-        return fields;
+        List<RelationType> relationTypes = new ArrayList<>();
+        List<List<String>> relationshipInfo = extractModelInfoFromSqlFile("relationship_info");
+        relationshipInfo.forEach(l -> {
+            String name = l.get(0);
+            String aSideAssociationName = l.get(1);
+            String aSideMOType = l.get(2);
+            long aSideMinCardinality = Long.parseLong(l.get(4));
+            long aSideMaxCardinality = Long.parseLong(l.get(5));
+            String bSideAssociationName = l.get(6);
+            String bSideMOType = l.get(7);
+            long bSideMinCardinality = Long.parseLong(l.get(9));
+            long bSideMaxCardinality = Long.parseLong(l.get(10));
+            RelationshipDataLocation relationshipDataLocation = RelationshipDataLocation.valueOf(l.get(13));
+            boolean connectSameEntity = Boolean.parseBoolean(l.get(12));
+            String storedAt = l.get(14);
+            String moduleReferenceName = l.get(15);
+
+            relationTypes.add(RelationType.builder().name(name).aSideAssociation(getRelationshipAssociation(
+                    aSideAssociationName, aSideMinCardinality, aSideMaxCardinality)).aSide(SchemaRegistry
+                            .getEntityTypeByName(aSideMOType)).bSideAssociation(getRelationshipAssociation(
+                                    bSideAssociationName, bSideMinCardinality, bSideMaxCardinality)).bSide(SchemaRegistry
+                                            .getEntityTypeByName(bSideMOType)).connectsSameEntity(connectSameEntity)
+                    .relationshipStorageLocation(relationshipDataLocation).tableName(storedAt).module(SchemaRegistry
+                            .getModuleByName(moduleReferenceName)).build());
+        });
+
+        SchemaRegistry.initializeRelationTypes(relationTypes);
     }
 
     private Association getRelationshipAssociation(String associationName, long minCardinality, long maxCardinality) {
         return Association.builder().name((associationName)).minCardinality(minCardinality).maxCardinality(maxCardinality)
                 .build();
     }
+
+    private List<List<String>> extractModelInfoFromSqlFile(String tableName) {
+        List<List<String>> modelInfo = new ArrayList<>();
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader(
+                    "src/test/resources/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql"));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (line.startsWith("COPY ties_model." + tableName)) {
+                    while (!(line = reader.readLine()).startsWith("\\.")) {
+                        List<String> l = List.of(line.split("\t"));
+                        modelInfo.add(l);
+                    }
+                }
+            }
+            reader.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return modelInfo;
+    }
+
+    private Map<String, DataType> extractDataFieldsFromSqlFile(String tableName) {
+        Map<String, DataType> dataFields = new HashMap<>();
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader(
+                    "src/test/resources/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql"));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (line.startsWith("CREATE TABLE IF NOT EXISTS ties_data.\"" + tableName + "\"")) {
+                    while (!(line = reader.readLine()).startsWith(");")) {
+                        List<String> l = List.of(line.trim().replace("\t\t\t", "\t").replaceAll("[\",]", "").split("\t"));
+                        String fieldName = l.get(0);
+                        String dataType = l.get(1);
+                        switch (dataType) {
+                            case "TEXT" -> dataFields.put(fieldName, PRIMITIVE);
+                            case "INTEGER" -> dataFields.put(fieldName, INTEGER);
+                            case "BIGINT" -> dataFields.put(fieldName, BIGINT);
+                            case "DECIMAL" -> dataFields.put(fieldName, DECIMAL);
+                            case "jsonb" -> dataFields.put(fieldName, CONTAINER);
+                            case "geography" -> dataFields.put(fieldName, GEOGRAPHIC);
+                        }
+                    }
+                }
+            }
+            reader.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return dataFields;
+    }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryContainerizedTest.java b/teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryContainerizedTest.java
deleted file mode 100644 (file)
index 1cef7b2..0000000
+++ /dev/null
@@ -1,402 +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 org.oran.smo.teiv.schema;
-
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.A_SIDE;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
-import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
-import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
-import static org.oran.smo.teiv.utils.TiesConstants.TEIV_DOMAIN;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
-import static org.jooq.impl.DSL.field;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.sql.DataSource;
-
-import org.jooq.DSLContext;
-import org.jooq.JSONB;
-import org.jooq.SQLDialect;
-import org.jooq.impl.DSL;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.oran.smo.teiv.db.TestPostgresqlContainer;
-import org.oran.smo.teiv.exception.TiesException;
-
-class SchemaRegistryContainerizedTest {
-    public static TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
-    private static DSLContext dslContext;
-
-    @BeforeAll
-    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
-        String url = postgreSQLContainer.getJdbcUrl();
-        TestPostgresqlContainer.loadSampleData();
-        DataSource ds = DataSourceBuilder.create().url(url).username("test").password("test").build();
-        dslContext = DSL.using(ds, SQLDialect.POSTGRES);
-        PostgresSchemaLoader postgresSchemaLoader = new PostgresSchemaLoader(dslContext, new ObjectMapper());
-        postgresSchemaLoader.loadSchemaRegistry();
-    }
-
-    @BeforeEach
-    public void deleteAll() {
-        dslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(t -> dslContext
-                .truncate(t).cascade().execute());
-    }
-
-    @Test
-    void testGetModulesByName() {
-        //given
-        String expectedName = "o-ran-smo-teiv-cloud-to-ran";
-        String expectedNamespace = "urn:o-ran:smo-teiv-cloud-to-ran";
-        String expectedDomain = "CLOUD_TO_RAN";
-        List<String> expectedIncludedModules = List.of("o-ran-smo-teiv-cloud", "o-ran-smo-teiv-ran");
-        //when
-        Module logicalToCloud = SchemaRegistry.getModuleByName("o-ran-smo-teiv-cloud-to-ran");
-        //then
-        assertEquals(9, SchemaRegistry.getModuleRegistry().size());
-        assertTrue(SchemaRegistry.getModuleRegistry().containsValue(logicalToCloud));
-        assertEquals(expectedName, logicalToCloud.getName());
-        assertEquals(expectedNamespace, logicalToCloud.getNamespace());
-        assertEquals(expectedDomain, logicalToCloud.getDomain());
-        assertEquals(expectedIncludedModules, logicalToCloud.getIncludedModuleNames());
-        assertThrows(TiesException.class, () -> SchemaRegistry.getModuleByName("invalid-module"));
-    }
-
-    @Test
-    void testGetDomainsForModules() {
-        //given
-
-        Set<String> expectedDomains = Set.of(TEIV_DOMAIN, "OAM_TO_CLOUD", "EQUIPMENT_TO_RAN", "RAN", "OAM", "CLOUD",
-                "EQUIPMENT", "CLOUD_TO_RAN", "OAM_TO_RAN");
-        //when
-        Set<String> actualDomains = SchemaRegistry.getDomains();
-        //then
-        assertEquals(expectedDomains, actualDomains);
-    }
-
-    @Test
-    void testRootDomainIncludesAllAvailableDomains() {
-        //given
-        Set<String> availableDomains = SchemaRegistry.getDomains();
-        availableDomains.remove(TEIV_DOMAIN);
-        //when
-        List<String> rootIncludedDomains = SchemaRegistry.getIncludedDomains(TEIV_DOMAIN);
-        //then
-        assertEquals(availableDomains.size(), rootIncludedDomains.size());
-        assertTrue(availableDomains.containsAll(rootIncludedDomains));
-    }
-
-    @Test
-    void testGetModuleByDomainTrowsUnknownDomainException() {
-        assertThrows(TiesException.class, () -> SchemaRegistry.getModuleByDomain("throwError"));
-    }
-
-    //Entities
-    @Test
-    void testGetEntityNames() {
-        //given
-        Set<String> expectedEntityName = Set.of("Site", "ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt",
-                "ENodeBFunction", "CloudNativeApplication", "AntennaModule", "Sector",
-                "Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "NRCellDU", "LTESectorCarrier",
-                "ManagedElement", "NRCellCU", "NRSectorCarrier", "PhysicalNetworkAppliance", "Namespace", "GNBCUUPFunction",
-                "NodeCluster", "CloudNativeSystem", "NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
-                "CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
-                "CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-                "ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE", "GNBDUFunction", "CloudSite",
-                "EUtranCell", "GNBCUCPFunction", "AntennaCapability", "TestEntityA", "TestEntityB");
-        //when
-        Set<String> actualEntityName = SchemaRegistry.getEntityNames();
-        //then
-        assertEquals(expectedEntityName.size(), actualEntityName.size());
-        assertEquals(expectedEntityName, actualEntityName);
-    }
-
-    @Test
-    void testGetTableNameForEntity() {
-        //given
-        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByName("GNBDUFunction");
-        //then
-        assertEquals("ties_data.\"GNBDUFunction\"", gnbduFunction.getTableName());
-    }
-
-    @Test
-    void testGetFieldsForEntity() {
-        //given
-        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByName("GNBDUFunction");
-        //then
-        assertEquals(Set.of(field("dUpLMNId", JSONB.class).as("dUpLMNId"), field("gNBDUId").as("gNBDUId"), field("gNBId")
-                .as("gNBId"), field("gNBIdLength").as("gNBIdLength"), field("cmId", JSONB.class).as("cmId"), field("fdn")
-                        .as("fdn"), field("id").as("id"), field("CD_sourceIds").as("CD_sourceIds")), new HashSet<>(
-                                gnbduFunction.getAllFieldsWithId()));
-    }
-
-    @Test
-    void testGetAttrColumnsForEntity() {
-        //given
-        List<String> expectedColumns = List.of("ties_data.\"GNBDUFunction\".\"gNBDUId\"",
-                "ties_data.\"GNBDUFunction\".\"gNBId\"", "ties_data.\"GNBDUFunction\".\"gNBIdLength\"",
-                "ties_data.\"GNBDUFunction\".\"dUpLMNId\"", "ties_data.\"GNBDUFunction\".\"cmId\"",
-                "ties_data.\"GNBDUFunction\".\"fdn\"", "ties_data.\"GNBDUFunction\".\"id\"");
-        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByName("GNBDUFunction");
-        //then
-        List<String> columns = gnbduFunction.getAttributeColumnsWithId();
-        assertEquals(expectedColumns.size(), columns.size());
-        assertTrue(expectedColumns.containsAll(columns));
-    }
-
-    @Test
-    void testGetAttrColumnsForEntityWithLongNames() {
-        //given
-        List<String> expectedColumns = List.of("ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"gNBDUId\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"gNBId\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"gNBIdLength\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"dUpLMNId\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"cmId\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"3786A6CA64C9422F9E7FC35B7B039F345BBDDA65\"",
-                "ties_data.\"7D7AACEBB0E4E4732835BA4BFE708DDD3738962D\".\"id\"");
-        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByName(
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
-        //then
-        List<String> columns = gnbduFunction.getAttributeColumnsWithId();
-        assertEquals(expectedColumns.size(), columns.size());
-        assertTrue(expectedColumns.containsAll(columns));
-    }
-
-    @Test
-    void testGetEntityTypesByDomain() {
-        //given
-        List<String> expectedEntities = List.of("Site", "ENodeBFunction", "AntennaModule", "Sector", "NRCellDU",
-                "LTESectorCarrier", "NRCellCU", "NRSectorCarrier", "PhysicalNetworkAppliance", "GNBCUUPFunction",
-                "GNBDUFunction", "EUtranCell", "GNBCUCPFunction", "AntennaCapability",
-                "GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn",
-                "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-                "ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE",
-                "NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", "TestEntityA", "TestEntityB");
-        //when
-        List<String> ranLogicalToEquipmentEntityTypes = SchemaRegistry.getEntityNamesByDomain("EQUIPMENT_TO_RAN");
-        //then
-        assertEquals(expectedEntities.size(), ranLogicalToEquipmentEntityTypes.size());
-        assertTrue(expectedEntities.containsAll(ranLogicalToEquipmentEntityTypes));
-    }
-
-    //Relations
-    @Test
-    void getRelationNames() {
-        //when
-        SchemaRegistry.getRelationNames();
-        //then
-        assertEquals(41, SchemaRegistry.getRelationNames().size());
-    }
-
-    @Test
-    void testGetRelationTypeByName() {
-        //when
-        RelationType managedElementManagesEnodebfunction = SchemaRegistry.getRelationTypeByName(
-                "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION");
-        //then
-        assertTrue(SchemaRegistry.getRelationTypes().contains(managedElementManagesEnodebfunction));
-        Association expectedAssociation = new Association("managed-enodebFunction", 1, 1);
-        assertEquals(expectedAssociation.toString(), managedElementManagesEnodebfunction.getASideAssociation().toString());
-
-    }
-
-    @Test
-    void testGetRelationTypesByEntityType() {
-        //given
-        List<RelationType> expectedRelationsList = new ArrayList<>();
-        expectedRelationsList.add(SchemaRegistry.getRelationTypeByName(
-                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"));
-        expectedRelationsList.add(SchemaRegistry.getRelationTypeByName("GNBCUCPFUNCTION_PROVIDES_NRCELLCU"));
-        expectedRelationsList.add(SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"));
-        //then
-        assertEquals(3, SchemaRegistry.getRelationTypesByEntityName("GNBCUCPFunction").size());
-        assertTrue(SchemaRegistry.getRelationTypesByEntityName("GNBCUCPFunction").containsAll(expectedRelationsList));
-    }
-
-    @Test
-    void testGetFullyQualifiedNameForRelation() {
-        //given
-        RelationType gnbduFunctionRealisedByCloudnativeapplication = SchemaRegistry.getRelationTypeByName(
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        //then
-        assertEquals("o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                gnbduFunctionRealisedByCloudnativeapplication.getFullyQualifiedName());
-    }
-
-    @Test
-    void testGetTableNameForRelation() {
-        //given
-        String expectedManyToMany = "ties_data.\"GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"";
-        String expectedOneToOne = "ties_data.\"ManagedElement\"";
-        String expectedOneToMany = "ties_data.\"GNBDUFunction\"";
-        String expectedManyToOne = "ties_data.\"NodeCluster\"";
-        String expectedRelConnectingSameEntity = "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"";
-        //when
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        RelationType oneToOne = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-        RelationType manyToOne = SchemaRegistry.getRelationTypeByName("NODECLUSTER_LOCATED_AT_CLOUDSITE");
-        RelationType relConnectingSameEntity = SchemaRegistry.getRelationTypeByName(
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-        //then
-        assertEquals(expectedManyToMany, manyToMany.getTableName());
-        assertEquals(expectedOneToOne, oneToOne.getTableName());
-        assertEquals(expectedOneToMany, oneToMany.getTableName());
-        assertEquals(expectedManyToOne, manyToOne.getTableName());
-        assertEquals(expectedRelConnectingSameEntity, relConnectingSameEntity.getTableName());
-    }
-
-    @Test
-    void testGetRelationshipDataLocationForRelation() {
-        //when
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        RelationType oneToOne = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-        RelationType manyToOne = SchemaRegistry.getRelationTypeByName("NODECLUSTER_LOCATED_AT_CLOUDSITE");
-        RelationType relConnectingSameEntity = SchemaRegistry.getRelationTypeByName(
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
-        //then
-        assertEquals(RELATION, manyToMany.getRelationshipStorageLocation());
-        assertEquals(A_SIDE, oneToOne.getRelationshipStorageLocation());
-        assertEquals(B_SIDE, oneToMany.getRelationshipStorageLocation());
-        assertEquals(A_SIDE, manyToOne.getRelationshipStorageLocation());
-        assertEquals(RELATION, relConnectingSameEntity.getRelationshipStorageLocation());
-    }
-
-    @Test
-    void testGetIdColumnNameRelationTest() {
-        //given
-        String expectedManyToManyId = "id";
-        String expectedOneToManyId = "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION";
-        //when
-        RelationType manyToManyRelation = SchemaRegistry.getRelationTypeByName(
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-        //then
-        assertEquals(expectedManyToManyId, manyToManyRelation.getIdColumnName());
-        assertEquals(expectedOneToManyId, oneToMany.getIdColumnName());
-    }
-
-    @Test
-    void testGetASideColumnNameForRelationType() {
-        //given
-        String expectedManyToMAny = "aSide_GNBDUFunction";
-        String expectedOneToOne = "id";
-        String expectedOneToMany = "REL_FK_managed-by-managedElement";
-        //when
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        RelationType oneToOne = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-        //then
-        assertEquals(expectedManyToMAny, manyToMany.aSideColumnName());
-        assertEquals(expectedOneToOne, oneToOne.aSideColumnName());
-        assertEquals(expectedOneToMany, oneToMany.aSideColumnName());
-    }
-
-    @Test
-    void testGetBSideColumnNameForRelationType() {
-        //given
-        String expectedManyToMAny = "bSide_CloudNativeApplication";
-        String expectedOneToOne = "REL_FK_deployed-as-cloudNativeSystem";
-        String expectedOneToMany = "id";
-        //when
-        RelationType manyToMany = SchemaRegistry.getRelationTypeByName("GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        RelationType oneToOne = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");
-        RelationType oneToMany = SchemaRegistry.getRelationTypeByName("MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
-        //then
-        assertEquals(expectedManyToMAny, manyToMany.bSideColumnName());
-        assertEquals(expectedOneToOne, oneToOne.bSideColumnName());
-        assertEquals(expectedOneToMany, oneToMany.bSideColumnName());
-    }
-
-    @Test
-    void testGetFieldsForRelationType() {
-        //given
-        RelationType gnbduFunctionRealisedByCloudnativeapplication = SchemaRegistry.getRelationTypeByName(
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
-        //then
-        assertEquals(List.of(field(String.format(TIES_DATA,
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(QUOTED_STRING,
-                        "aSide_GNBDUFunction")), field(String.format(TIES_DATA,
-                                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(QUOTED_STRING,
-                                        "bSide_CloudNativeApplication")), field(String.format(TIES_DATA,
-                                                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(
-                                                        QUOTED_STRING, "id")), field(String.format(TIES_DATA,
-                                                                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String
-                                                                        .format(QUOTED_STRING, "CD_sourceIds"))),
-                gnbduFunctionRealisedByCloudnativeapplication.getAllFieldsWithId());
-    }
-
-    @Test
-    void testGetRelationTypesByDomain() {
-        //given
-        List<String> expectedRelations = List.of("CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION",
-                "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE", "NRCELLDU_USES_NRSECTORCARRIER",
-                "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "ENODEBFUNCTION_PROVIDES_EUTRANCELL",
-                "NRSECTORCARRIER_USES_ANTENNACAPABILITY", "GNBDUFUNCTION_PROVIDES_NRCELLDU",
-                "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "EUTRANCELL_USES_LTESECTORCARRIER",
-                "NODECLUSTER_LOCATED_AT_CLOUDSITE", "NAMESPACE_DEPLOYED_ON_NODECLUSTER",
-                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION",
-                "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
-                "LTESECTORCARRIER_USES_ANTENNACAPABILITY",
-                "GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU",
-                "GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN",
-                "CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE", "TESTENTITYA_GROUPS_TESTENTITYB",
-                "TESTENTITYA_USES_TESTENTITYB", "TESTENTITYA_PROVIDES_TESTENTITYB", "SECTOR_GROUPS_NRCELLDU");
-        //when
-        List<String> ranLogicalToCloudRelations = SchemaRegistry.getRelationNamesByDomain("CLOUD_TO_RAN");
-        //then
-        assertEquals(expectedRelations.size(), ranLogicalToCloudRelations.size());
-        assertTrue(expectedRelations.containsAll(ranLogicalToCloudRelations));
-    }
-
-    @Test
-    void testGetIncludedModules() {
-        //when
-        Module module = SchemaRegistry.getModuleByName("o-ran-smo-teiv-oam-to-ran");
-        //then
-        assertEquals(2, module.getIncludedModuleNames().size());
-        assertTrue(List.of("o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran").containsAll(module.getIncludedModuleNames()));
-    }
-
-    @Test
-    void testGetIncludedDomains() {
-        //when
-        List<String> includedDomains = SchemaRegistry.getIncludedDomains("CLOUD_TO_RAN");
-        //then
-        assertEquals(2, includedDomains.size());
-        assertTrue(List.of("RAN", "CLOUD").containsAll(includedDomains));
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryTest.java b/teiv/src/test/java/org/oran/smo/teiv/schema/SchemaRegistryTest.java
new file mode 100644 (file)
index 0000000..22bd34c
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ *  ============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.teiv.schema;
+
+import static org.oran.smo.teiv.exposure.tiespath.refiner.AliasMapper.hashAlias;
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.A_SIDE;
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.ENTITY_NOT_FOUND_IN_DOMAIN;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.RELATIONSHIP_NOT_FOUND_IN_DOMAIN;
+import static org.oran.smo.teiv.schema.SchemaRegistryErrorCode.RELATIONSHIP_NOT_FOUND_IN_MODULE;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
+import static org.oran.smo.teiv.utils.TiesConstants.TEIV_DOMAIN;
+import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA;
+import static org.jooq.impl.DSL.field;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jooq.JSONB;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import org.oran.smo.teiv.exception.TiesException;
+import org.oran.smo.teiv.exposure.spi.Module;
+
+class SchemaRegistryTest {
+
+    @BeforeAll
+    public static void beforeAll() throws UnsupportedOperationException, SchemaLoaderException {
+        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
+        mockSchemaLoader.loadSchemaRegistry();
+    }
+
+    @Test
+    void testGetModulesName() {
+        //given
+        Set<String> expectedModuleNames = Set.of("o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran", "o-ran-smo-teiv-equipment",
+                "o-ran-smo-teiv-rel-oam-ran", "o-ran-smo-teiv-rel-equipment-ran", TEIV_DOMAIN,
+                "_3gpp-common-yang-extensions", "_3gpp-common-yang-types", "ietf-geo-location", "ietf-inet-types",
+                "ietf-yang-types", "o-ran-smo-teiv-common-yang-extensions", "o-ran-smo-teiv-common-yang-types");
+        //when
+        Set<String> moduleNames = SchemaRegistry.getModuleRegistry().keySet();
+        //then
+        assertEquals(expectedModuleNames.size(), moduleNames.size());
+        assertEquals(expectedModuleNames, moduleNames);
+    }
+
+    @Test
+    void testGetModulesByName() {
+        //given
+        String expectedName = "o-ran-smo-teiv-rel-oam-ran";
+        String expectedNamespace = "urn:o-ran:smo-teiv-rel-oam-ran";
+        String expectedDomain = "REL_OAM_RAN";
+        List<String> expectedIncludedModules = List.of("o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran");
+        //when
+        Module oamToRanModule = SchemaRegistry.getModuleByName("o-ran-smo-teiv-rel-oam-ran");
+        //then
+        assertEquals(expectedName, oamToRanModule.getName());
+        assertEquals(expectedNamespace, oamToRanModule.getNamespace());
+        assertEquals(expectedDomain, oamToRanModule.getDomain());
+        assertEquals(expectedIncludedModules, oamToRanModule.getIncludedModuleNames());
+
+        assertThrows(TiesException.class, () -> SchemaRegistry.getModuleByName("invalid-module"));
+    }
+
+    @Test
+    void testGetAllDomainsIncludingRootDomain() {
+        //given
+        Set<String> expectedDomains = Set.of(TEIV_DOMAIN, "EQUIPMENT", "REL_EQUIPMENT_RAN", "OAM", "REL_OAM_RAN", "RAN");
+        //when
+        Set<String> actualDomains = SchemaRegistry.getDomains();
+        //then
+        assertEquals(expectedDomains, actualDomains);
+    }
+
+    @Test
+    void testRootDomainIncludesAllAvailableDomains() {
+        //given
+        Set<String> availableDomains = SchemaRegistry.getDomains();
+        availableDomains.remove(TEIV_DOMAIN);
+        //when
+        List<String> rootIncludedDomains = SchemaRegistry.getIncludedDomains(TEIV_DOMAIN);
+        //then
+        assertEquals(availableDomains.size(), rootIncludedDomains.size());
+        assertTrue(availableDomains.containsAll(rootIncludedDomains));
+    }
+
+    @Test
+    void testGetModuleByDomainThrowsUnknownDomainException() {
+        assertThrows(TiesException.class, () -> SchemaRegistry.getModuleByDomain("throwError"));
+    }
+
+    //Entities
+
+    @Test
+    void testGetEntityTypeByDomainAndName() throws SchemaRegistryException {
+        //when
+        List<EntityType> entityTypes = SchemaRegistry.getEntityTypeByDomainAndName("RAN", "GNBDUFunction");
+        //then
+        assertEquals(1, entityTypes.size());
+        EntityType entityType = entityTypes.get(0);
+        assertEquals("GNBDUFunction", entityType.getName());
+        assertEquals("RAN", entityType.getModule().getDomain());
+
+        final SchemaRegistryException exception = assertThrows(SchemaRegistryException.class, () -> SchemaRegistry
+                .getEntityTypeByDomainAndName("OAM", "GNBDUFunction"));
+        assertEquals(ENTITY_NOT_FOUND_IN_DOMAIN, exception.getErrorCode());
+    }
+
+    @Test
+    void testGetEntityTypeByModuleAndName() throws SchemaRegistryException {
+        //when
+        EntityType entityType = SchemaRegistry.getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction");
+        //then
+        assertEquals("GNBDUFunction", entityType.getName());
+        assertEquals("RAN", entityType.getModule().getDomain());
+
+        final SchemaRegistryException exception = assertThrows(SchemaRegistryException.class, () -> SchemaRegistry
+                .getEntityTypeByDomainAndName("o-ran-smo-teiv-oam", "GNBDUFunction"));
+        assertEquals(ENTITY_NOT_FOUND_IN_DOMAIN, exception.getErrorCode());
+    }
+
+    @Test
+    void testGetEntityNames() {
+        //given
+        List<String> expectedEntityName = List.of("AntennaCapability", "AntennaModule", "ENodeBFunction", "EUtranCell",
+                "GNBCUCPFunction", "GNBCUUPFunction", "GNBDUFunction", "LTESectorCarrier", "ManagedElement", "NRCellCU",
+                "NRCellDU", "NRSectorCarrier", "Sector", "Site");
+        //when
+        List<String> actualEntityNames = SchemaRegistry.getEntityNames();
+        //then
+        assertEquals(expectedEntityName.size(), actualEntityNames.size());
+        assertTrue(actualEntityNames.containsAll(expectedEntityName));
+    }
+
+    @Test
+    void testGetTableNameForEntity() throws SchemaRegistryException {
+        //given
+        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction");
+        //then
+        assertEquals("ties_data.\"o-ran-smo-teiv-ran_GNBDUFunction\"", gnbduFunction.getTableName());
+    }
+
+    @Test
+    void testGetClassifiersColumnNameForEntity() throws SchemaRegistryException {
+        //given
+        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction");
+        //then
+        assertEquals("CD_classifiers", gnbduFunction.getClassifiersColumnName());
+    }
+
+    @Test
+    void testGetDecoratorsColumnNameForEntity() throws SchemaRegistryException {
+        //given
+        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction");
+        //then
+        assertEquals("CD_decorators", gnbduFunction.getDecoratorsColumnName());
+    }
+
+    @Test
+    void testGetFieldsForEntity() throws SchemaRegistryException {
+        //given
+        EntityType gnbduFunction = SchemaRegistry.getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction");
+        //then
+        assertEquals(Set.of(field("dUpLMNId", JSONB.class).as("o-ran-smo-teiv-ran:GNBDUFunction.attr.dUpLMNId"), field(
+                "gNBDUId").as("o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBDUId"), field("gNBId").as(
+                        "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBId"), field("gNBIdLength").as(
+                                "o-ran-smo-teiv-ran:GNBDUFunction.attr.gNBIdLength"), field("id").as(
+                                        "o-ran-smo-teiv-ran:GNBDUFunction.id"), field("CD_sourceIds").as(
+                                                "o-ran-smo-teiv-ran:GNBDUFunction.sourceIds"), field("CD_classifiers").as(
+                                                        "o-ran-smo-teiv-ran:GNBDUFunction.classifiers"), field(
+                                                                "CD_decorators").as(
+                                                                        "o-ran-smo-teiv-ran:GNBDUFunction.decorators")),
+                new HashSet<>(gnbduFunction.getAllFieldsWithId()));
+    }
+
+    @Test
+    void testGetEntityTypesByDomain() {
+        //given
+        List<String> expectedEntities = List.of("AntennaCapability", "AntennaModule", "ENodeBFunction", "EUtranCell",
+                "GNBCUCPFunction", "GNBCUUPFunction", "GNBDUFunction", "LTESectorCarrier", "NRCellCU", "NRCellDU",
+                "NRSectorCarrier", "Sector", "Site");
+        //when
+        List<String> equipmentToRanEntityTypes = SchemaRegistry.getEntityNamesByDomain("REL_EQUIPMENT_RAN");
+        //then
+        assertEquals(expectedEntities.size(), equipmentToRanEntityTypes.size());
+        assertTrue(expectedEntities.containsAll(equipmentToRanEntityTypes));
+    }
+
+    //Relations
+    @Test
+    void getRelationNames() {
+        List<String> expectedRelationNames = List.of("ANTENNAMODULE_SERVES_ANTENNACAPABILITY",
+                "NRSECTORCARRIER_USES_ANTENNACAPABILITY", "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                "EUTRANCELL_USES_LTESECTORCARRIER", "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION", "SECTOR_GROUPS_EUTRANCELL",
+                "NRCELLDU_USES_NRSECTORCARRIER", "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION",
+                "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION",
+                "SECTOR_GROUPS_ANTENNAMODULE", "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "SECTOR_GROUPS_NRCELLDU",
+                "ENODEBFUNCTION_PROVIDES_EUTRANCELL", "ANTENNAMODULE_INSTALLED_AT_SITE",
+                "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
+                "LTESECTORCARRIER_USES_ANTENNACAPABILITY");
+        //when
+        List<String> relationNames = SchemaRegistry.getRelationNames();
+        //then
+        assertEquals(expectedRelationNames.size(), relationNames.size());
+        assertTrue(relationNames.containsAll(expectedRelationNames));
+    }
+
+    @Test
+    void testGetRelationTypeByName() {
+        //given
+        Association expectedASideAssociation = new Association("managed-gnbcucpFunction", 1, 1);
+        Association expectedBSideAssociation = new Association("managed-by-managedElement", 0, 9223372036854775807L);
+        //when
+        RelationType managedElementManagesGnbcucpfunction = SchemaRegistry.getRelationTypeByName(
+                "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
+        //then
+        assertEquals(expectedASideAssociation.toString(), managedElementManagesGnbcucpfunction.getASideAssociation()
+                .toString());
+        assertEquals(expectedBSideAssociation.toString(), managedElementManagesGnbcucpfunction.getBSideAssociation()
+                .toString());
+    }
+
+    @Test
+    void testGetRelationTypeByModuleAndName() throws SchemaRegistryException {
+        //given
+        Association expectedASideAssociation = new Association("managed-gnbcucpFunction", 1, 1);
+        Association expectedBSideAssociation = new Association("managed-by-managedElement", 0, 9223372036854775807L);
+        //when
+        RelationType managedElementManagesGnbcucpfunction = SchemaRegistry.getRelationTypeByModuleAndName(
+                "o-ran-smo-teiv-rel-oam-ran", "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
+        //then
+        assertEquals(expectedASideAssociation.toString(), managedElementManagesGnbcucpfunction.getASideAssociation()
+                .toString());
+        assertEquals(expectedBSideAssociation.toString(), managedElementManagesGnbcucpfunction.getBSideAssociation()
+                .toString());
+
+        final SchemaRegistryException exception = assertThrows(SchemaRegistryException.class, () -> SchemaRegistry
+                .getRelationTypeByModuleAndName("o-ran-smo-teiv-ran", "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"));
+        assertEquals(RELATIONSHIP_NOT_FOUND_IN_MODULE, exception.getErrorCode());
+    }
+
+    @Test
+    void testGetRelationTypeByDomainAndName() throws SchemaRegistryException {
+        //given
+        Association expectedASideAssociation = new Association("managed-gnbcucpFunction", 1, 1);
+        Association expectedBSideAssociation = new Association("managed-by-managedElement", 0, 9223372036854775807L);
+        //when
+        List<RelationType> relationTypes = SchemaRegistry.getRelationTypeByDomainAndName("REL_OAM_RAN",
+                "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
+        //then
+        assertEquals(1, relationTypes.size());
+        RelationType managedElementManagesGnbcucpfunction = relationTypes.get(0);
+        assertEquals(expectedASideAssociation.toString(), managedElementManagesGnbcucpfunction.getASideAssociation()
+                .toString());
+        assertEquals(expectedBSideAssociation.toString(), managedElementManagesGnbcucpfunction.getBSideAssociation()
+                .toString());
+
+        final SchemaRegistryException exception = assertThrows(SchemaRegistryException.class, () -> SchemaRegistry
+                .getRelationTypeByDomainAndName("OAM", "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"));
+        assertEquals(RELATIONSHIP_NOT_FOUND_IN_DOMAIN, exception.getErrorCode());
+    }
+
+    @Test
+    void testGetRelationTypesByEntityType() throws SchemaRegistryException {
+        //given
+        List<RelationType> expectedRelationsList = new ArrayList<>();
+        expectedRelationsList.add(SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY"));
+        expectedRelationsList.add(SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "SECTOR_GROUPS_ANTENNAMODULE"));
+        expectedRelationsList.add(SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-equipment",
+                "ANTENNAMODULE_INSTALLED_AT_SITE"));
+        //when
+        List<RelationType> relationTypes = SchemaRegistry.getRelationTypesByEntityName("AntennaModule");
+        //then
+        assertEquals(3, relationTypes.size());
+        assertTrue(relationTypes.containsAll(expectedRelationsList));
+    }
+
+    @Test
+    void testGetFullyQualifiedNameForRelation() throws SchemaRegistryException {
+        //given
+        RelationType gnbduFunctionRealisedByCloudnativeapplication = SchemaRegistry.getRelationTypeByModuleAndName(
+                "o-ran-smo-teiv-equipment", "ANTENNAMODULE_INSTALLED_AT_SITE");
+        //then
+        assertEquals("o-ran-smo-teiv-equipment:ANTENNAMODULE_INSTALLED_AT_SITE",
+                gnbduFunctionRealisedByCloudnativeapplication.getFullyQualifiedName());
+    }
+
+    @Test
+    void testGetTableNameForRelation() throws SchemaRegistryException {
+        //given
+        String expectedManyToMany = "ties_data.\"CFC235E0404703D1E4454647DF8AAE2C193DB402\"";
+        String expectedOneToMany = "ties_data.\"o-ran-smo-teiv-ran_NRCellDU\"";
+        String expectedManyToOne = "ties_data.\"o-ran-smo-teiv-equipment_AntennaModule\"";
+        //when
+        RelationType manyToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        RelationType oneToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        RelationType manyToOne = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-equipment",
+                "ANTENNAMODULE_INSTALLED_AT_SITE");
+        //then
+        assertEquals(expectedManyToMany, manyToMany.getTableName());
+        assertEquals(expectedOneToMany, oneToMany.getTableName());
+        assertEquals(expectedManyToOne, manyToOne.getTableName());
+    }
+
+    @Test
+    void testGetRelationshipDataLocationForRelation() throws SchemaRegistryException {
+        //when
+        RelationType manyToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        RelationType oneToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        RelationType manyToOne = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-equipment",
+                "ANTENNAMODULE_INSTALLED_AT_SITE");
+        //then
+        assertEquals(RELATION, manyToMany.getRelationshipStorageLocation());
+        assertEquals(B_SIDE, oneToMany.getRelationshipStorageLocation());
+        assertEquals(A_SIDE, manyToOne.getRelationshipStorageLocation());
+    }
+
+    @Test
+    void testGetClassifiersColumnNameForRelationType() throws SchemaRegistryException {
+        //when
+        RelationType relationType = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        //then
+        assertEquals("REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU", relationType.getClassifiersColumnName());
+    }
+
+    @Test
+    void testGetDecoratorsColumnNameForRelationType() throws SchemaRegistryException {
+        //when
+        RelationType relationType = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        //then
+        assertEquals("REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU", relationType.getDecoratorsColumnName());
+    }
+
+    @Test
+    void testGetIdColumnNameRelationTest() throws SchemaRegistryException {
+        //given
+        String expectedManyToManyId = "id";
+        String expectedOneToManyId = "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU";
+        //when
+        RelationType manyToManyRelation = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        RelationType oneToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        //then
+        assertEquals(expectedManyToManyId, manyToManyRelation.getIdColumnName());
+        assertEquals(expectedOneToManyId, oneToMany.getIdColumnName());
+    }
+
+    @Test
+    void testGetASideColumnNameForRelationType() throws SchemaRegistryException {
+        //given
+        String expectedManyToMany = "aSide_AntennaModule";
+        String expectedOneToMany = "REL_FK_provided-by-gnbduFunction";
+        //when
+        RelationType manyToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        RelationType oneToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        //then
+        assertEquals(expectedManyToMany, manyToMany.aSideColumnName());
+        assertEquals(expectedOneToMany, oneToMany.aSideColumnName());
+    }
+
+    @Test
+    void testGetBSideColumnNameForRelationType() throws SchemaRegistryException {
+        //given
+        String expectedManyToMAny = "bSide_AntennaCapability";
+        String expectedOneToMany = "id";
+        //when
+        RelationType manyToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-rel-equipment-ran",
+                "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        RelationType oneToMany = SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU");
+        //then
+        assertEquals(expectedManyToMAny, manyToMany.bSideColumnName());
+        assertEquals(expectedOneToMany, oneToMany.bSideColumnName());
+    }
+
+    @Test
+    void testGetFieldsForRelationType() throws SchemaRegistryException {
+        //given
+        RelationType antennamoduleServesAntennacapability = SchemaRegistry.getRelationTypeByModuleAndName(
+                "o-ran-smo-teiv-rel-equipment-ran", "ANTENNAMODULE_SERVES_ANTENNACAPABILITY");
+        //then
+        assertEquals(Set.of(field(String.format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String
+                .format(QUOTED_STRING, "aSide_AntennaModule")).as(hashAlias(
+                        "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.aSide")), field(String
+                                .format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String.format(
+                                        QUOTED_STRING, "bSide_AntennaCapability")).as(hashAlias(
+                                                "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.bSide")),
+                field(String.format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String.format(
+                        QUOTED_STRING, "id")).as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.id")), field(String
+                                        .format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String
+                                                .format(QUOTED_STRING, "CD_sourceIds")).as(hashAlias(
+                                                        "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.sourceIds")),
+                field(String.format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String.format(
+                        QUOTED_STRING, "CD_decorators")).as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.decorators")),
+                field(String.format(TIES_DATA, "CFC235E0404703D1E4454647DF8AAE2C193DB402") + "." + String.format(
+                        QUOTED_STRING, "CD_classifiers")).as(hashAlias(
+                                "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY.classifiers"))),
+                new HashSet<>(antennamoduleServesAntennacapability.getAllFieldsWithId()));
+    }
+
+    @Test
+    void testGetRelationTypesByDomain() {
+        //given
+        List<String> expectedRelations = List.of("ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER",
+                "ENODEBFUNCTION_PROVIDES_EUTRANCELL", "LTESECTORCARRIER_USES_ANTENNACAPABILITY", "SECTOR_GROUPS_EUTRANCELL",
+                "SECTOR_GROUPS_NRCELLDU", "NRCELLDU_USES_NRSECTORCARRIER", "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
+                "GNBDUFUNCTION_PROVIDES_NRCELLDU", "NRSECTORCARRIER_USES_ANTENNACAPABILITY",
+                "GNBCUCPFUNCTION_PROVIDES_NRCELLCU", "EUTRANCELL_USES_LTESECTORCARRIER",
+                "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION",
+                "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
+        //when
+        List<String> oamToRanRelations = SchemaRegistry.getRelationNamesByDomain("REL_OAM_RAN");
+        //then
+        assertEquals(expectedRelations.size(), oamToRanRelations.size());
+        assertTrue(expectedRelations.containsAll(oamToRanRelations));
+    }
+
+    @Test
+    void getAttributeColumnsWithFilterTest() throws SchemaRegistryException {
+        Assertions.assertEquals(Map.of(field("ties_data.\"GNBDUFunction\".\"dUpLMNId\"").as(
+                "o-ran-smo-teiv-ran:GNBDUFunction.attr.dUpLMNId"), DataType.CONTAINER), SchemaRegistry
+                        .getEntityTypeByModuleAndName("o-ran-smo-teiv-ran", "GNBDUFunction").getSpecificAttributeColumns(
+                                List.of("dUpLMNId")));
+        Assertions.assertEquals(Map.of(field("ties_data.\"AntennaModule\".\"geo-location\"").as(
+                "o-ran-smo-teiv-equipment:AntennaModule.attr.geo-location"), DataType.GEOGRAPHIC), SchemaRegistry
+                        .getEntityTypeByModuleAndName("o-ran-smo-teiv-equipment", "AntennaModule")
+                        .getSpecificAttributeColumns(List.of("geo-location")));
+        Assertions.assertEquals(Map.of(), SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").getSpecificAttributeColumns(List.of()));
+    }
+
+    @Test
+    void testGetAttributeNamesForRelation() throws SchemaRegistryException {
+        Assertions.assertEquals(Collections.emptyList(), SchemaRegistry.getRelationTypeByModuleAndName("o-ran-smo-teiv-ran",
+                "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER").getAttributeNames());
+    }
+
+    @Test
+    void testGetIncludedModules() {
+        //when
+        Module module = SchemaRegistry.getModuleByName("o-ran-smo-teiv-rel-oam-ran");
+        //then
+        assertEquals(2, module.getIncludedModuleNames().size());
+        assertTrue(List.of("o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran").containsAll(module.getIncludedModuleNames()));
+    }
+
+    @Test
+    void testGetIncludedDomains() {
+        //when
+        List<String> includedDomains = SchemaRegistry.getIncludedDomains("REL_OAM_RAN");
+        //then
+        assertEquals(2, includedDomains.size());
+        assertTrue(List.of("OAM", "RAN").containsAll(includedDomains));
+    }
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/service/EndToEndApiTest.java b/teiv/src/test/java/org/oran/smo/teiv/service/EndToEndApiTest.java
deleted file mode 100644 (file)
index 2b10333..0000000
+++ /dev/null
@@ -1,263 +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 org.oran.smo.teiv.service;
-
-import static org.oran.smo.teiv.utils.TiesConstants.REQUEST_MAPPING;
-import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import java.io.IOException;
-import java.time.Duration;
-import java.util.List;
-
-import org.awaitility.Awaitility;
-import org.jooq.DSLContext;
-import org.jooq.JSONB;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.server.LocalServerPort;
-import org.springframework.http.HttpStatusCode;
-import org.springframework.kafka.test.EmbeddedKafkaBroker;
-import org.springframework.kafka.test.context.EmbeddedKafka;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.DynamicPropertyRegistry;
-import org.springframework.test.context.DynamicPropertySource;
-import org.springframework.web.client.HttpClientErrorException;
-
-import org.oran.smo.teiv.CustomMetrics;
-import org.oran.smo.teiv.db.TestPostgresqlContainer;
-import org.oran.smo.teiv.service.kafka.KafkaTopicService;
-import org.oran.smo.teiv.startup.AppInit;
-import org.oran.smo.teiv.availability.DependentServiceAvailabilityKafka;
-import org.oran.smo.teiv.config.KafkaConfig;
-import org.oran.smo.teiv.listener.ListenerStarter;
-import org.oran.smo.teiv.utils.CloudEventTestUtil;
-import org.oran.smo.teiv.utils.EndToEndExpectedResults;
-import org.oran.smo.teiv.utils.EndToEndTestUtil;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-
-@EmbeddedKafka
-@SpringBootTest(properties = {
-        "kafka.server.bootstrap-server-host:#{environment.getProperty(\"spring.embedded.kafka.brokers\").split(\":\")[0]}",
-        "kafka.server.bootstrap-server-port:#{environment.getProperty(\"spring.embedded.kafka.brokers\").split(\":\")[1]}",
-        "kafka.availability.retryIntervalMs:10",
-        "kafka.topic.replicas:1" }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-@ActiveProfiles({ "test", "ingestion" })
-@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
-class EndToEndApiTest {
-    private static final TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
-
-    @Autowired
-    private DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka;
-
-    @Autowired
-    private KafkaTopicService kafkaTopicService;
-
-    @Autowired
-    private ListenerStarter listenerStarter;
-
-    @Autowired
-    private EmbeddedKafkaBroker embeddedKafkaBroker;
-
-    @Autowired
-    private CustomMetrics customMetrics;
-
-    @LocalServerPort
-    private int port;
-
-    private AppInit appInit;
-
-    private static String URI;
-
-    @Autowired
-    private KafkaConfig kafkaConfig;
-
-    @Autowired
-    private DSLContext writeDataDslContext;
-
-    @DynamicPropertySource
-    static void setProperties(DynamicPropertyRegistry registry) {
-        registry.add("spring.datasource.read.jdbc-url", () -> postgreSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.read.username", () -> postgreSQLContainer.getUsername());
-        registry.add("spring.datasource.read.password", () -> postgreSQLContainer.getPassword());
-
-        registry.add("spring.datasource.write.jdbc-url", () -> postgreSQLContainer.getJdbcUrl());
-        registry.add("spring.datasource.write.username", () -> postgreSQLContainer.getUsername());
-        registry.add("spring.datasource.write.password", () -> postgreSQLContainer.getPassword());
-    }
-
-    @BeforeEach
-    void setUp() {
-        writeDataDslContext.meta().filterSchemas(s -> s.getName().equals(TIES_DATA_SCHEMA)).getTables().forEach(
-                t -> writeDataDslContext.truncate(t).cascade().execute());
-        appInit = new AppInit(dependentServiceAvailabilityKafka, kafkaTopicService, listenerStarter);
-        appInit.startUpHandler();
-        URI = String.format("http://localhost:%s%s/domains/", port, REQUEST_MAPPING);
-    }
-
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
-    @Test
-    void testEndToEndApi() {
-        final String TEST_EVENT_FOLDER = "src/test/resources/cloudeventdata/end-to-end/";
-        final String EXPECTED_RESULTS_FOLDER = "src/test/resources/cloudeventdata/end-to-end/expected-results/api/";
-
-        final String CREATE_MANY_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-create-many-to-many.json";
-        final String CREATE_MANY_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-create-many-to-one.json";
-        final String CREATE_ONE_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-create-one-to-many.json";
-        final String CREATE_SECOND_CASE_PATH = TEST_EVENT_FOLDER + "ce-create-second-case.json";
-        final String CREATE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH = TEST_EVENT_FOLDER + "ce-create-relationship-connecting-same-entity.json";
-
-        final String MERGE_ONE_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-merge-one-to-many-deprecated-structure.json";
-
-        final String DELETE_MANY_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-delete-many-to-many.json";
-        final String DELETE_MANY_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-delete-many-to-one.json";
-        final String DELETE_ONE_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-delete-one-to-many.json";
-        final String DELETE_EVENT_CMHANDLE_PATH = TEST_EVENT_FOLDER + "ce-source-entity-delete-cm-handle.json";
-        final String DELETE_EVENT_CMHANDLE_PATH_2 = TEST_EVENT_FOLDER + "ce-source-entity-delete-cm-handle2.json";
-        final String DELETE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH = TEST_EVENT_FOLDER + "ce-delete-relationship-connecting-same-entity.json";
-
-        final String EXP_CREATE_MANY_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-many-to-many.json";
-        final String EXP_CREATE_MANY_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-many-to-one.json";
-        final String EXP_CREATE_ONE_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-one-to-many.json";
-        final String EXP_CREATE_SECOND_CASE_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-second-case.json";
-        final String EXP_CREATE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-relationship-connecting-same-entity.json";
-
-        final String EXP_MERGE_ONE_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-merge-one-to-many.json";
-
-        final String EXP_DELETE_MANY_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-delete-many-to-many.json";
-        final String EXP_DELETE_ONE_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-delete-one-to-many.json";
-        final String EXP_DELETE_MANY_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "exp-delete-many-to-one.json";
-        final String EXP_SOURCE_ENTITY_DELETE_CM_HANDLE = EXPECTED_RESULTS_FOLDER + "exp-source-entity-delete-cm-handle.json";
-        final String EXP_DELETE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH = EXPECTED_RESULTS_FOLDER + "exp-delete-relationship-connecting-same-entity.json";
-
-        validateReceivedCloudEventMetrics(0, 0, 0, 0);
-
-        sendEventFromFile(CREATE_MANY_TO_MANY_PATH);
-        sendEventFromFile(CREATE_ONE_TO_MANY_PATH);
-        sendEventFromFile(CREATE_MANY_TO_ONE_PATH);
-        sendEventFromFile(CREATE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                validateApiResultsWithValues(EXP_CREATE_MANY_TO_MANY_PATH);
-                validateApiResultsWithValues(EXP_CREATE_ONE_TO_MANY_PATH);
-                validateApiResultsWithValues(EXP_CREATE_MANY_TO_ONE_PATH);
-                validateApiResultsWithValues(EXP_CREATE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH);
-                validateReceivedCloudEventMetrics(4, 0, 0, 0);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Create many to many event: " + e
-                        .getMessage(), e);
-            }
-        });
-
-        sendEventFromFile(MERGE_ONE_TO_MANY_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                validateApiResultsWithValues(EXP_MERGE_ONE_TO_MANY_PATH);
-                validateReceivedCloudEventMetrics(4, 1, 0, 0);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Merge one to many event: " + e.getMessage(),
-                        e);
-            }
-
-        });
-
-        sendEventFromFile(CREATE_SECOND_CASE_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                validateApiResultsWithValues(EXP_CREATE_SECOND_CASE_PATH);
-                validateReceivedCloudEventMetrics(5, 1, 0, 0);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Create with CmHandle event: " + e
-                        .getMessage(), e);
-            }
-        });
-
-        sendEventFromFile(DELETE_MANY_TO_MANY_PATH);
-        sendEventFromFile(DELETE_ONE_TO_MANY_PATH);
-        sendEventFromFile(DELETE_MANY_TO_ONE_PATH);
-        sendEventFromFile(DELETE_EVENT_CMHANDLE_PATH);
-        sendEventFromFile(DELETE_EVENT_CMHANDLE_PATH_2);
-        sendEventFromFile(DELETE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                validateApiResultsAfterDelete(EXP_DELETE_MANY_TO_MANY_PATH);
-                validateApiResultsAfterDelete(EXP_DELETE_ONE_TO_MANY_PATH);
-                validateApiResultsAfterDelete(EXP_DELETE_MANY_TO_ONE_PATH);
-                validateApiResultsAfterDelete(EXP_SOURCE_ENTITY_DELETE_CM_HANDLE);
-                validateApiResultsAfterDelete(EXP_DELETE_RELATIONSHIP_CONNECTING_SAME_ENTITY_PATH);
-                validateReceivedCloudEventMetrics(5, 1, 4, 2);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Delete event: " + e.getMessage(), e);
-            }
-        });
-    }
-
-    private void validateReceivedCloudEventMetrics(final int create, final int merge, final int delete,
-            final int sourceDelete) {
-        assertEquals(create, customMetrics.getNumReceivedCloudEventCreate().count());
-        assertEquals(merge, customMetrics.getNumReceivedCloudEventMerge().count());
-        assertEquals(delete, customMetrics.getNumReceivedCloudEventDelete().count());
-        assertEquals(sourceDelete, customMetrics.getNumReceivedCloudEventSourceEntityDelete().count());
-    }
-
-    private void validateApiResultsWithValues(final String expectedValuesCollectionPath) throws JsonMappingException,
-            JsonProcessingException, IOException {
-        EndToEndExpectedResults values = getExpectedResults(expectedValuesCollectionPath);
-        values.getAll().forEach((requestSubUri, responseResult) -> {
-            String apiRes = processApiCall(URI + requestSubUri);
-            String expectedRes = responseResult.toString();
-            assertEquals(JSONB.jsonb(expectedRes), JSONB.jsonb(apiRes));
-        });
-    }
-
-    private void validateApiResultsAfterDelete(String requestUrlCollectionPath) {
-        EndToEndExpectedResults values = getExpectedResults(requestUrlCollectionPath);
-        assertDoesNotThrow(() -> values.getAll(), "Reading expected results resulted in error.").keySet().forEach((key) -> {
-            assertResponseNotContainId(URI + key);
-        });
-    };
-
-    private void assertResponseNotContainId(final String requestUri) {
-        HttpClientErrorException e = assertThrows(HttpClientErrorException.class, () -> EndToEndTestUtil.processApiCall(
-                requestUri));
-        assertEquals(HttpStatusCode.valueOf(404), e.getStatusCode(), "API Response status is not 404, but it should");
-    }
-
-    private void sendEventFromFile(final String path) {
-        assertDoesNotThrow(() -> EndToEndTestUtil.sendEventList(List.of(CloudEventTestUtil.getCloudEventFromJsonFile(path)),
-                embeddedKafkaBroker, kafkaConfig), "Sending cloud event from file resulted in error.");
-    }
-
-    private EndToEndExpectedResults getExpectedResults(final String path) {
-        return assertDoesNotThrow(() -> new EndToEndExpectedResults(path), "Reading expected values resulted in error.");
-
-    }
-
-    private String processApiCall(final String uri) {
-        return assertDoesNotThrow(() -> EndToEndTestUtil.processApiCall(uri), "Processing api call resulted in error.");
-    }
-}
index 720447a..7537ed5 100644 (file)
@@ -26,16 +26,31 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
 
-import java.io.IOException;
+import java.io.File;
 import java.time.Duration;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.kafka.CloudEventSerializer;
+import org.apache.kafka.clients.admin.Admin;
+import org.apache.kafka.clients.admin.ConsumerGroupDescription;
+import org.apache.kafka.clients.admin.DescribeConsumerGroupsOptions;
+import org.apache.kafka.clients.admin.DescribeConsumerGroupsResult;
+import org.apache.kafka.clients.producer.Producer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.common.serialization.StringSerializer;
 import org.awaitility.Awaitility;
 import org.jooq.DSLContext;
 import org.jooq.Record;
 import org.jooq.Result;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.oran.smo.teiv.CustomMetrics;
@@ -47,11 +62,13 @@ import org.oran.smo.teiv.service.kafka.KafkaTopicService;
 import org.oran.smo.teiv.startup.AppInit;
 import org.oran.smo.teiv.utils.CloudEventTestUtil;
 import org.oran.smo.teiv.utils.EndToEndExpectedResults;
-import org.oran.smo.teiv.utils.EndToEndTestUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaAdmin;
 import org.springframework.kafka.test.EmbeddedKafkaBroker;
 import org.springframework.kafka.test.context.EmbeddedKafka;
+import org.springframework.kafka.test.utils.KafkaTestUtils;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.DynamicPropertyRegistry;
@@ -61,10 +78,11 @@ import org.springframework.test.context.DynamicPropertySource;
 @SpringBootTest(properties = {
         "kafka.server.bootstrap-server-host:#{environment.getProperty(\"spring.embedded.kafka.brokers\").split(\":\")[0]}",
         "kafka.server.bootstrap-server-port:#{environment.getProperty(\"spring.embedded.kafka.brokers\").split(\":\")[1]}",
-        "kafka.availability.retryIntervalMs:10", "kafka.topic.replicas:1" })
+        "kafka.availability.retryIntervalMs:10", "kafka.topic.replicas:1",
+        "kafka.topology-ingestion.consumer.concurrency:2" })
 @ActiveProfiles({ "test", "ingestion" })
 public class EndToEndDbTest {
-    public static TestPostgresqlContainer postgresqlContainer = TestPostgresqlContainer.getInstance();
+    private static TestPostgresqlContainer postgresqlContainer = TestPostgresqlContainer.getInstance();
 
     @Autowired
     private DependentServiceAvailabilityKafka dependentServiceAvailabilityKafka;
@@ -81,37 +99,27 @@ public class EndToEndDbTest {
     @Autowired
     private CustomMetrics customMetrics;
 
-    @Autowired
-    private TiesDbService tiesDbService;
-
     private AppInit appInit;
 
     @Autowired
     private KafkaConfig kafkaConfig;
 
+    @Autowired
+    private KafkaAdmin kafkaAdmin;
+
     @Autowired
     private DSLContext writeDataDslContext;
 
-    private final static String CNA_TABLE = "CloudNativeApplication";
-    private final static String CNS_TABLE = "CloudNativeSystem";
-    private final static String ME_TABLE = "ManagedElement";
-    private final static String GNBDU_TABLE = "GNBDUFunction";
-    private final static String GNBCUUP_TABLE = "GNBCUUPFunction";
-    private final static String GNBCUCP_TABLE = "GNBCUCPFunction";
-    private final static String NRCELLDU_TABLE = "NRCellDU";
-    private final static String GNBDU_CNA_TABLE = "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
-    private final static String GNBCUUP_CNA_TABLE = "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
-    private final static String GNBCUCP_CNA_TABLE = "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
+    static Producer<String, CloudEvent> producer;
 
     private static final String TEST_EVENT_FOLDER = "src/test/resources/cloudeventdata/end-to-end/";
-    private static final String EXPECTED_RESULTS_FOLDER = "src/test/resources/cloudeventdata/end-to-end/expected-results/db/";
+    private static final String EXPECTED_RESULTS_FOLDER = "src/test/resources/cloudeventdata/end-to-end/expected-results/";
 
     @DynamicPropertySource
     static void setProperties(DynamicPropertyRegistry registry) {
         registry.add("spring.datasource.read.jdbc-url", () -> postgresqlContainer.getJdbcUrl());
         registry.add("spring.datasource.read.username", () -> postgresqlContainer.getUsername());
         registry.add("spring.datasource.read.password", () -> postgresqlContainer.getPassword());
-
         registry.add("spring.datasource.write.jdbc-url", () -> postgresqlContainer.getJdbcUrl());
         registry.add("spring.datasource.write.username", () -> postgresqlContainer.getUsername());
         registry.add("spring.datasource.write.password", () -> postgresqlContainer.getPassword());
@@ -123,89 +131,135 @@ public class EndToEndDbTest {
                 t -> writeDataDslContext.truncate(t).cascade().execute());
         appInit = new AppInit(dependentServiceAvailabilityKafka, kafkaTopicService, listenerStarter);
         appInit.startUpHandler();
+        producer = new DefaultKafkaProducerFactory<>(new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker)),
+                new StringSerializer(), new CloudEventSerializer()).createProducer();
+    }
+
+    @AfterEach
+    void tearDown() {
+        embeddedKafkaBroker.destroy();
     }
 
     @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
     @Test
-    void testEndToEndDb() throws InterruptedException, IOException {
+    void testEndToEndDb() {
+        final String CREATE_ONE_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-create-one-to-one.json";
         final String CREATE_MANY_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-create-many-to-many.json";
         final String CREATE_SECOND_CASE_PATH = TEST_EVENT_FOLDER + "ce-create-second-case.json";
-        final String MERGE_ONE_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-merge-one-to-many-deprecated-structure.json";
-        final String DELETE_EVENT_PATH = TEST_EVENT_FOLDER + "ce-delete-many-to-many.json";
-        final String DELETE_EVENT_ONE_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-delete-one-to-one.json";
-        final String DELETE_EVENT_CMHANDLE_PATH = TEST_EVENT_FOLDER + "ce-source-entity-delete-cm-handle.json";
-        final String CREATE_ONE_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-create-one-to-one.json";
+        final String MERGE_ONE_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-merge-one-to-many.json";
+        final String DELETE_MANY_TO_MANY_PATH = TEST_EVENT_FOLDER + "ce-delete-many-to-many.json";
+        final String DELETE_ONE_TO_ONE_PATH = TEST_EVENT_FOLDER + "ce-delete-one-to-one.json";
+        final String DELETE_CMHANDLE_PATH = TEST_EVENT_FOLDER + "ce-source-entity-delete-cm-handle.json";
 
+        final String EXP_CREATE_ONE_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-one-to-one.json";
         final String EXP_CREATE_MANY_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-many-to-many.json";
-        final String EXP_MERGE_ONE_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-merge-one-to-many.json";
         final String EXP_CREATE_SECOND_CASE_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-second-case.json";
-        final String EXP_CREATE_ONE_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "exp-create-one-to-one.json";
-        final String EXP_ONE_TO_ONE_PATH_AFTER_DELETE = EXPECTED_RESULTS_FOLDER + "exp-delete-one-to-one.json";
+        final String EXP_MERGE_ONE_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "exp-merge-one-to-many.json";
+        final String EXP_DELETE_ONE_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "exp-delete-one-to-one.json";
+        final String NOT_EXP_DELETE_ONE_TO_ONE_PATH = EXPECTED_RESULTS_FOLDER + "not-exp-delete-one-to-one.json";
+        final String NOT_EXP_DELETE_MANY_TO_MANY_PATH = EXPECTED_RESULTS_FOLDER + "not-exp-delete-many-to-many.json";
+        final String NOT_EXP_DELETE_CMHANDLE_PATH = EXPECTED_RESULTS_FOLDER + "not-exp-source-entity-delete-cm-handle.json";
 
         validateReceivedCloudEventMetrics(0, 0, 0, 0);
         sendEventFromFile(CREATE_ONE_TO_ONE_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                EndToEndExpectedResults values = getExpectedResults(EXP_CREATE_ONE_TO_ONE_PATH);
-                validateDbResultsAfterOneToOneCE(values);
-                validateReceivedCloudEventMetrics(1, 0, 0, 0);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Create one to one event: " + e.getMessage(),
-                        e);
-            }
+        validateWithTimeout(999999, () -> {
+            EndToEndExpectedResults expected = getExpectedResults(EXP_CREATE_ONE_TO_ONE_PATH);
+            assertDbContainsExpectedValues(expected);
+            validateReceivedCloudEventMetrics(1, 0, 0, 0);
         });
 
         sendEventFromFile(CREATE_MANY_TO_MANY_PATH);
-        Awaitility.await().atMost(10, TimeUnit.SECONDS).pollDelay(Duration.ofSeconds(5)).untilAsserted(
-                () -> assertWithErrorMessage(() -> {
-                    EndToEndExpectedResults values = getExpectedResults(EXP_CREATE_MANY_TO_MANY_PATH);
-                    validateDbResultsAfterCreate(values);
-                    validateReceivedCloudEventMetrics(2, 0, 0, 0);
-                }, "Assertion failed during validation of Create many to many event"));
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults expected = getExpectedResults(EXP_CREATE_MANY_TO_MANY_PATH);
+            assertDbContainsExpectedValues(expected);
+            validateReceivedCloudEventMetrics(2, 0, 0, 0);
+        });
 
         sendEventFromFile(MERGE_ONE_TO_MANY_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> assertWithErrorMessage(() -> {
-            EndToEndExpectedResults values = getExpectedResults(EXP_MERGE_ONE_TO_MANY_PATH);
-            validateDbResultsAfterMerge(values);
+
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults expected = getExpectedResults(EXP_MERGE_ONE_TO_MANY_PATH);
+            assertDbContainsExpectedValues(expected);
             validateReceivedCloudEventMetrics(2, 1, 0, 0);
-        }, "Assertion failed during validation of Merge one to many event"));
+        });
 
         sendEventFromFile(CREATE_SECOND_CASE_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> assertWithErrorMessage(() -> {
-            EndToEndExpectedResults values = getExpectedResults(EXP_CREATE_SECOND_CASE_PATH);
-            validateDbResultsAfterCmHandle(values);
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults expected = getExpectedResults(EXP_CREATE_SECOND_CASE_PATH);
+            assertDbContainsExpectedValues(expected);
             validateReceivedCloudEventMetrics(3, 1, 0, 0);
-        }, "Assertion failed during validation of Create with CmHandle event"));
+        });
 
-        sendEventFromFile(DELETE_EVENT_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> assertWithErrorMessage(() -> {
-            validateDbResultsAfterDelete();
+        sendEventFromFile(DELETE_MANY_TO_MANY_PATH);
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults notExpected = getExpectedResults(NOT_EXP_DELETE_MANY_TO_MANY_PATH);
+            assertDbNotContainsExpectedValues(notExpected);
             validateReceivedCloudEventMetrics(3, 1, 1, 0);
-        }, "Assertion failed during validation of Delete event"));
+        });
 
-        sendEventFromFile(DELETE_EVENT_ONE_TO_ONE_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                EndToEndExpectedResults values = getExpectedResults(EXP_ONE_TO_ONE_PATH_AFTER_DELETE);
-                validateDbResultsAfterDeleteOneToOne(values);
-                validateReceivedCloudEventMetrics(3, 1, 2, 0);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Delete one to one relationship event: " + e
-                        .getMessage(), e);
-            }
+        sendEventFromFile(DELETE_ONE_TO_ONE_PATH);
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults expected = getExpectedResults(EXP_DELETE_ONE_TO_ONE_PATH);
+            assertDbContainsExpectedValues(expected);
+            EndToEndExpectedResults notExpected = getExpectedResults(NOT_EXP_DELETE_ONE_TO_ONE_PATH);
+            assertDbNotContainsExpectedValues(notExpected);
+            validateReceivedCloudEventMetrics(3, 1, 2, 0);
         });
 
-        sendEventFromFile(DELETE_EVENT_CMHANDLE_PATH);
-        Awaitility.await().pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
-            try {
-                validateDbResultsAfterDeleteCmHandle();
-                validateReceivedCloudEventMetrics(3, 1, 2, 1);
-            } catch (AssertionError e) {
-                throw new AssertionError("Assertion failed during validation of Delete with CmHandle event: " + e
-                        .getMessage(), e);
-            }
+        sendEventFromFile(DELETE_CMHANDLE_PATH);
+        validateWithTimeout(20, () -> {
+            EndToEndExpectedResults notExpected = getExpectedResults(NOT_EXP_DELETE_CMHANDLE_PATH);
+            assertDbNotContainsExpectedValues(notExpected);
+            validateReceivedCloudEventMetrics(3, 1, 2, 1);
         });
+    }
 
+    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
+    @Test
+    void testTopologyIngestionConcurrentListeners() {
+        final String COMMON_EVENT_FOLDER = "src/test/resources/cloudeventdata/common/";
+
+        List<String> commonPartition0 = List.of("ce-invalid-entity-attribute.json", "ce-one-entity.json",
+                "ce-relationship-invalid-module.json", "ce-relationship-invalid-module-type-pair.json",
+                "ce-create-geo-location.json", "ce-create-many-to-many.json");
+        List<String> commonPartition1 = List.of("ce-relationship-invalid-type.json", "ce-relationship-missing-a-side.json",
+                "ce-relationship-missing-b-side.json", "ce-relationship-missing-both-sides.json",
+                "ce-create-many-to-one.json", "ce-create-one-to-many.json");
+        List<String> partition2 = List.of("ce-create-one-to-one.json", "ce-create-relationship-connecting-same-entity.json",
+                "ce-create-second-case.json", "ce-delete-many-to-many.json", "ce-delete-many-to-one.json",
+                "ce-delete-one-to-many.json");
+        List<String> partition3 = List.of("ce-delete-one-to-one.json", "ce-delete-relationship-connecting-same-entity.json",
+                "ce-merge-long-names.json", "ce-merge-one-to-many2.json", "ce-source-entity-delete-cm-handle.json");
+
+        List<String> cloudEventsForPartition0 = new ArrayList<>();
+        cloudEventsForPartition0.addAll(getMultipleFilesInDirectory(COMMON_EVENT_FOLDER, commonPartition0));
+        cloudEventsForPartition0.addAll(getMultipleFilesInDirectory(TEST_EVENT_FOLDER, commonPartition0));
+
+        List<String> cloudEventsForPartition1 = new ArrayList<>();
+        cloudEventsForPartition1.addAll(getMultipleFilesInDirectory(COMMON_EVENT_FOLDER, commonPartition1));
+        cloudEventsForPartition1.addAll(getMultipleFilesInDirectory(TEST_EVENT_FOLDER, commonPartition1));
+
+        List<String> cloudEventsForPartition2 = getMultipleFilesInDirectory(TEST_EVENT_FOLDER, partition2);
+        List<String> cloudEventsForPartition3 = getMultipleFilesInDirectory(TEST_EVENT_FOLDER, partition3);
+
+        List<List<String>> cloudEventPathLists = List.of(cloudEventsForPartition0, cloudEventsForPartition1,
+                cloudEventsForPartition2, cloudEventsForPartition3);
+
+        produceKafkaMessages(cloudEventPathLists, List.of(0, 1, 2, 3));
+        validateWithTimeout(10, () -> {
+            assertEquals(2, assertDoesNotThrow(() -> getActiveConsumers(kafkaConfig.getTopologyIngestion().getGroupId())));
+            validateReceivedCloudEventMetrics(15, 2, 5, 1);
+            validatePersistedCloudEventMetrics(8, 2, 5, 1);
+        });
+    }
+
+    private void validatePersistedCloudEventMetrics(final int createEventQuantity, final int mergeEventQuantity,
+            final int deleteEventQuantity, final int sourceEntityDeleteEventQuantity) {
+        assertEquals(createEventQuantity, customMetrics.getNumSuccessfullyPersistedCreateCloudEvents().count());
+        assertEquals(deleteEventQuantity, customMetrics.getNumSuccessfullyPersistedDeleteCloudEvents().count());
+        assertEquals(mergeEventQuantity, customMetrics.getNumSuccessfullyPersistedMergeCloudEvents().count());
+        assertEquals(sourceEntityDeleteEventQuantity, customMetrics
+                .getNumSuccessfullyPersistedSourceEntityDeleteCloudEvents().count());
     }
 
     private void validateReceivedCloudEventMetrics(final int create, final int merge, final int delete,
@@ -216,124 +270,97 @@ public class EndToEndDbTest {
         assertEquals(sourceDelete, customMetrics.getNumReceivedCloudEventSourceEntityDelete().count());
     }
 
-    private void validateDbResultsAfterCreate(final EndToEndExpectedResults values) {
-        assertDatabaseContainsValues(CNA_TABLE, values.get("entity_map_CNA_1"));
-        assertDatabaseContainsValues(CNA_TABLE, values.get("entity_map_CNA_2"));
-        assertDatabaseContainsValues(CNA_TABLE, values.get("entity_map_CNA_3"));
-        assertDatabaseContainsValues(GNBCUUP_TABLE, values.get("entity_map_GNBCUUP_1"));
-        assertDatabaseContainsValues(GNBCUCP_TABLE, values.get("entity_map_GNBCUCP_1"));
-        assertDatabaseContainsValues(GNBDU_TABLE, values.get("entity_map_GNBDU_1"));
-
-        assertDatabaseContainsValues(GNBDU_CNA_TABLE, values.get("relation_map_GNBDU_CNA_1"));
-        assertDatabaseContainsValues(GNBDU_CNA_TABLE, values.get("relation_map_GNBDU_CNA_4"));
-        assertDatabaseContainsValues(GNBCUUP_CNA_TABLE, values.get("relation_map_GNBCUUP_CNA_2"));
-        assertDatabaseContainsValues(GNBCUUP_CNA_TABLE, values.get("relation_map_GNBCUUP_CNA_5"));
-        assertDatabaseContainsValues(GNBCUCP_CNA_TABLE, values.get("relation_map_GNBCUCP_CNA_3"));
-        assertDatabaseContainsValues(GNBCUCP_CNA_TABLE, values.get("relation_map_GNBCUCP_CNA_6"));
-
+    private void assertDbContainsExpectedValues(EndToEndExpectedResults expectedResults) {
+        expectedResults.getTables().forEach(tableName -> expectedResults.getTableData(tableName).forEach(
+                attributes -> assertDatabaseContainsValues(tableName, attributes)));
     }
 
-    private void validateDbResultsAfterOneToOneCE(final EndToEndExpectedResults values) throws IOException {
-        assertDatabaseContainsValues(CNS_TABLE, values.get("entity_map_CNS_1"));
-        assertDatabaseContainsValues(ME_TABLE, values.get("entity_map_ME_1"));
-        assertDatabaseContainsValues(CNS_TABLE, values.get("entity_map_CNS_2"));
-        assertDatabaseContainsValues(ME_TABLE, values.get("entity_map_ME_2"));
+    private void assertDbNotContainsExpectedValues(EndToEndExpectedResults expectedResults) {
+        expectedResults.getTables().forEach(tableName -> expectedResults.getTableEntryIds(tableName).forEach(
+                ids -> assertDatabaseDoesNotContainRecord(tableName, ids)));
     }
 
-    private void validateDbResultsAfterMerge(final EndToEndExpectedResults values) {
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_1"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_2"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_3"));
-
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_1"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_2"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_3"));
+    private void assertDatabaseContainsValues(final String table, final Map<String, Object> attributes) {
+        Result<Record> results = TiesDbServiceContainerizedTest.selectAllRowsFromTable(writeDataDslContext,
+                "ties_data.\"" + table + "\"");
+        boolean containsExpectedData = results.stream().anyMatch(row -> attributes.entrySet().stream().allMatch(attr -> {
+            if (attr.getValue() != null) {
+                return Objects.equals(attr.getValue().toString(), row.get(attr.getKey()).toString());
+            }
+            return row.get(attr.getKey()) == null;
+        }));
+        assertTrue(containsExpectedData, String.format(
+                "Database table \"%s\" does not contain expected data, but it should.", table));
     }
 
-    private void validateDbResultsAfterCmHandle(final EndToEndExpectedResults values) {
-        assertDatabaseContainsValues(CNA_TABLE, values.get("entity_map_CNA_4"));
-        assertDatabaseContainsValues(GNBDU_TABLE, values.get("entity_map_GNBDU_1"));
-        assertDatabaseContainsValues(GNBDU_TABLE, values.get("entity_map_GNBDU_2"));
-        assertDatabaseContainsValues(GNBCUUP_TABLE, values.get("entity_map_GNBCUUP_1"));
-        assertDatabaseContainsValues(GNBCUCP_TABLE, values.get("entity_map_GNBCUCP_1"));
-        assertDatabaseContainsValues(GNBCUCP_TABLE, values.get("entity_map_GNBCUCP_2"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_1"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_2"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("entity_map_NRCellDU_3"));
-        assertDatabaseContainsValues(GNBDU_CNA_TABLE, values.get("relation_map_GNBDU_CNA_1"));
-        assertDatabaseContainsValues(GNBCUUP_CNA_TABLE, values.get("relation_map_GNBCUUP_CNA_2"));
-        assertDatabaseContainsValues(GNBCUCP_CNA_TABLE, values.get("relation_map_GNBCUCP_CNA_3"));
-        assertDatabaseContainsValues(GNBDU_CNA_TABLE, values.get("relation_map_GNBDU_CNA_4"));
-        assertDatabaseContainsValues(GNBCUUP_CNA_TABLE, values.get("relation_map_GNBCUUP_CNA_5"));
-        assertDatabaseContainsValues(GNBCUCP_CNA_TABLE, values.get("relation_map_GNBCUCP_CNA_6"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_1"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_2"));
-        assertDatabaseContainsValues(NRCELLDU_TABLE, values.get("relation_map_GNBDU_NRCellDU_3"));
+    private void assertDatabaseDoesNotContainRecord(final String table, final String id) {
+        Result<Record> results = TiesDbServiceContainerizedTest.selectAllRowsFromTable(writeDataDslContext,
+                "ties_data.\"" + table + "\"");
+        if (results.isNotEmpty()) {
+            boolean containsRecord = results.stream().map(row -> row.get("id").toString()).anyMatch(id::equals);
+            assertFalse(containsRecord, String.format("Database table \"%s\" contains record: \"%s\", but it should not.",
+                    table, id));
+        }
     }
 
-    private void validateDbResultsAfterDelete() {
-        assertDatabaseDoesNotContainRecord(CNA_TABLE, "CloudNativeApplication_3");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_TABLE, "GNBCUCP_1");
-        assertDatabaseDoesNotContainRecord(GNBDU_CNA_TABLE, "relation_1");
-        assertDatabaseDoesNotContainRecord(GNBCUUP_CNA_TABLE, "relation_5");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_CNA_TABLE, "relation_3");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_CNA_TABLE, "relation_6");
+    private int getActiveConsumers(String consumerGroupId) throws InterruptedException, ExecutionException {
+        try (Admin adminClient = Admin.create(kafkaAdmin.getConfigurationProperties())) {
+            DescribeConsumerGroupsOptions options = new DescribeConsumerGroupsOptions().includeAuthorizedOperations(false);
+            DescribeConsumerGroupsResult consumerGroupsResult = adminClient.describeConsumerGroups(List.of(consumerGroupId),
+                    options);
+            ConsumerGroupDescription description = consumerGroupsResult.describedGroups().get(consumerGroupId).get();
+            return description.members().size();
+        }
     }
 
-    private void validateDbResultsAfterDeleteCmHandle() {
-        assertDatabaseDoesNotContainRecord(GNBDU_TABLE, "GNBDU_SED_1");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_TABLE, "GNBCUCP_SED_1");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_TABLE, "GNBCUCP_SED_2");
-        assertDatabaseDoesNotContainRecord(GNBCUCP_CNA_TABLE, "relation_sed_1");
-        assertDatabaseDoesNotContainRecord(GNBDU_CNA_TABLE, "relation_sed_2");
+    private List<String> getMultipleFilesInDirectory(String directoryName, List<String> filenames) {
+        File[] files = new File(directoryName).listFiles();
+        return files == null ?
+                List.of() :
+                Stream.of(files).map(File::getName).filter(filenames::contains).map(filename -> String.format("%s%s",
+                        directoryName, filename)).toList();
     }
 
-    private void validateDbResultsAfterDeleteOneToOne(final EndToEndExpectedResults values) {
-        // Test case 1: Delete an entity - relationship removed from an existing entity
-        assertDatabaseDoesNotContainRecord(CNS_TABLE, "relation_11");
-        assertDatabaseDoesNotContainRecord(ME_TABLE, "relation_11");
-        assertDatabaseDoesNotContainRecord(ME_TABLE, "ManagedElement_2");
-        assertDatabaseContainsValues(CNS_TABLE, values.get("entity_map_CNS_1"));
-        // Test case 2: Delete a relationship - relationship removed from both existing
-        // entities
-        assertDatabaseDoesNotContainRecord(CNS_TABLE, "relation_12");
-        assertDatabaseDoesNotContainRecord(ME_TABLE, "relation_12");
-        assertDatabaseContainsValues(CNS_TABLE, values.get("entity_map_CNS_2"));
-        assertDatabaseContainsValues(ME_TABLE, values.get("entity_map_ME_2"));
+    private void produceKafkaMessages(List<List<String>> cloudEventPathLists, List<Integer> partitions) {
+        if (cloudEventPathLists.size() != partitions.size()) {
+            throw new RuntimeException("A partition is needed for every CloudEvent list");
+        }
+        int maxLength = cloudEventPathLists.stream().mapToInt(List::size).max().orElse(0);
+        for (int i = 0; i < maxLength; i++) {
+            for (int j = 0; j < cloudEventPathLists.size(); j++) {
+                if (cloudEventPathLists.get(j).size() > i) {
+                    sendEventFromFile(cloudEventPathLists.get(j).get(i), partitions.get(j));
+                }
+            }
+        }
     }
 
-    private void assertDatabaseContainsValues(final String table, final Map<String, Object> attributes) {
-        Result<Record> results = tiesDbService.selectAllRowsFromTable("ties_data.\"" + table + "\"");
-        assertTrue(results.isNotEmpty(), String.format("Database table \"%s\" is empty, but it should not.", table));
-        assertTrue(results.stream().anyMatch(row -> attributes.keySet().stream().allMatch(attr -> Objects.equals(attributes
-                .get(attr), row.get(attr)))), String.format(
-                        "Database table \"%s\" does not contain expected data, but it should.", table));
+    private void sendEventFromFile(final String path) {
+        final int partition_0 = 0;
+        sendEventFromFile(path, partition_0);
     }
 
-    private void assertDatabaseDoesNotContainRecord(final String table, final String id) {
-        Result<Record> results = tiesDbService.selectAllRowsFromTable("ties_data.\"" + table + "\"");
-        if (results.isNotEmpty()) {
-            boolean contains = results.stream().map(row -> row.get("id")).filter(Objects::nonNull).map(Object::toString)
-                    .anyMatch(id::equals);
-            assertFalse(contains, String.format("Database table \"%s\" contains record: \"%s\", but it should not.", table,
-                    id));
-        }
-    }
+    private void sendEventFromFile(final String path, int partition) {
+        assertDoesNotThrow(() -> {
+            CloudEvent event = CloudEventTestUtil.getCloudEventFromJsonFile(path);
+            ProducerRecord<String, CloudEvent> producerRecord = new ProducerRecord<String, CloudEvent>(kafkaConfig
+                    .getTopologyIngestion().getTopicName(), partition, null, event);
+            producer.send(producerRecord);
+        });
 
-    private void sendEventFromFile(final String path) {
-        assertDoesNotThrow(() -> EndToEndTestUtil.sendEventList(List.of(CloudEventTestUtil.getCloudEventFromJsonFile(path)),
-                embeddedKafkaBroker, kafkaConfig));
     }
 
     private EndToEndExpectedResults getExpectedResults(final String path) {
         return assertDoesNotThrow(() -> new EndToEndExpectedResults(path));
     }
 
-    private void assertWithErrorMessage(Runnable assertion, String errorMessage) {
-        try {
-            assertion.run();
-        } catch (Error e) {
-            throw new AssertionError(errorMessage + ": " + e.getMessage(), e);
-        }
+    private void validateWithTimeout(int timeout, Runnable runnable) {
+        Awaitility.await().atMost(timeout, TimeUnit.SECONDS).pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
+            try {
+                runnable.run();
+            } catch (AssertionError e) {
+                throw new AssertionError("Assertion failed during validation of CloudEvent: " + e.getMessage(), e);
+            }
+        });
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/service/ModelSchemaServiceTest.java b/teiv/src/test/java/org/oran/smo/teiv/service/ModelSchemaServiceTest.java
deleted file mode 100644 (file)
index 6a57c1e..0000000
+++ /dev/null
@@ -1,206 +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 org.oran.smo.teiv.service;
-
-import org.oran.smo.teiv.api.model.OranTeivSchema;
-import org.oran.smo.teiv.api.model.OranTeivSchemaList;
-import org.oran.smo.teiv.exception.TiesException;
-import org.oran.smo.teiv.exposure.model.api.impl.ModelSchemaServiceImpl;
-import org.oran.smo.teiv.exposure.spi.DataPersistanceService;
-import org.oran.smo.teiv.exposure.spi.impl.DataPersistanceServiceImpl;
-import org.oran.smo.teiv.exposure.spi.impl.StoredSchema;
-import org.oran.smo.teiv.exposure.spi.mapper.MapperUtility;
-import org.oran.smo.teiv.exposure.spi.mapper.PageMetaData;
-import org.oran.smo.teiv.exposure.spi.mapper.PaginationMetaData;
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.springframework.mock.web.MockMultipartFile;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.oran.smo.teiv.utils.TiesConstants.IN_USAGE;
-import static org.oran.smo.teiv.utils.exposure.PaginationVerifierTestUtil.verifyResponse;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class ModelSchemaServiceTest {
-
-    private static final DataPersistanceService dataPersistanceService = mock(DataPersistanceServiceImpl.class);
-    private static final MapperUtility mapperUtility = new MapperUtility();
-    private final ModelSchemaServiceImpl service = new ModelSchemaServiceImpl(dataPersistanceService);
-
-    @BeforeAll
-    static void beforeAll() {
-        StoredSchema ranLogicalToCloud = new StoredSchema();
-        ranLogicalToCloud.setName("o-ran-smo-teiv-cloud-to-ran");
-        ranLogicalToCloud.setNamespace("urn:o-ran:smo-teiv-cloud-to-ran");
-        ranLogicalToCloud.setDomain("CLOUD_TO_RAN");
-        ranLogicalToCloud.setRevision("2023-10-24");
-        ranLogicalToCloud.setStatus(IN_USAGE);
-
-        StoredSchema ranEquipment = new StoredSchema();
-        ranEquipment.setName("o-ran-smo-teiv-equipment");
-        ranEquipment.setNamespace("urn:o-ran:smo-teiv-equipment");
-        ranEquipment.setDomain("EQUIPMENT");
-        ranEquipment.setRevision("2023-06-26");
-        ranEquipment.setStatus(IN_USAGE);
-
-        StoredSchema ranOamToCloud = new StoredSchema();
-        ranOamToCloud.setName("o-ran-smo-teiv-oam-to-cloud");
-        ranOamToCloud.setNamespace("urn:o-ran:smo-teiv-oam-to-cloud");
-        ranOamToCloud.setDomain("OAM_TO_CLOUD");
-        ranOamToCloud.setRevision("2023-10-24");
-        ranOamToCloud.setStatus(IN_USAGE);
-
-        StoredSchema ranOamToLogical = new StoredSchema();
-        ranOamToLogical.setName("o-ran-smo-teiv-oam-to-ran");
-        ranOamToLogical.setNamespace("urn:o-ran:smo-teiv-oam-to-ran");
-        ranOamToLogical.setDomain("OAM_TO_RAN");
-        ranOamToLogical.setRevision("2023-10-24");
-        ranOamToLogical.setStatus(IN_USAGE);
-
-        StoredSchema ranCloud = new StoredSchema();
-        ranCloud.setName("o-ran-smo-teiv-cloud");
-        ranCloud.setNamespace("urn:o-ran:smo-teiv-cloud");
-        ranCloud.setDomain("CLOUD");
-        ranCloud.setRevision("2023-06-26");
-        ranCloud.setStatus(IN_USAGE);
-
-        StoredSchema ranOam = new StoredSchema();
-        ranOam.setName("o-ran-smo-teiv-oam");
-        ranOam.setNamespace("urn:o-ran:smo-teiv-oam");
-        ranOam.setDomain("OAM");
-        ranOam.setRevision("2023-06-26");
-        ranOam.setContent("yang model o-ran-smo-teiv-oam {}");
-        ranOam.setStatus(IN_USAGE);
-        ranOam.setOwnerAppId("BUILT_IN_MODULE");
-
-        when(dataPersistanceService.getSchemas(PaginationDTO.builder().offset(0).limit(8).build())).thenReturn(mapperUtility
-                .wrapSchema(Arrays.asList(ranLogicalToCloud, ranEquipment, ranOamToCloud, ranOamToLogical, ranCloud,
-                        ranOam), PaginationDTO.builder().offset(0).limit(8).build()));
-        when(dataPersistanceService.getSchema("o-ran-smo-teiv-oam")).thenReturn(ranOam);
-        when(dataPersistanceService.getSchema("o-ran-smo-teiv")).thenReturn(null);
-
-        when(dataPersistanceService.getSchemas("ties_logical", PaginationDTO.builder().basePath("/schemas/ties_logical")
-                .offset(0).limit(8).build())).thenReturn(mapperUtility.wrapSchema(new ArrayList<>(), PaginationDTO.builder()
-                        .basePath("/schemas/ties_logical").offset(0).limit(8).build()));
-        when(dataPersistanceService.getSchemas("CLOUD", PaginationDTO.builder().basePath("/schemas/CLOUD").offset(0).limit(
-                8).build())).thenReturn(mapperUtility.wrapSchema(List.of(ranCloud), PaginationDTO.builder().basePath(
-                        "/schemas/CLOUD").offset(0).limit(8).build()));
-        when(dataPersistanceService.getSchemas("ran*", PaginationDTO.builder().basePath("/schemas/ran*").offset(0).limit(8)
-                .build())).thenReturn(mapperUtility.wrapSchema(Arrays.asList(ranLogicalToCloud, ranEquipment, ranOamToCloud,
-                        ranOamToLogical, ranCloud, ranOam), PaginationDTO.builder().basePath("/schemas/ran*").offset(0)
-                                .limit(8).build()));
-    }
-
-    @Test
-    void testGetSchemas() throws IOException {
-        //when
-        OranTeivSchemaList schemaItems = service.getSchemas(PaginationDTO.builder().offset(0).limit(8).build());
-        //then
-        List<OranTeivSchema> schemasMetaData = schemaItems.getItems();
-        Assertions.assertEquals(6, schemasMetaData.size());
-
-        MapperUtility mapperUtility = new MapperUtility();
-        List<Object> resultException = new ArrayList<>(schemasMetaData);
-        PaginationDTO paginationDTO = PaginationDTO.builder().basePath("/schemas").offset(100).limit(5).build();
-        paginationDTO.setTotalSize(5);
-        Assertions.assertThrows(TiesException.class, () -> mapperUtility.wrapList(resultException, paginationDTO));
-
-        Map<String, Object> fullResult = new HashMap<>();
-        fullResult.put("items", schemasMetaData);
-
-        PaginationMetaData pmd = new PaginationMetaData();
-
-        PaginationDTO paginationDTO2 = PaginationDTO.builder().basePath("/schemas").offset(0).limit(15).build();
-        paginationDTO2.setTotalSize(6);
-        fullResult.putAll(pmd.getObjectList(paginationDTO2));
-
-        verifyResponse(fullResult, mapperUtility.wrapList(resultException, PaginationDTO.builder().basePath("/schemas")
-                .offset(0).limit(15).build()));
-
-        Map<String, Object> fullResult2 = new HashMap<>();
-        fullResult2.put("items", schemasMetaData.subList(0, 5));
-
-        PageMetaData pageMetaDataSelf2 = new PageMetaData(0, PaginationDTO.builder().limit(5).basePath("/schemas").build());
-        PageMetaData pageMetaDataFirst2 = new PageMetaData(0, PaginationDTO.builder().limit(5).basePath("/schemas")
-                .build());
-        PageMetaData pageMetaDataPrev2 = new PageMetaData(0, PaginationDTO.builder().limit(5).basePath("/schemas").build());
-        PageMetaData pageMetaDataNext2 = new PageMetaData(5, PaginationDTO.builder().limit(5).basePath("/schemas").build());
-        PageMetaData pageMetaDataLast2 = new PageMetaData(5, PaginationDTO.builder().limit(5).basePath("/schemas").build());
-
-        fullResult2.put("self", pageMetaDataSelf2);
-        fullResult2.put("first", pageMetaDataFirst2);
-        fullResult2.put("prev", pageMetaDataPrev2);
-        fullResult2.put("next", pageMetaDataNext2);
-        fullResult2.put("last", pageMetaDataLast2);
-
-        verifyResponse(fullResult2, mapperUtility.wrapList(resultException, PaginationDTO.builder().basePath("/schemas")
-                .offset(0).limit(5).build()));
-    }
-
-    @Test
-    void testGetSchemasByName() {
-        //when
-        String incorrectSchemaName = "o-ran-smo-teiv";
-        String responseForCorrectSchemaName = service.getSchemaByName("o-ran-smo-teiv-oam");
-        //then
-        Assertions.assertThrowsExactly(TiesException.class, () -> service.getSchemaByName(incorrectSchemaName));
-        Assertions.assertTrue(responseForCorrectSchemaName.contains("o-ran-smo-teiv-oam"));
-    }
-
-    @Test
-    void testGetSchemasInDomain() {
-        //when
-        List<OranTeivSchema> schemasInIncorrectDomain = (List<OranTeivSchema>) service.getSchemasInDomain("ties_logical",
-                PaginationDTO.builder().basePath("/schemas/ties_logical").offset(0).limit(8).build()).getItems();
-        List<OranTeivSchema> schemasInDomainRanCloud = (List<OranTeivSchema>) service.getSchemasInDomain("CLOUD",
-                PaginationDTO.builder().basePath("/schemas/CLOUD").offset(0).limit(8).build()).getItems();
-        List<OranTeivSchema> schemasInDomainPartiallyMatchingRan = (List<OranTeivSchema>) service.getSchemasInDomain("ran*",
-                PaginationDTO.builder().basePath("/schemas/ran*").offset(0).limit(8).build()).getItems();
-        //then
-        Assertions.assertEquals(List.of(), schemasInIncorrectDomain);
-        Assertions.assertEquals(1, schemasInDomainRanCloud.size());
-        Assertions.assertEquals(6, schemasInDomainPartiallyMatchingRan.size());
-    }
-
-    @Test
-    void testCreateSchema() {
-        service.createSchema(new MockMultipartFile("yangModule.yang", "yangContent".getBytes(StandardCharsets.UTF_8)));
-    }
-
-    @Test
-    void testDeleteSchema() {
-        Assertions.assertEquals("Invalid schema name", Assertions.assertThrowsExactly(TiesException.class, () -> service
-                .deleteSchema("schemaToDelete")).getMessage());
-
-        Assertions.assertEquals("Forbidden", Assertions.assertThrowsExactly(TiesException.class, () -> service.deleteSchema(
-                "o-ran-smo-teiv-oam")).getMessage());
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/service/SchemaCleanUpServiceTest.java b/teiv/src/test/java/org/oran/smo/teiv/service/SchemaCleanUpServiceTest.java
new file mode 100644 (file)
index 0000000..4228b71
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  ============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.teiv.service;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.oran.smo.teiv.api.model.OranTeivClassifier;
+import org.oran.smo.teiv.api.model.OranTeivDecorator;
+import org.oran.smo.teiv.exposure.consumerdata.ConsumerDataOperationRegistry;
+import org.oran.smo.teiv.exposure.consumerdata.operation.ClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DecoratorsOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteClassifiersOperation;
+import org.oran.smo.teiv.exposure.consumerdata.operation.DeleteDecoratorsOperation;
+import org.oran.smo.teiv.exposure.spi.DataRepository;
+import org.oran.smo.teiv.exposure.spi.ModelRepository;
+import org.oran.smo.teiv.exposure.spi.impl.DataRepositoryImpl;
+import org.oran.smo.teiv.exposure.spi.impl.ModelRepositoryImpl;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+
+class SchemaCleanUpServiceTest {
+
+    private static final ModelRepository MODEL_REPOSITORY = mock(ModelRepositoryImpl.class);
+    private static final DataRepository DATA_REPOSITORY = mock(DataRepositoryImpl.class);
+    private static final ConsumerDataOperationRegistry consumerDataOperationRegistry = mock(
+            ConsumerDataOperationRegistry.class);
+    private static final SchemaCleanUpService schemaCleanUpService = new SchemaCleanUpService(MODEL_REPOSITORY,
+            DATA_REPOSITORY, consumerDataOperationRegistry);
+    private static final ClassifiersOperation deleteClassifiersOperation = mock(DeleteClassifiersOperation.class);
+    private static final DecoratorsOperation deleteDecoratorsOperation = mock(DeleteDecoratorsOperation.class);
+
+    @BeforeAll
+    static void setUp() throws SchemaLoaderException {
+        new MockSchemaLoader().loadSchemaRegistry();
+
+        when(DATA_REPOSITORY.getDecoratorsForSchema("gnbcucp-gnbcuup-model")).thenReturn(Collections.singleton(
+                "gnbcucp-gnbcuup-model:metadata"));
+        when(DATA_REPOSITORY.getClassifiersForSchema("gnbcucp-gnbcuup-model")).thenReturn(Collections.singleton(
+                "gnbcucp-gnbcuup-model:Weekend"));
+
+        when(DATA_REPOSITORY.getRelationshipIdsForClassifierDeletion(any(), any())).thenReturn(Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getRelationshipIdsForDecoratorDeletion(any(), any())).thenReturn(Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getEntityIdsForClassifierDeletion(any(), any())).thenReturn(Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getEntityIdsForDecoratorDeletion(any(), any())).thenReturn(Collections.EMPTY_LIST);
+
+        when(DATA_REPOSITORY.getRelationshipIdsForClassifierDeletion(SchemaRegistry.getRelationTypeByName(
+                "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"), Set.of("gnbcucp-gnbcuup-model:Weekend"))).thenReturn(
+                        Collections.singletonList(
+                                "urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="),
+                        Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getRelationshipIdsForDecoratorDeletion(SchemaRegistry.getRelationTypeByName(
+                "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"), Set.of("gnbcucp-gnbcuup-model:metadata")))
+                        .thenReturn(Collections.singletonList(
+                                "urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc="),
+                                Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getRelationshipIdsForClassifierDeletion(SchemaRegistry.getRelationTypeByName(
+                "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"), Set.of("gnbcucp-gnbcuup-model:Weekend"))).thenReturn(Collections
+                        .singletonList(
+                                "urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="),
+                        Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getRelationshipIdsForDecoratorDeletion(SchemaRegistry.getRelationTypeByName(
+                "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"), Set.of("gnbcucp-gnbcuup-model:metadata"))).thenReturn(Collections
+                        .singletonList(
+                                "urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU="),
+                        Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getEntityIdsForClassifierDeletion(SchemaRegistry.getEntityTypeByName("NRSectorCarrier"), Set
+                .of("gnbcucp-gnbcuup-model:Weekend"))).thenReturn(Collections.singletonList(
+                        "E49D942C16E0364E1E0788138916D70C"), Collections.EMPTY_LIST);
+        when(DATA_REPOSITORY.getEntityIdsForDecoratorDeletion(SchemaRegistry.getEntityTypeByName("NRSectorCarrier"), Set.of(
+                "gnbcucp-gnbcuup-model:metadata"))).thenReturn(Collections.singletonList(
+                        "E49D942C16E0364E1E0788138916D70C"), Collections.EMPTY_LIST);
+
+        when(consumerDataOperationRegistry.getClassifiersOperation(OranTeivClassifier.OperationEnum.DELETE)).thenReturn(
+                deleteClassifiersOperation);
+        when(consumerDataOperationRegistry.getDecoratorsOperation(OranTeivDecorator.OperationEnum.DELETE)).thenReturn(
+                deleteDecoratorsOperation);
+    }
+
+    @Test
+    void cleanUpModuleTest() {
+        schemaCleanUpService.cleanUpModule("gnbcucp-gnbcuup-model");
+
+        verify(MODEL_REPOSITORY).deleteModuleByName("gnbcucp-gnbcuup-model");
+    }
+}
index d44e3ab..8485db9 100644 (file)
@@ -20,8 +20,6 @@
  */
 package org.oran.smo.teiv.service;
 
-import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_A_SIDE;
-import static org.oran.smo.teiv.utils.TiesConstants.PROPERTY_B_SIDE;
 import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -39,7 +37,6 @@ import java.util.Optional;
 
 import javax.sql.DataSource;
 
-import org.oran.smo.teiv.exception.TiesException;
 import org.jooq.DSLContext;
 import org.jooq.JSONB;
 import org.jooq.Record;
@@ -49,6 +46,7 @@ import org.jooq.impl.DSL;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.oran.smo.teiv.service.models.OperationResult;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.jdbc.DataSourceBuilder;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -56,12 +54,18 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.test.context.ActiveProfiles;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.cloudevents.CloudEvent;
+
 import org.oran.smo.teiv.db.TestPostgresqlContainer;
 import org.oran.smo.teiv.exception.InvalidFieldInYangDataException;
+import org.oran.smo.teiv.exception.TiesException;
 import org.oran.smo.teiv.ingestion.DeadlockRetryPolicy;
 import org.oran.smo.teiv.ingestion.validation.IngestionOperationValidatorFactory;
 import org.oran.smo.teiv.ingestion.validation.MaximumCardinalityViolationException;
-import org.oran.smo.teiv.service.models.OperationResult;
+import org.oran.smo.teiv.schema.EntityType;
+import org.oran.smo.teiv.schema.BidiDbNameMapper;
+
 import org.oran.smo.teiv.schema.PostgresSchemaLoader;
 import org.oran.smo.teiv.schema.RelationType;
 import org.oran.smo.teiv.schema.SchemaLoaderException;
@@ -71,14 +75,12 @@ import org.oran.smo.teiv.service.cloudevent.data.ParsedCloudEventData;
 import org.oran.smo.teiv.service.cloudevent.data.Relationship;
 import org.oran.smo.teiv.startup.SchemaHandler;
 import org.oran.smo.teiv.utils.CloudEventTestUtil;
-import org.oran.smo.teiv.utils.ConvertToJooqTypeUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.cloudevents.CloudEvent;
+import org.oran.smo.teiv.utils.JooqTypeConverter;
 
 @Configuration
 @SpringBootTest
 @ActiveProfiles({ "test", "ingestion" })
-public class TiesDbOperationResultsTest {
+class TiesDbOperationResultsTest {
     public static TestPostgresqlContainer postgresqlContainer = TestPostgresqlContainer.getInstance();
     private static TiesDbService tiesDbService;
     private static TiesDbOperations tiesDbOperations;
@@ -122,16 +124,18 @@ public class TiesDbOperationResultsTest {
 
         assertEquals(3, mergeResult.size());
         assertEquals("ManagedElement_1", mergeResult.get(0).getId());
-        assertEquals("ManagedElement", mergeResult.get(0).getEntryType());
-        assertEquals(Map.of(), mergeResult.get(0).getContent());
+        assertEquals("ManagedElement", mergeResult.get(0).getType());
+        assertEquals(Map.of(), mergeResult.get(0).getAttributes());
 
         assertEquals("ENodeBFunction_1", mergeResult.get(1).getId());
-        assertEquals("ENodeBFunction", mergeResult.get(1).getEntryType());
-        assertEquals(Map.of(), mergeResult.get(1).getContent());
+        assertEquals("ENodeBFunction", mergeResult.get(1).getType());
+        assertEquals(Map.of(), mergeResult.get(1).getAttributes());
 
         assertEquals("relation_1", mergeResult.get(2).getId());
-        assertEquals("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", mergeResult.get(2).getEntryType());
-        assertEquals(Map.of("aSide", "ManagedElement_1", "bSide", "ENodeBFunction_1"), mergeResult.get(2).getContent());
+        assertEquals("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", mergeResult.get(2).getType());
+        assertEquals("ManagedElement_1", mergeResult.get(2).getASide());
+        assertEquals("ENodeBFunction_1", mergeResult.get(2).getBSide());
+
     }
 
     @Test
@@ -140,14 +144,15 @@ public class TiesDbOperationResultsTest {
         managedElementEntity.put("id", "managed_element_entity_id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity);
 
         // Delete operation - expected to succeed
         List<OperationResult> deleteResultMatch = tiesDbOperations.deleteEntity(dslContext, SchemaRegistry
                 .getEntityTypeByName("ManagedElement"), "managed_element_entity_id1");
 
         assertFalse(deleteResultMatch.isEmpty(), "Delete operation should return a non-empty list");
-        assertTrue(deleteResultMatch.contains(new OperationResult("managed_element_entity_id1", "ManagedElement", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createEntityOperationResult("managed_element_entity_id1",
+                "ManagedElement")),
                 "The list should contain the delete operation result with id: 'managed_element_entity_id1'");
 
         // Delete operation with the same EIID - expected to fail
@@ -169,11 +174,13 @@ public class TiesDbOperationResultsTest {
         Map<String, Object> cloudNativeSystemEntity = new HashMap<>();
         cloudNativeSystemEntity.put("id", "cloud_native_system_entity_id1");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                cloudNativeSystemEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity);
 
         cloudNativeSystemEntity.put("name", "CloudNativeSystem");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                cloudNativeSystemEntity);
 
         // Delete operation for aSide - expected to succeed
         Optional<OperationResult> deleteASideResultMatch = tiesDbOperations.deleteRelationFromEntityTableByRelationId(
@@ -181,8 +188,9 @@ public class TiesDbOperationResultsTest {
                         "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
 
         assertTrue(deleteASideResultMatch.isPresent(), "Delete operation should return a present Optional");
-        assertEquals(new OperationResult("relation_eiid1", "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", null),
-                deleteASideResultMatch.get(), "The delete operation result should be present for: 'relation_eiid1'");
+        assertEquals(OperationResult.createRelationshipOperationResult("relation_eiid1",
+                "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"), deleteASideResultMatch.get(),
+                "The delete operation result should be present for: 'relation_eiid1'");
 
         // Delete operation with the same EIID - expected to fail
         Optional<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteRelationFromEntityTableByRelationId(
@@ -191,8 +199,10 @@ public class TiesDbOperationResultsTest {
         assertTrue(deleteResultNoMatch.isEmpty(),
                 "Delete operation should return an empty list for already deleted/non existing ID");
 
-        Result<Record> rows = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
-        Result<Record> rowsOnBSide = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rows = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
+        Result<Record> rowsOnBSide = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals("managed_element_entity_id1", rows.get(0).get("id"));
         assertEquals("fdn1", rows.get(0).get("fdn"));
         assertEquals("cloud_native_system_entity_id1", rowsOnBSide.get(0).get("id"));
@@ -200,7 +210,7 @@ public class TiesDbOperationResultsTest {
         assertNull(rows.get(0).get("REL_FK_deployed-as-cloudNativeSystem"));
         assertNull(rows.get(0).get("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
         assertNull(rowsOnBSide.get(0).get("REL_FK_deployed-managedElement"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of()), rows.get(0).get(
+        assertEquals(JooqTypeConverter.toJsonb(List.of()), rows.get(0).get(
                 "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
     }
 
@@ -217,8 +227,8 @@ public class TiesDbOperationResultsTest {
         cna1.put("REL_FK_realised-managedElement", "managed_element_entity_id1");
         cna1.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_eiid1");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElement1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElement1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna1);
 
         // Delete operation with existing relationship
         List<OperationResult> deleteResultMatch = tiesDbOperations.deleteRelationshipByManySideEntityId(dslContext,
@@ -226,8 +236,8 @@ public class TiesDbOperationResultsTest {
                         "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION"));
 
         assertFalse(deleteResultMatch.isEmpty(), "Delete operation should return a non-empty list");
-        assertTrue(deleteResultMatch.contains(new OperationResult("relation_eiid1",
-                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("relation_eiid1",
+                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'relation_eiid1'");
 
         // Delete operation with the same entity ID - expected to return an empty list
@@ -264,10 +274,10 @@ public class TiesDbOperationResultsTest {
         cna3.put("REL_FK_realised-managedElement", "managed_element_entity_id1");
         cna3.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_eiid3");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElement1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna2);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna3);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElement1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna3);
 
         // Delete operation for managed_element_entity_id1
         List<OperationResult> deleteResultMatch = tiesDbOperations.deleteEntity(dslContext, SchemaRegistry
@@ -276,21 +286,23 @@ public class TiesDbOperationResultsTest {
 
         // Check if all expected IDs are present in the deletion result
         assertEquals(4, deleteResultMatch.size(), "Delete operation should match expected size");
-        assertTrue(deleteResultMatch.contains(new OperationResult("managed_element_entity_id1", "ManagedElement", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createEntityOperationResult("managed_element_entity_id1",
+                "ManagedElement")),
                 "The list should contain the delete operation result with id: 'managed_element_entity_id1'");
 
-        assertTrue(deleteResultMatch.contains(new OperationResult("relation_eiid1",
-                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("relation_eiid1",
+                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'relation_eiid1'");
-        assertTrue(deleteResultMatch.contains(new OperationResult("relation_eiid2",
-                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("relation_eiid2",
+                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'relation_eiid2'");
-        assertTrue(deleteResultMatch.contains(new OperationResult("relation_eiid3",
-                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("relation_eiid3",
+                "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'relation_eiid3'");
 
         // Verify all related entities have their relationships deleted
-        Result<Record> rows = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeApplication\"");
+        Result<Record> rows = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"");
         assertEquals(3, rows.size());
         for (Record row : rows) {
             assertNull(row.get("REL_FK_realised-managedElement"),
@@ -329,30 +341,35 @@ public class TiesDbOperationResultsTest {
         rel2.put("aSide_GNBCUCPFunction", "gnbcucp_id1");
         rel2.put("bSide_CloudNativeApplication", "cloud_native_id2");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFunction\"", gnbcucp1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna2);
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", rel1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", rel2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"", gnbcucp1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"", rel1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"", rel2);
 
-        Result<Record> row1 = tiesDbService.selectAllRowsFromTable("ties_data.\"GNBCUCPFunction\"");
+        Result<Record> row1 = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"");
         assertEquals(1, row1.size());
-        Result<Record> row2 = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeApplication\"");
+        Result<Record> row2 = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"");
         assertEquals(2, row2.size());
-        Result<Record> row3 = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"");
+        Result<Record> row3 = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"");
         assertEquals(2, row3.size());
 
+        RelationType relType = SchemaRegistry.getRelationTypeByName("GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
+
         // Test deletion of a relationship by ID (expected success)
         Optional<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByRelationId(dslContext,
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", "rel_id1");
+                relType, "rel_id1");
         assertTrue(deleteResultMatch.isPresent(), "Delete operation should return a present Optional");
-        assertEquals(new OperationResult("rel_id1", "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", null),
-                deleteResultMatch.get(), "Deleted relationship ID should match 'rel_id1'");
+        assertEquals(OperationResult.createRelationshipOperationResult("rel_id1",
+                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"), deleteResultMatch.get(),
+                "Deleted relationship ID should match 'rel_id1'");
 
         // Test deletion of the same relationship ID again (expected failure)
         Optional<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByRelationId(dslContext,
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", "rel_id1");
+                relType, "rel_id1");
         assertTrue(deleteResultNoMatch.isEmpty(), "Delete operation should not return a present Optional");
     }
 
@@ -385,38 +402,40 @@ public class TiesDbOperationResultsTest {
         rel2.put("aSide_GNBCUCPFunction", "gnbcucp_id1");
         rel2.put("bSide_CloudNativeApplication", "cloud_native_id2");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFunction\"", gnbcucp1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna2);
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", rel1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", rel2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"", gnbcucp1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cna2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"", rel1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"", rel2);
 
-        assertEquals(1, tiesDbService.selectAllRowsFromTable("ties_data.\"GNBCUCPFunction\"").size(),
-                "Expected one GNBCUCPFunction record");
-        assertEquals(2, tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeApplication\"").size(),
+        assertEquals(1, TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"").size(), "Expected one GNBCUCPFunction record");
+        assertEquals(2, TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"").size(),
                 "Expected two CloudNativeApplication records");
-        assertEquals(2, tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"").size(),
+        assertEquals(2, TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"").size(),
                 "Expected two GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION relations");
 
+        RelationType relType = SchemaRegistry.getRelationTypeByName("GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION");
+
         // Test deletion of relations by entity ID (expected to delete two relations)
-        List<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext,
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", "gnbcucp_id1", "aSide_GNBCUCPFunction",
-                "bSide_CloudNativeApplication");
+        List<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext, relType,
+                "gnbcucp_id1", "aSide_GNBCUCPFunction", "bSide_CloudNativeApplication");
+
         assertEquals(2, deleteResultMatch.size(), "Expected two relations to be deleted");
-        assertTrue(deleteResultMatch.contains(new OperationResult("rel_id1",
-                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("rel_id1",
+                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'rel_id1'");
 
-        assertTrue(deleteResultMatch.contains(new OperationResult("rel_id2",
-                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", null)),
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("rel_id2",
+                "GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION")),
                 "The list should contain the delete operation result with id: 'rel_id2'");
 
         // Test deletion of relations by the same entity ID again (expected to find no
         // relations to delete)
-        List<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext,
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", "gnbcucp_id1", "aSide_GNBCUCPFunction",
-                "bSide_CloudNativeApplication");
+        List<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext, relType,
+                "gnbcucp_id1", "aSide_GNBCUCPFunction", "bSide_CloudNativeApplication");
         assertTrue(deleteResultNoMatch.isEmpty(),
                 "Delete operation should return an empty list for already deleted/non existing ID");
     }
@@ -455,26 +474,32 @@ public class TiesDbOperationResultsTest {
         rel2.put("bSide_AntennaModule", "module_id2");
         rel2.put("aSide_AntennaModule", "module_id1");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"AntennaModule\"", antennaModule1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"AntennaModule\"", antennaModule2);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", rel1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", rel2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"", rel1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"", rel2);
 
-        Result<Record> row1 = tiesDbService.selectAllRowsFromTable("ties_data.\"AntennaModule\"");
+        Result<Record> row1 = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"");
         assertEquals(2, row1.size());
-        Result<Record> row2 = tiesDbService.selectAllRowsFromTable("ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"");
+        Result<Record> row2 = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"");
         assertEquals(2, row2.size());
 
+        RelationType antennaRelType1 = SchemaRegistry.getRelationTypeByName("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
+
         // Test deletion of a relationship by ID (expected success)
         Optional<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByRelationId(dslContext,
-                "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", "rel_id1");
+                antennaRelType1, "rel_id1");
+
         assertTrue(deleteResultMatch.isPresent(), "Delete operation should return a present Optional");
-        assertEquals(new OperationResult("rel_id1", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE", null), deleteResultMatch
-                .get(), "Deleted relationship ID should match 'rel_id1'");
+        assertEquals(OperationResult.createRelationshipOperationResult("rel_id1",
+                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE"), deleteResultMatch.get(),
+                "Deleted relationship ID should match 'rel_id1'");
 
         // Test deletion of the same relationship ID again (expected failure)
         Optional<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByRelationId(dslContext,
-                "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", "rel_id1");
+                antennaRelType1, "rel_id1");
         assertTrue(deleteResultNoMatch.isEmpty(), "Delete operation should not return a present Optional");
 
     }
@@ -513,32 +538,35 @@ public class TiesDbOperationResultsTest {
         rel2.put("bSide_AntennaModule", "module_id2");
         rel2.put("aSide_AntennaModule", "module_id1");
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"AntennaModule\"", antennaModule1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"AntennaModule\"", antennaModule2);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", rel1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", rel2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"", rel1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"", rel2);
+
+        assertEquals(2, TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"").size(), "Expected two AntennaModule records");
+        assertEquals(2, TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext,
+                "ties_data.\"5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6\"").size(),
+                "Expected two ANTENNAMODULE_REALISED_BY_ANTENNAMODULE relations");
 
-        assertEquals(2, tiesDbService.selectAllRowsFromTable("ties_data.\"AntennaModule\"").size(),
-                "Expected two AntennaModule records");
-        assertEquals(2, tiesDbService.selectAllRowsFromTable("ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"")
-                .size(), "Expected two ANTENNAMODULE_REALISED_BY_ANTENNAMODULE relations");
+        RelationType relType = SchemaRegistry.getRelationTypeByName("ANTENNAMODULE_REALISED_BY_ANTENNAMODULE");
 
         // Test deletion of relations by entity ID (expected to delete two relations)
-        List<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext,
-                "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", "module_id1", "aSide_AntennaModule",
-                "bSide_AntennaModule");
+        List<OperationResult> deleteResultMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext, relType,
+                "module_id1", "aSide_AntennaModule", "bSide_AntennaModule");
         assertEquals(2, deleteResultMatch.size(), "Expected two relations to be deleted");
-        assertTrue(deleteResultMatch.contains(new OperationResult("rel_id1", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE",
-                null)), "The list should contain the delete operation result with id: 'rel_id1'");
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("rel_id1",
+                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE")),
+                "The list should contain the delete operation result with id: 'rel_id1'");
 
-        assertTrue(deleteResultMatch.contains(new OperationResult("rel_id2", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE",
-                null)), "The list should contain the delete operation result with id: 'rel_id2'");
+        assertTrue(deleteResultMatch.contains(OperationResult.createRelationshipOperationResult("rel_id2",
+                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE")),
+                "The list should contain the delete operation result with id: 'rel_id2'");
 
         // Test deletion of relations by the same entity ID again (expected to find no
         // relations to delete)
-        List<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext,
-                "ties_data.\"ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\"", "module_id1", "aSide_AntennaModule",
-                "bSide_AntennaModule");
+        List<OperationResult> deleteResultNoMatch = tiesDbOperations.deleteManyToManyRelationByEntityId(dslContext, relType,
+                "module_id1", "aSide_AntennaModule", "bSide_AntennaModule");
         assertTrue(deleteResultNoMatch.isEmpty(),
                 "Delete operation should return an empty list for already deleted/non existing ID");
 
@@ -669,8 +697,8 @@ public class TiesDbOperationResultsTest {
                 parsedCloudEventData);
         assertEquals(40, mergeResult.size());
 
-        //One_To_One Relationship
-        Relationship oneToOneRelationship = new Relationship("o-ran-smo-teiv-oam-to-cloud",
+        // One_To_One Relationship
+        Relationship oneToOneRelationship = new Relationship("o-ran-smo-teiv-ran-oam-to-cloud",
                 "MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM",
                 "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_relation_3", "ManagedElement_3", "CloudNativeSystem_3", List
                         .of());
@@ -679,8 +707,8 @@ public class TiesDbOperationResultsTest {
                 .deleteRelationFromEntityTableByRelationId(dslContext, oneToOneRelationship.getId(), oneToOneRelationType);
         assertTrue(deleteOneToOneRelationshipResult.isPresent(), "Delete operation should return a present Optional");
 
-        //One_To_Many Relationship
-        Relationship oneToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        // One_To_Many Relationship
+        Relationship oneToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU",
                 "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_2", "GNBDUFunction_1", "NRCellDU_2", List.of());
         RelationType oneToManyRelationType = SchemaRegistry.getRelationTypeByName(oneToManyRelationship.getType());
@@ -689,8 +717,8 @@ public class TiesDbOperationResultsTest {
                         oneToManyRelationType);
         assertTrue(deleteOneToManyRelationshipResult.isPresent(), "Delete operation should return a present Optional");
 
-        //Many_To_One Relationship
-        Relationship manyToOneRelationship = new Relationship("o-ran-smo-teiv-cloud",
+        // Many_To_One Relationship
+        Relationship manyToOneRelationship = new Relationship("o-ran-smo-teiv-ran-cloud",
                 "CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE",
                 "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE_relation_3", "CloudNativeApplication_3", "Namespace_3", List
                         .of());
@@ -700,37 +728,36 @@ public class TiesDbOperationResultsTest {
                         manyToOneRelationType);
         assertTrue(deleteManyToOneRelationshipResult.isPresent(), "Delete operation should return a present Optional");
 
-        //Many_To_Many Relationship
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-cloud-to-ran",
+        // Many_To_Many Relationship
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical-to-cloud",
                 "GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN",
                 "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_1", "GNBDUFunction_1",
                 "CloudNativeApplication_1", List.of());
         RelationType manyToManyRelationType = SchemaRegistry.getRelationTypeByName(manyToManyRelationship.getType());
         Optional<OperationResult> deleteManyToManyRelationshipResult = tiesDbOperations
-                .deleteManyToManyRelationByRelationId(dslContext, manyToManyRelationType.getTableName(),
-                        manyToManyRelationship.getId());
+                .deleteManyToManyRelationByRelationId(dslContext, manyToManyRelationType, manyToManyRelationship.getId());
         assertTrue(deleteManyToManyRelationshipResult.isPresent(), "Delete operation should return a present Optional");
 
-        //One_To_One Relationship ConnectingSameEntity
-        Relationship connectingSameEntityOneToOneRelationship = new Relationship("o-ran-smo-teiv-equipment",
+        // One_To_One Relationship ConnectingSameEntity
+        Relationship connectingSameEntityOneToOneRelationship = new Relationship("o-ran-smo-teiv-ran-equipment",
                 "ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE",
                 "ANTENNAMODULE_DEPLOYED_ON_ANTENNAMODULE_relation_1", "AntennaModule_5", "AntennaModule_6", List.of());
         RelationType connectingSameEntityType = SchemaRegistry.getRelationTypeByName(
                 connectingSameEntityOneToOneRelationship.getType());
         Optional<OperationResult> deleteConnectingSameEntityOneToOneRelationshipResult = tiesDbOperations
-                .deleteManyToManyRelationByRelationId(dslContext, connectingSameEntityType.getTableName(),
+                .deleteManyToManyRelationByRelationId(dslContext, connectingSameEntityType,
                         connectingSameEntityOneToOneRelationship.getId());
         assertTrue(deleteConnectingSameEntityOneToOneRelationshipResult.isPresent(),
                 "Delete operation should return a present Optional");
 
-        //One_To_Many Relationship ConnectingSameEntity
-        Relationship connectingSameEntityOneToManyRelationship = new Relationship("o-ran-smo-teiv-equipment",
+        // One_To_Many Relationship ConnectingSameEntity
+        Relationship connectingSameEntityOneToManyRelationship = new Relationship("o-ran-smo-teiv-ran-equipment",
                 "ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE",
                 "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_relation_1", "AntennaModule_1", "AntennaModule_2", List.of());
         connectingSameEntityType = SchemaRegistry.getRelationTypeByName(connectingSameEntityOneToManyRelationship
                 .getType());
         Optional<OperationResult> deleteConnectingSameEntityOneToManyRelationshipResult = tiesDbOperations
-                .deleteManyToManyRelationByRelationId(dslContext, connectingSameEntityType.getTableName(),
+                .deleteManyToManyRelationByRelationId(dslContext, connectingSameEntityType,
                         connectingSameEntityOneToManyRelationship.getId());
         assertTrue(deleteConnectingSameEntityOneToManyRelationshipResult.isPresent(),
                 "Delete operation should return a present Optional");
@@ -738,24 +765,22 @@ public class TiesDbOperationResultsTest {
 
     @Test
     void testSelectByCmHandleFormSourceIds() {
-        Map<String, Object> cna1 = new HashMap<>();
-        cna1.put("id", "cloud_native_id1");
-        cna1.put("name", "CloudNativeApplication");
-        cna1.put("CD_sourceIds", JSONB.jsonb(
-                "[\"urn:3gpp:dn:/fdn\"," + "\"urn:cmHandle:/395221E080CCF0FD1924103B15873814\"]"));
+        Map<String, Object> antennaModule1 = new HashMap<>();
+        antennaModule1.put("id", "module_id1");
+        antennaModule1.put("CD_sourceIds", JSONB.jsonb(
+                "[\"urn:3gpp:dn:fdn\"," + "\"urn:cmHandle:395221E080CCF0FD1924103B15873814\"]"));
 
-        Map<String, Object> cna2 = new HashMap<>();
-        cna2.put("id", "cloud_native_id2");
-        cna2.put("name", "CloudNativeApplication");
-        cna2.put("CD_sourceIds", JSONB.jsonb(
-                "[\"urn:3gpp:dn:/fdn\"," + "\"urn:cmHandle:/395221E080CCF0FD1924103B15873815\"]"));
+        Map<String, Object> antennaModule2 = new HashMap<>();
+        antennaModule2.put("id", "module_id2");
+        antennaModule2.put("CD_sourceIds", JSONB.jsonb(
+                "[\"urn:3gpp:dn:fdn\"," + "\"urn:cmHandle:395221E080CCF0FD1924103B15873815\"]"));
 
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna1);
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cna2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", antennaModule2);
 
         List<String> ids = tiesDbOperations.selectByCmHandleFormSourceIds(dslContext,
-                "ties_data.\"CloudNativeApplication\"", "395221E080CCF0FD1924103B15873814");
-        assertEquals(List.of("cloud_native_id1"), ids);
+                "ties_data.\"f8caf5ebe876c3001d67efe06e4d83abf0babe31\"", "395221E080CCF0FD1924103B15873814");
+        assertEquals(List.of("module_id1"), ids);
     }
 
     @Test
@@ -767,7 +792,7 @@ public class TiesDbOperationResultsTest {
                 parsedCloudEventData);
         assertEquals(12, mergeResult.size());
 
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_2", "GNBCUUP_1", "CloudNativeApplication_3",
                 new ArrayList<>());
         final ParsedCloudEventData finalParsedCloudEventData = new ParsedCloudEventData(new ArrayList<>(), List.of(
@@ -785,7 +810,7 @@ public class TiesDbOperationResultsTest {
                 parsedCloudEventData);
         assertEquals(12, mergeResult.size());
 
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_2", "GNBCUUP_1", "CloudNativeApplication_2",
                 new ArrayList<>());
         final ParsedCloudEventData finalParsedCloudEventData = new ParsedCloudEventData(new ArrayList<>(), List.of(
@@ -805,7 +830,7 @@ public class TiesDbOperationResultsTest {
                 parsedCloudEventData);
         assertEquals(12, mergeResult.size());
 
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_4", "GNBCUUP_3", "CloudNativeApplication_4",
                 new ArrayList<>());
         parsedCloudEventData = new ParsedCloudEventData(new ArrayList<>(), List.of(manyToManyRelationship));
@@ -823,13 +848,14 @@ public class TiesDbOperationResultsTest {
                 parsedCloudEventData);
         assertEquals(12, mergeResult.size());
 
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_4", "GNBCUUP_1", "CloudNativeApplication_4",
                 new ArrayList<>());
         parsedCloudEventData = new ParsedCloudEventData(new ArrayList<>(), List.of(manyToManyRelationship));
         List<OperationResult> result = tiesDbOperations.executeEntityAndRelationshipMergeOperations(parsedCloudEventData);
 
         assertEquals(2, result.size());
+
     }
 
     @Test // Both endpoints exist, and a new relationship ID is received.
@@ -867,9 +893,12 @@ public class TiesDbOperationResultsTest {
         oneToManyResult = mergeSingleTestEvent(VALIDATE_ONE_TO_MANY_DIR + "ce-create-one-to-many.json");
         oneToOneResult = mergeSingleTestEvent(VALIDATE_ONE_TO_ONE_DIR + "ce-create-one-to-one.json");
 
-        assertEquals(3, manyToOneResult.size());
-        assertEquals(3, oneToManyResult.size());
-        assertEquals(3, oneToOneResult.size());
+        // If an entity already exists with the given id and there's no attribute to
+        // merge in the json, then the entity is not updated.
+        // If it's not updated, then it shouldn't be in the OperationResult list
+        assertEquals(2, manyToOneResult.size());
+        assertEquals(1, oneToManyResult.size());
+        assertEquals(1, oneToOneResult.size());
 
         assertDbContainsOperationResults(manyToOneResult);
         assertDbContainsOperationResults(oneToManyResult);
@@ -1029,25 +1058,23 @@ public class TiesDbOperationResultsTest {
                 VALIDATE_ONE_TO_ONE_DIR + "ce-create-one-to-one8.json"));
     }
 
-    @Test
-    void testOperationResultFromRelationship() {
-        Relationship relationship = new Relationship("o-ran-smo-teiv-equipment", "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE",
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_relation_1", "AntennaModule_1", "AntennaModule_2", List.of());
+    @Test // Missing "many" side endpoint with an existing relationship ID.
+    void testMergeWithMissingManySideAndExistingRelationshipIdInCaseOfGeoLocation()
+            throws MaximumCardinalityViolationException, InvalidFieldInYangDataException {
+        List<OperationResult> manyToOneResult = mergeSingleTestEvent(
+                VALIDATE_MANY_TO_ONE_DIR + "ce-create-many-to-one-geolocation.json");
 
-        Map<String, Object> relationshipSides = new HashMap<>();
-        relationshipSides.put("aSide", relationship.getASide());
-        relationshipSides.put("bSide", relationship.getBSide());
+        assertEquals(3, manyToOneResult.size());
+        assertDbContainsOperationResults(manyToOneResult);
 
-        OperationResult result = OperationResult.createFromRelationship(relationship);
-        assertEquals(result.getId(), relationship.getId());
-        assertEquals(result.getEntryType(), relationship.getType());
-        assertEquals(result.getContent(), relationshipSides);
+        assertThrows(MaximumCardinalityViolationException.class, () -> mergeSingleTestEvent(
+                VALIDATE_MANY_TO_ONE_DIR + "ce-create-many-to-one-geolocation2.json"));
     }
 
     @Test
     void testRelationRelatedMethodsWhenRelationshipIsStoredInSeparateTable() {
 
-        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran",
+        Relationship manyToManyRelationship = new Relationship("o-ran-smo-teiv-ran-logical",
                 "GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION", "relation_4", "GNBCUUP_1", "CloudNativeApplication_4",
                 new ArrayList<>());
 
@@ -1066,15 +1093,15 @@ public class TiesDbOperationResultsTest {
     @Test
     void testRelationRelatedMethodsWhenRelationshipIsStoredOnBSide() {
 
-        Relationship relationship = new Relationship("o-ran-smo-teiv-ran", "GNBDUFUNCTION_PROVIDES_NRCELLDU", "relation_2",
-                "GNBDUFunction_1", "NRCellDU_5", new ArrayList<>());
+        Relationship relationship = new Relationship("o-ran-smo-teiv-ran-logical", "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                "relation_2", "GNBDUFunction_1", "NRCellDU_5", new ArrayList<>());
 
         assertEquals("NRCellDU_5", relationship.getStoringSideEntityId());
         assertEquals("GNBDUFunction_1", relationship.getNotStoringSideEntityId());
 
         RelationType relationType = SchemaRegistry.getRelationTypeByName(relationship.getType());
 
-        assertEquals("ties_data.\"GNBDUFunction\"", relationType.getNotStoringSideTableName());
+        assertEquals("ties_data.\"o-ran-smo-teiv-ran-logical_GNBDUFunction\"", relationType.getNotStoringSideTableName());
         assertEquals("REL_FK_provided-by-gnbduFunction", relationType
                 .getNotStoringSideEntityIdColumnNameInStoringSideTable());
         assertEquals("NRCellDU", relationType.getStoringSideEntityType());
@@ -1091,19 +1118,19 @@ public class TiesDbOperationResultsTest {
 
     private void assertDbContainsOperationResults(List<OperationResult> results) {
         for (OperationResult result : results) {
-            boolean isRelation = result.getContent().containsKey(PROPERTY_A_SIDE) && result.getContent().containsKey(
-                    PROPERTY_B_SIDE);
-            if (isRelation) {
-                RelationType relationType = SchemaRegistry.getRelationTypeByName(result.getEntryType());
-                tableContainsId(relationType.getTableName(), relationType.getIdColumnName(), result);
+            if (result.isRelationship()) {
+                RelationType relationType = SchemaRegistry.getRelationTypeByName(result.getType());
+                tableContainsId(BidiDbNameMapper.getDbName(relationType.getTableName()), relationType.getIdColumnName(),
+                        result);
             } else {
-                tableContainsId("ties_data.\"" + result.getEntryType() + "\"", "id", result);
+                final EntityType entityType = SchemaRegistry.getEntityTypeByName(result.getType());
+                tableContainsId(BidiDbNameMapper.getDbName(entityType.getTableName()), "id", result);
             }
         }
     }
 
     private void tableContainsId(String tableName, String idColumn, OperationResult result) {
-        Result<Record> dbResults = tiesDbService.selectAllRowsFromTable(tableName);
+        Result<Record> dbResults = TiesDbServiceContainerizedTest.selectAllRowsFromTable(dslContext, tableName);
         final boolean contains = dbResults.stream().map(row -> row.get(idColumn)).filter(Objects::nonNull).map(
                 Object::toString).anyMatch(result.getId()::equals);
         assertTrue(contains);
index 9431880..a1866b9 100644 (file)
 package org.oran.smo.teiv.service;
 
 import static org.oran.smo.teiv.ingestion.DeadlockRetryPolicy.POSTGRES_DEADLOCK_ERROR_CODE;
+import static org.oran.smo.teiv.utils.TiesConstants.QUOTED_STRING;
 import static org.oran.smo.teiv.utils.TiesConstants.TIES_DATA_SCHEMA;
 import static org.jooq.impl.DSL.field;
+import static org.jooq.impl.DSL.name;
 import static org.jooq.impl.DSL.table;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -41,12 +43,14 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
-import org.oran.smo.teiv.utils.ConvertToJooqTypeUtil;
 import org.jooq.DSLContext;
+import org.jooq.Field;
 import org.jooq.JSONB;
 import org.jooq.Record;
 import org.jooq.Result;
+import org.jooq.Table;
 import org.jooq.exception.DataAccessException;
+import org.jooq.util.xml.jaxb.Column;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -60,11 +64,13 @@ import org.springframework.test.context.DynamicPropertySource;
 import org.oran.smo.teiv.db.TestPostgresqlContainer;
 import org.oran.smo.teiv.exception.TiesException;
 import org.oran.smo.teiv.schema.SchemaRegistry;
+import org.oran.smo.teiv.utils.JooqTypeConverter;
+import org.oran.smo.teiv.utils.TiesConstants;
 import org.oran.smo.teiv.utils.schema.Geography;
 
 @Configuration
 @SpringBootTest
-public class TiesDbServiceContainerizedTest {
+class TiesDbServiceContainerizedTest {
     public static TestPostgresqlContainer postgreSQLContainer = TestPostgresqlContainer.getInstance();
 
     @Autowired
@@ -103,9 +109,9 @@ public class TiesDbServiceContainerizedTest {
         map1.put("id", "id1");
         map1.put("fdn", "fdn1");
         map1.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map1);
 
-        Result<Record> rows = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rows = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         for (Entry<String, Object> e : map1.entrySet()) {
             assertEquals(e.getValue(), rows.get(0).get(e.getKey()));
         }
@@ -114,9 +120,9 @@ public class TiesDbServiceContainerizedTest {
         map2.put("id", "id1");
         map2.put("fdn", "fdn2");
         map2.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann2\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map2);
 
-        Result<Record> rows2 = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rows2 = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         for (Entry<String, Object> e : map2.entrySet()) {
             assertEquals(e.getValue(), rows2.get(0).get(e.getKey()));
         }
@@ -129,10 +135,11 @@ public class TiesDbServiceContainerizedTest {
         map.put("sectorId", 7);
         map.put("geo-location", new Geography("{\"latitude\": 47.497913,\"longitude\": 19.040236}"));
         map.put("azimuth", 7.3);
-        tiesDbOperations.merge(dslContext, "ties_data.\"Sector\"", map);
+        tiesDbOperations.merge(dslContext, "ties_data.\"22174a23af5d5a96143c83ddfa78654df0acb697\"", map);
 
         Result<?> rows = dslContext.select(field("id"), field("\"sectorId\"").as("sectorId"), field(
-                "ST_AsText(\"geo-location\")"), field("azimuth")).from(table("ties_data.\"Sector\"")).fetch();
+                "ST_AsText(\"geo-location\")"), field("azimuth")).from(table(
+                        "ties_data.\"22174a23af5d5a96143c83ddfa78654df0acb697\"")).fetch();
 
         assertEquals("id1", rows.get(0).get("id"));
         assertEquals(7L, rows.get(0).get("sectorId"));
@@ -147,20 +154,20 @@ public class TiesDbServiceContainerizedTest {
         map1.put("id", "id1");
         map1.put("fdn", "fdn1");
         map1.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map1);
 
         Map<String, Object> map2 = new HashMap<>();
         map2.put("id", "id2");
         map2.put("fdn", "fdn2");
         map2.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann2\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map2);
 
-        Result<Record> row1 = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> row1 = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(2, row1.size());
 
         tiesDbOperations.deleteEntity(dslContext, SchemaRegistry.getEntityTypeByName("ManagedElement"), "id1");
 
-        Result<Record> row2 = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> row2 = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, row2.size());
     }
 
@@ -175,25 +182,24 @@ public class TiesDbServiceContainerizedTest {
         map1.put("gNBIdLength", 1);
         map1.put("pLMNId", JSONB.jsonb("{\"name\":\"pLMNId1\"}"));
         map1.put("cmId", JSONB.jsonb("{\"name\":\"cmId1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFunction\"", map1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"", map1);
 
         Map<String, Object> map2 = new HashMap<>();
         map2.put("id", "id1");
         map2.put("name", "CloudNativeApplication");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", map2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", map2);
 
         Map<String, Object> map3 = new HashMap<>();
         map3.put("id", "id1");
         map3.put("aSide_GNBCUCPFunction", "id1");
         map3.put("bSide_CloudNativeApplication", "id1");
-        tiesDbOperations.merge(dslContext, "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"", map3);
+        tiesDbOperations.merge(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"", map3);
 
-        Result<Record> row1 = tiesDbService.selectAllRowsFromTable("ties_data.\"GNBCUCPFunction\"");
+        Result<Record> row1 = selectAllRowsFromTable(dslContext, "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"");
         assertEquals(1, row1.size());
-        Result<Record> row2 = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeApplication\"");
+        Result<Record> row2 = selectAllRowsFromTable(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"");
         assertEquals(1, row2.size());
-        Result<Record> row3 = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"");
+        Result<Record> row3 = selectAllRowsFromTable(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"");
         assertEquals(1, row3.size());
 
         dbOperations.add(dslContext -> tiesDbOperations.deleteEntity(dslContext, SchemaRegistry.getEntityTypeByName(
@@ -201,12 +207,11 @@ public class TiesDbServiceContainerizedTest {
 
         assertDoesNotThrow(() -> tiesDbService.execute(dbOperations));
 
-        Result<Record> row4 = tiesDbService.selectAllRowsFromTable("ties_data.\"GNBCUCPFunction\"");
+        Result<Record> row4 = selectAllRowsFromTable(dslContext, "ties_data.\"c4a425179d3089b5288fdf059079d0ea26977f0f\"");
         assertEquals(0, row4.size());
-        Result<Record> row5 = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeApplication\"");
+        Result<Record> row5 = selectAllRowsFromTable(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"");
         assertEquals(1, row5.size());
-        Result<Record> row6 = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\"");
+        Result<Record> row6 = selectAllRowsFromTable(dslContext, "ties_data.\"7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7\"");
         assertEquals(0, row6.size());
 
     }
@@ -218,22 +223,22 @@ public class TiesDbServiceContainerizedTest {
         map1.put("id", "id1");
         map1.put("fdn", "fdn1");
         map1.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map1);
 
         Map<String, Object> map2 = new HashMap<>();
         map2.put("id", "id1");
         map2.put("name", "CloudNativeSystem");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", map2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"", map2);
 
         Map<String, Object> map3 = new HashMap<>();
         map3.put("id", "id1");
         map3.put("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "relId");
         map3.put("REL_FK_deployed-as-cloudNativeSystem", "id1");
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", map3);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", map3);
 
-        Result<Record> row2 = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> row2 = selectAllRowsFromTable(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(1, row2.size());
-        Result<Record> row1 = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> row1 = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, row1.size());
 
         dbOperations.add(dslContext -> tiesDbOperations.deleteEntity(dslContext, SchemaRegistry.getEntityTypeByName(
@@ -241,12 +246,14 @@ public class TiesDbServiceContainerizedTest {
 
         assertDoesNotThrow(() -> tiesDbService.execute(dbOperations));
 
-        Result<Record> meRecords = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> meRecords = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals("id1", meRecords.get(0).get("id"));
         assertEquals("fdn1", meRecords.get(0).get("fdn"));
         assertNull(meRecords.get(0).get("REL_FK_deployed-as-cloudNativeSystem"));
         assertNull(meRecords.get(0).get("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
-        Result<Record> cnsRecords = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> cnsRecords = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(0, cnsRecords.size());
     }
 
@@ -256,24 +263,24 @@ public class TiesDbServiceContainerizedTest {
         managedElementEntity1.put("id", "managedelement_id1");
         managedElementEntity1.put("fdn", "managedelement_fdn1");
         managedElementEntity1.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity1);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity1);
 
         Map<String, Object> cloudNativeAppEntity = new HashMap<>();
         cloudNativeAppEntity.put("id", "cna-1");
         cloudNativeAppEntity.put("name", "CloudNativeApp1");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cloudNativeAppEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cloudNativeAppEntity);
 
         Map<String, Object> meToCnaRelationship = new HashMap<>();
         meToCnaRelationship.put("id", "cna-1");
         meToCnaRelationship.put("REL_FK_realised-managedElement", "managedelement_id1");
         meToCnaRelationship.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "rel_id1");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", meToCnaRelationship);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", meToCnaRelationship);
 
         Result<?> rowsBeforeMerge = dslContext.select(field("id"), field("name"), field(
                 "\"REL_FK_realised-managedElement\"").as("REL_FK_realised-managedElement"), field(
                         "\"REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION\"").as(
                                 "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")).from(table(
-                                        "ties_data.\"CloudNativeApplication\"")).fetch();
+                                        "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"")).fetch();
         assertEquals("cna-1", rowsBeforeMerge.get(0).get("id"));
         assertEquals("CloudNativeApp1", rowsBeforeMerge.get(0).get("name"));
         assertEquals("managedelement_id1", rowsBeforeMerge.get(0).get("REL_FK_realised-managedElement"));
@@ -282,18 +289,19 @@ public class TiesDbServiceContainerizedTest {
         Map<String, Object> cloudNativeAppEntity2 = new HashMap<>();
         cloudNativeAppEntity2.put("id", "cna-2");
         cloudNativeAppEntity2.put("name", "CloudNativeApp2");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", cloudNativeAppEntity2);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"", cloudNativeAppEntity2);
 
         Map<String, Object> modifiedMeToCnaRelationship = new HashMap<>();
         modifiedMeToCnaRelationship.put("id", "cna-2");
         modifiedMeToCnaRelationship.put("REL_FK_realised-managedElement", "managedelement_id1");
         modifiedMeToCnaRelationship.put("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "rel_id2");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeApplication\"", modifiedMeToCnaRelationship);
+        tiesDbOperations.merge(dslContext, "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"",
+                modifiedMeToCnaRelationship);
 
         Result<?> rowsAfterMerge = dslContext.select(field("id"), field("name"), field("\"REL_FK_realised-managedElement\"")
                 .as("REL_FK_realised-managedElement"), field("\"REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION\"")
                         .as("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION")).from(table(
-                                "ties_data.\"CloudNativeApplication\"")).fetch();
+                                "ties_data.\"e01fcb87ad2c34ce66c34420255e25aaca270e5e\"")).fetch();
 
         assertEquals("cna-1", rowsAfterMerge.get(0).get("id"));
         assertEquals("CloudNativeApp1", rowsAfterMerge.get(0).get("name"));
@@ -311,30 +319,31 @@ public class TiesDbServiceContainerizedTest {
         managedElementEntity.put("id", "me-id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity);
 
         Map<String, Object> enodeBFunctionEntity = new HashMap<>();
         enodeBFunctionEntity.put("id", "enodeb-id1");
         enodeBFunctionEntity.put("eNBId", 1L);
-        tiesDbOperations.merge(dslContext, "ties_data.\"ENodeBFunction\"", enodeBFunctionEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-logical_ENodeBFunction\"", enodeBFunctionEntity);
 
         Map<String, Object> meToEnodeBFuncRelation = new HashMap<>();
         meToEnodeBFuncRelation.put("id", "enodeb-id1");
         meToEnodeBFuncRelation.put("REL_FK_managed-by-managedElement", "me-id1");
         meToEnodeBFuncRelation.put("REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "eiid1");
-        meToEnodeBFuncRelation.put("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", ConvertToJooqTypeUtil.toJsonb(
-                List.of("fdn1", "cmHandleId1")));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ENodeBFunction\"", meToEnodeBFuncRelation);
+        meToEnodeBFuncRelation.put("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", JooqTypeConverter.toJsonb(List
+                .of("fdn1", "cmHandleId1")));
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-logical_ENodeBFunction\"",
+                meToEnodeBFuncRelation);
 
         tiesDbOperations.deleteRelationFromEntityTableByRelationId(dslContext, "eiid1", SchemaRegistry
                 .getRelationTypeByName("MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"));
 
-        Result<Record> rows = tiesDbService.selectAllRowsFromTable("ties_data.\"ENodeBFunction\"");
+        Result<Record> rows = selectAllRowsFromTable(dslContext, "ties_data.\"o-ran-smo-teiv-ran-logical_ENodeBFunction\"");
         assertEquals("enodeb-id1", rows.get(0).get("id"));
         assertEquals(1L, rows.get(0).get("eNBId"));
         //assertNull(rows.get(0).get("REL_FK_managed-by-managedElement"));
         assertNull(rows.get(0).get("REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of()), rows.get(0).get(
+        assertEquals(JooqTypeConverter.toJsonb(List.of()), rows.get(0).get(
                 "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"));
     }
 
@@ -344,36 +353,38 @@ public class TiesDbServiceContainerizedTest {
         Map<String, Object> cloudNativeSystemEntity = new HashMap<>();
         cloudNativeSystemEntity.put("id", "cloudnative_id1");
         cloudNativeSystemEntity.put("name", "CloudNativeSystem");
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"CloudNativeSystem\"",
-                cloudNativeSystemEntity));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"", cloudNativeSystemEntity));
 
         Map<String, Object> managedElementEntity = new HashMap<>();
         managedElementEntity.put("id", "managed_element_id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"ManagedElement\"",
-                managedElementEntity));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity));
 
         Map<String, Object> meTocnsRelationship = new HashMap<>();
         meTocnsRelationship.put("id", "managed_element_id1");
         meTocnsRelationship.put("REL_FK_deployed-as-cloudNativeSystem", "cloudnative_id1");
         meTocnsRelationship.put("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "eiid1");
-        meTocnsRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", ConvertToJooqTypeUtil
-                .toJsonb(List.of("fdn1", "cmHandleId1")));
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"ManagedElement\"",
-                meTocnsRelationship));
+        meTocnsRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", JooqTypeConverter.toJsonb(
+                List.of("fdn1", "cmHandleId1")));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", meTocnsRelationship));
 
         assertDoesNotThrow(() -> tiesDbService.execute(dbOperations));
 
-        Result<Record> rowsFromManagedElementTable = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementTable = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, rowsFromManagedElementTable.size());
         assertEquals("cloudnative_id1", rowsFromManagedElementTable.get(0).get("REL_FK_deployed-as-cloudNativeSystem"));
         assertEquals("eiid1", rowsFromManagedElementTable.get(0).get(
                 "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementTable.get(0).get(
+        assertEquals(JooqTypeConverter.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementTable.get(0).get(
                 "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
 
-        Result<Record> rowsFromCloudNativeSystem = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystem = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(1, rowsFromCloudNativeSystem.size());
     }
 
@@ -384,15 +395,15 @@ public class TiesDbServiceContainerizedTest {
         managedElementEntity.put("id", "managed_element_id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"ManagedElement\"",
-                managedElementEntity));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity));
 
         Map<String, Object> cloudNativeSystemEntity = new HashMap<>();
         cloudNativeSystemEntity.put("id", "cloudnative_id1");
         cloudNativeSystemEntity.put("name", "CloudNativeSystem");
 
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"CloudNativeSystem\"",
-                cloudNativeSystemEntity));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"", cloudNativeSystemEntity));
 
         // Create a faulty relationship map to trigger the rollback
         Map<String, Object> faultyCloudNativeSystemRelationship = new HashMap<>();
@@ -400,15 +411,17 @@ public class TiesDbServiceContainerizedTest {
         faultyCloudNativeSystemRelationship.put("REL_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_BAAAD",
                 "managed_element_id1");
         faultyCloudNativeSystemRelationship.put("REL_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_EIID", "eiid1");
-        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext, "ties_data.\"CloudNativeSystem\"",
-                faultyCloudNativeSystemRelationship));
+        dbOperations.add(wrDSLContext -> tiesDbOperations.merge(wrDSLContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"", faultyCloudNativeSystemRelationship));
 
         assertThrows(TiesException.class, () -> tiesDbService.execute(dbOperations));
 
-        Result<Record> rowsFromManagedElementTable = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementTable = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(0, rowsFromManagedElementTable.size());
 
-        Result<Record> rowsFromCloudNativeSystem = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystem = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(0, rowsFromCloudNativeSystem.size());
     }
 
@@ -418,35 +431,36 @@ public class TiesDbServiceContainerizedTest {
         Map<String, Object> cloudNativeSystemEntity = new HashMap<>();
         cloudNativeSystemEntity.put("id", "cloudnative_id1");
         cloudNativeSystemEntity.put("name", "CloudNativeSystem");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                cloudNativeSystemEntity);
 
         Map<String, Object> managedElementEntity = new HashMap<>();
         managedElementEntity.put("id", "managed_element_id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity);
 
         Map<String, Object> meToCnsRelationship = new HashMap<>();
         meToCnsRelationship.put("id", "managed_element_id1");
         meToCnsRelationship.put("REL_FK_deployed-as-cloudNativeSystem", "cloudnative_id1");
         meToCnsRelationship.put("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "eiid1");
-        meToCnsRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", ConvertToJooqTypeUtil
-                .toJsonb(List.of("fdn1", "cmHandleId1")));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", meToCnsRelationship);
+        meToCnsRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", JooqTypeConverter.toJsonb(
+                List.of("fdn1", "cmHandleId1")));
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", meToCnsRelationship);
 
-        Result<Record> rowsFromCloudNativeSystemBeforeDelete = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystemBeforeDelete = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(1, rowsFromCloudNativeSystemBeforeDelete.size());
 
-        Result<Record> rowsFromManagedElementBeforeDelete = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementBeforeDelete = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, rowsFromManagedElementBeforeDelete.size());
         assertEquals("cloudnative_id1", rowsFromManagedElementBeforeDelete.get(0).get(
                 "REL_FK_deployed-as-cloudNativeSystem"));
         assertEquals("eiid1", rowsFromManagedElementBeforeDelete.get(0).get(
                 "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementBeforeDelete.get(
-                0).get("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
+        assertEquals(JooqTypeConverter.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementBeforeDelete.get(0)
+                .get("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
 
         dbOperations.add(wrDSLContext -> tiesDbOperations.deleteEntity(wrDSLContext, SchemaRegistry.getEntityTypeByName(
                 "ManagedElement"), "managed_element_id1"));
@@ -462,10 +476,12 @@ public class TiesDbServiceContainerizedTest {
 
         assertDoesNotThrow(() -> tiesDbService.execute(dbOperations));
 
-        Result<Record> rowsFromManagedElementTable = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementTable = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(0, rowsFromManagedElementTable.size());
 
-        Result<Record> rowsFromCloudNativeSystem = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystem = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(0, rowsFromCloudNativeSystem.size());
     }
 
@@ -475,35 +491,37 @@ public class TiesDbServiceContainerizedTest {
         Map<String, Object> cloudNativeSystemEntity = new HashMap<>();
         cloudNativeSystemEntity.put("id", "cloudnative_id1");
         cloudNativeSystemEntity.put("name", "CloudNativeSystem");
-        tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                cloudNativeSystemEntity);
 
         Map<String, Object> managedElementEntity = new HashMap<>();
         managedElementEntity.put("id", "managed_element_id1");
         managedElementEntity.put("fdn", "fdn1");
         managedElementEntity.put("cmId", JSONB.jsonb("{\"name\":\"Hellmann1\"}"));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", managedElementEntity);
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"", managedElementEntity);
 
         Map<String, Object> cloudNativeSystemRelationship = new HashMap<>();
         cloudNativeSystemRelationship.put("id", "managed_element_id1");
         cloudNativeSystemRelationship.put("REL_FK_deployed-as-cloudNativeSystem", "cloudnative_id1");
         cloudNativeSystemRelationship.put("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", "eiid1");
-        cloudNativeSystemRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM",
-                ConvertToJooqTypeUtil.toJsonb(List.of("fdn1", "cmHandleId1")));
-        tiesDbOperations.merge(dslContext, "ties_data.\"ManagedElement\"", cloudNativeSystemRelationship);
+        cloudNativeSystemRelationship.put("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM", JooqTypeConverter
+                .toJsonb(List.of("fdn1", "cmHandleId1")));
+        tiesDbOperations.merge(dslContext, "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"",
+                cloudNativeSystemRelationship);
 
-        Result<Record> rowsFromCloudNativeSystemBeforeDelete = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystemBeforeDelete = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(1, rowsFromCloudNativeSystemBeforeDelete.size());
 
-        Result<Record> rowsFromManagedElementBeforeDelete = tiesDbService.selectAllRowsFromTable(
-                "ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementBeforeDelete = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, rowsFromManagedElementBeforeDelete.size());
         assertEquals("cloudnative_id1", rowsFromManagedElementBeforeDelete.get(0).get(
                 "REL_FK_deployed-as-cloudNativeSystem"));
         assertEquals("eiid1", rowsFromManagedElementBeforeDelete.get(0).get(
                 "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementBeforeDelete.get(
-                0).get("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
+        assertEquals(JooqTypeConverter.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementBeforeDelete.get(0)
+                .get("REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
 
         dbOperations.add(wrDSLContext -> tiesDbOperations.deleteEntity(wrDSLContext, SchemaRegistry.getEntityTypeByName(
                 "ManagedElement"), "managed_element_id1"));
@@ -516,14 +534,16 @@ public class TiesDbServiceContainerizedTest {
 
         assertThrows(TiesException.class, () -> tiesDbService.execute(dbOperations));
 
-        Result<Record> rowsFromCloudNativeSystem = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystem = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(1, rowsFromCloudNativeSystem.size());
-        Result<Record> rowsFromManagedElementTable = tiesDbService.selectAllRowsFromTable("ties_data.\"ManagedElement\"");
+        Result<Record> rowsFromManagedElementTable = selectAllRowsFromTable(dslContext,
+                "ties_data.\"o-ran-smo-teiv-ran-oam_ManagedElement\"");
         assertEquals(1, rowsFromManagedElementTable.size());
         assertEquals("cloudnative_id1", rowsFromManagedElementTable.get(0).get("REL_FK_deployed-as-cloudNativeSystem"));
         assertEquals("eiid1", rowsFromManagedElementTable.get(0).get(
                 "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
-        assertEquals(ConvertToJooqTypeUtil.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementTable.get(0).get(
+        assertEquals(JooqTypeConverter.toJsonb(List.of("fdn1", "cmHandleId1")), rowsFromManagedElementTable.get(0).get(
                 "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"));
     }
 
@@ -551,12 +571,15 @@ public class TiesDbServiceContainerizedTest {
         final CountDownLatch firstTransactionCompletedMergeEntity1 = new CountDownLatch(1);
         final CountDownLatch secondTransactionCompletedMergeEntity2 = new CountDownLatch(1);
         dbOperations1.add(dslContext -> {
-            tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity1);
+            tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                    cloudNativeSystemEntity1);
             firstTransactionCompletedMergeEntity1.countDown();
             try {
                 secondTransactionCompletedMergeEntity2.await();
-                tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity2);
-                tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity3);
+                tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                        cloudNativeSystemEntity2);
+                tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                        cloudNativeSystemEntity3);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
@@ -564,11 +587,14 @@ public class TiesDbServiceContainerizedTest {
         //Try to add the same rows in another transaction in another order.
         dbOperations2.add(dslContext -> {
             try {
-                tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity2);
+                tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                        cloudNativeSystemEntity2);
                 secondTransactionCompletedMergeEntity2.countDown();
                 firstTransactionCompletedMergeEntity1.await();
-                tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity1);
-                tiesDbOperations.merge(dslContext, "ties_data.\"CloudNativeSystem\"", cloudNativeSystemEntity4);
+                tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                        cloudNativeSystemEntity1);
+                tiesDbOperations.merge(dslContext, "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"",
+                        cloudNativeSystemEntity4);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
@@ -580,7 +606,8 @@ public class TiesDbServiceContainerizedTest {
         t2.start();
         t1.join();
         t2.join();
-        Result<Record> rowsFromCloudNativeSystem = tiesDbService.selectAllRowsFromTable("ties_data.\"CloudNativeSystem\"");
+        Result<Record> rowsFromCloudNativeSystem = selectAllRowsFromTable(dslContext,
+                "ties_data.\"163276fa439cdfccabb80f7acacb6fa638e8d314\"");
         assertEquals(4, rowsFromCloudNativeSystem.size());
     }
 
@@ -596,4 +623,31 @@ public class TiesDbServiceContainerizedTest {
         assertThrows(TiesException.class, () -> tiesDbService.execute(dbOperations));
         assertEquals(maxRetryAttemptsForDeadlock, attempts.get());
     }
+
+    /**
+     * The out of the box binding for geography is available in the commercial jOOQ distribution only. Because of this,
+     * a select * from tableName; query fails if the table has a column with geography type. Even if the value in that
+     * column is null.
+     *
+     * @param readDataDslContext
+     * @param tableName
+     *     For example: ties_data."AntennaModule"
+     * @return the fetched rows. Values of geography type are represented as String values.
+     */
+    public static Result<Record> selectAllRowsFromTable(DSLContext readDataDslContext, final String tableName) {
+        String unqualifiedName = tableName.split("\\.")[1].split("\"")[1];
+        Table<?> table = readDataDslContext.meta().getTables().stream().filter(t -> t.getName().equals(unqualifiedName))
+                .toList().get(0);
+        List<Column> columns = readDataDslContext.meta(table).informationSchema().getColumns();
+        List<Field<?>> columnsToSelect = columns.stream().map(c -> {
+            if ("geography".equals(c.getDataType())) {
+                return field(String.format(TiesConstants.ST_TO_STRING, String.format(QUOTED_STRING, c.getColumnName())));
+            } else if ("jsonb".equals(c.getDataType())) {
+                return field(name(c.getColumnName()), JSONB.class);
+            } else {
+                return field(name(c.getColumnName()));
+            }
+        }).toList();
+        return readDataDslContext.select(columnsToSelect).from(table(tableName)).fetch();
+    }
 }
index 9623be0..73c0053 100644 (file)
  */
 package org.oran.smo.teiv.service.cloudevent;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
+import org.junit.jupiter.api.BeforeEach;
+import org.oran.smo.teiv.exception.YangModelException;
+import org.oran.smo.teiv.schema.MockSchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoader;
+import org.oran.smo.teiv.schema.SchemaLoaderException;
 import org.oran.smo.teiv.startup.SchemaHandler;
 import io.cloudevents.CloudEvent;
 import org.junit.jupiter.api.Assertions;
 
+import static org.junit.Assert.assertNull;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -40,7 +47,6 @@ import org.oran.smo.teiv.service.cloudevent.data.Relationship;
 import org.oran.smo.teiv.utils.CloudEventTestUtil;
 
 import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.annotation.DirtiesContext;
 
 @SpringBootTest
 class CloudEventParserTest {
@@ -51,8 +57,13 @@ class CloudEventParserTest {
     @MockBean
     private SchemaHandler schemaHandler;
 
+    @BeforeEach
+    public void setup() throws SchemaLoaderException, YangModelException, IOException {
+        SchemaLoader mockSchemaLoader = new MockSchemaLoader();
+        mockSchemaLoader.loadSchemaRegistry();
+    }
+
     @Test
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
     void testParseCloudEventData() {
         final CloudEvent cloudEvent = cloudEventFromJson("src/test/resources/cloudeventdata/common/ce-with-data.json");
         final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
@@ -75,26 +86,63 @@ class CloudEventParserTest {
         Relationship relationship = parsedCloudEventData.getRelationships().get(0);
         assertEquals("o-ran-smo-teiv-ran", relationship.getModule());
         assertEquals("NRCELLDU_USES_NRSECTORCARRIER", relationship.getType());
-        assertEquals("entityId_1", relationship.getASide());
+        assertEquals("relationshipId", relationship.getId());
+        assertEquals(
+                "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR004,ManagedElement=me04,GNBDUFunction=gnbdu04,NRCellDU=NR-Cell-07",
+                relationship.getASide());
         assertEquals("entityId_2", relationship.getBSide());
+        assertEquals(null, relationship.getSourceIds());
 
         relationship = parsedCloudEventData.getRelationships().get(1);
         assertEquals("o-ran-smo-teiv-ran", relationship.getModule());
         assertEquals("NRCELLDU_USES_NRSECTORCARRIER", relationship.getType());
+        assertEquals("relationshipId2", relationship.getId());
         assertEquals("entityId_3", relationship.getASide());
         assertEquals("entityId_4", relationship.getBSide());
+        assertEquals(List.of("source10", "source20"), relationship.getSourceIds());
 
         relationship = parsedCloudEventData.getRelationships().get(2);
         assertEquals("o-ran-smo-teiv-ran", relationship.getModule());
-        assertEquals("GNBDUFunctionRealisedByCloudNativeApplication", relationship.getType());
+        assertEquals("GNBDUFUNCTION_PROVIDES_NRCELLDU", relationship.getType());
+        assertEquals(
+                "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=89FE9A4ED8451D779865C389900E247B13E360B0A4175EBA80AA9B384BFA4C688F17865AFD934085B0235BCA66128F2E6D4CE6953EAAB2EDEBD94B3683C1A064",
+                relationship.getId());
         assertEquals("entityId_5", relationship.getASide());
-        assertEquals("entityId_6", relationship.getBSide());
+        assertEquals(
+                "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR004,ManagedElement=me04,GNBDUFunction=gnbdu04,NRCellDU=NR-Cell-07",
+                relationship.getBSide());
 
         relationship = parsedCloudEventData.getRelationships().get(3);
         assertEquals("o-ran-smo-teiv-ran", relationship.getModule());
-        assertEquals("GNBDUFunctionRealisedByCloudNativeApplication", relationship.getType());
+        assertEquals("GNBDUFUNCTION_PROVIDES_NRCELLDU", relationship.getType());
+        assertEquals("relationshipId4", relationship.getId());
         assertEquals("entityId_5", relationship.getASide());
-        assertEquals("entityId_7", relationship.getBSide());
+        assertEquals("entityId_3", relationship.getBSide());
+        assertEquals(List.of("source21"), relationship.getSourceIds());
+    }
+
+    @Test
+    void testParseCloudEventDataWithArray() {
+        final CloudEvent cloudEvent = cloudEventFromJson("src/test/resources/cloudeventdata/common/ce-arrays.json");
+        final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        // Parse an array of 3 elements
+        validateEntity(parsedCloudEventData.getEntities().get(0), "o-ran-smo-teiv-ran", "AntennaCapability", "entityId_0",
+                Map.of("eUtranFqBands", "[a, b, c]"), null);
+
+        // Parse an array of 2 elements
+        validateEntity(parsedCloudEventData.getEntities().get(1), "o-ran-smo-teiv-ran", "AntennaCapability", "entityId_1",
+                Map.of("eUtranFqBands", "[a, b]"), null);
+
+        // Parse an array of 1 element
+        validateEntity(parsedCloudEventData.getEntities().get(2), "o-ran-smo-teiv-ran", "AntennaCapability", "entityId_2",
+                Map.of("geranFqBands", "a"), null);
+
+        // Parse an empty array
+        validateEntity(parsedCloudEventData.getEntities().get(3), "o-ran-smo-teiv-ran", "AntennaCapability", "entityId_3",
+                Map.of("eUtranFqBands", "q"), null);
+
+        Assertions.assertEquals(0, parsedCloudEventData.getRelationships().size());
     }
 
     @Test
@@ -109,8 +157,8 @@ class CloudEventParserTest {
     void testNoRelationshipInCloudEvent() {
         final CloudEvent cloudEvent = cloudEventFromJson("src/test/resources/cloudeventdata/common/ce-one-entity.json");
         final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
-        validateEntity(parsedCloudEventData.getEntities().get(0), "o-ran-smo-teiv-ran", "NRCellDU", "entityId_1", 3, Map.of(
-                "cellLocalId", 4589L, "nRPCI", 12L, "nRTAC", 310L));
+        validateEntity(parsedCloudEventData.getEntities().get(0), "o-ran-smo-teiv-ran", "NRCellDU", "entityId_1", Map.of(
+                "cellLocalId", 4589L, "nRPCI", 12L, "nRTAC", 310L), null);
         Assertions.assertTrue(parsedCloudEventData.getRelationships().isEmpty());
     }
 
@@ -118,7 +166,7 @@ class CloudEventParserTest {
     void testCloudEventDataIsNotAValidJson() {
         final CloudEvent cloudEvent = CloudEventTestUtil.getCloudEvent("create", "{invalidjson");
         final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
     }
 
     @Test
@@ -133,41 +181,142 @@ class CloudEventParserTest {
         final CloudEvent arrayEntitiesCloudEvent = CloudEventTestUtil.getCloudEvent("create",
                 "{\"entities\":[{\"some_entity_field\": 54321}]}");
         ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(arrayEntitiesCloudEvent);
-        Assertions.assertNull(parsedCloudEventData);
-
-        final CloudEvent objectEntitiesCloudEvent = CloudEventTestUtil.getCloudEvent("create",
-                "{\"entities\":{\"some_entity_field\": 54321}}");
-        parsedCloudEventData = cloudEventParser.getCloudEventData(objectEntitiesCloudEvent);
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
 
         final CloudEvent arrayRelationshipsCloudEvent = CloudEventTestUtil.getCloudEvent("create",
                 "{\"relationships\":[{\"some_relationship_field\": 54321}]}");
         parsedCloudEventData = cloudEventParser.getCloudEventData(arrayRelationshipsCloudEvent);
-        Assertions.assertNull(parsedCloudEventData);
-
-        final CloudEvent objectRelationshipsCloudEvent = CloudEventTestUtil.getCloudEvent("create",
-                "{\"relationships\":{\"some_relationship_field\": 54321}}");
-        parsedCloudEventData = cloudEventParser.getCloudEventData(objectRelationshipsCloudEvent);
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
     }
 
     @Test
-    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
     void testRelationshipsIsNotAValidYangData() {
-        CloudEvent cloudEvent = CloudEventTestUtil.getCloudEvent("create", "{\"relationships\":{\"a_field\": 123}}");
+        CloudEvent cloudEvent = CloudEventTestUtil.getCloudEvent("create", "{\"relationships\":[{\"a_field\": 123}]}");
         ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
 
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
 
-        cloudEvent = CloudEventTestUtil.getCloudEvent("merge", "{\"relationships\":{\"a_field\": 123}}");
+        cloudEvent = CloudEventTestUtil.getCloudEvent("merge", "{\"relationships\":[{\"a_field\": 123}]}");
         parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
 
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
 
-        cloudEvent = CloudEventTestUtil.getCloudEvent("delete", "{\"relationships\":{\"a_field\": 123}}");
+        cloudEvent = CloudEventTestUtil.getCloudEvent("delete", "{\"relationships\":[{\"a_field\": 123}]}");
         parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
 
-        Assertions.assertNull(parsedCloudEventData);
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipMissingASide() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-missing-a-side.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipMissingBSide() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-missing-b-side.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipMissingBothSides() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-missing-both-sides.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipMissingId() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-missing-id.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipInvalidType() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-invalid-type.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipInvalidModule() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-invalid-module.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testRelationshipInvalidModuleTypePair() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-relationship-invalid-module-type-pair.json");
+
+        ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testParseCloudEventDataWithInvalidRelationshipId() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids.json");
+        final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testParseCloudEventDataWithInvalidRelationshipASideId() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids2.json");
+        final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    @Test
+    void testParseCloudEventDataWithInvalidRelationshipBSideId() {
+        final CloudEvent cloudEvent = cloudEventFromJson(
+                "src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids3.json");
+        final ParsedCloudEventData parsedCloudEventData = cloudEventParser.getCloudEventData(cloudEvent);
+
+        assertNull(parsedCloudEventData);
+    }
+
+    private void validateEntity(final Entity entity, String expectedModuleReference, String expectedEntityName,
+            String expectedId, Map<String, Object> expectedAttributes, List<String> expectedSourceIds) {
+        assertEquals(expectedModuleReference, entity.getModule());
+        assertEquals(expectedEntityName, entity.getType());
+        assertEquals(expectedId, entity.getId());
+        final Map<String, Object> attributes = entity.getAttributes();
+        assertEquals(expectedAttributes.size(), attributes.size());
+        for (Map.Entry<String, Object> entry : expectedAttributes.entrySet()) {
+            assertTrue(attributes.containsKey(entry.getKey()));
+            assertEquals(entry.getValue().getClass(), attributes.get(entry.getKey()).getClass());
+            assertEquals(entry.getValue(), attributes.get(entry.getKey()));
+        }
+        assertEquals(expectedSourceIds, entity.getSourceIds());
     }
 
     private void validateEntity(final Entity entity, String expectedModuleReference, String expectedEntityName,
diff --git a/teiv/src/test/java/org/oran/smo/teiv/service/cloudevent/data/ParsedCloudEventDataTest.java b/teiv/src/test/java/org/oran/smo/teiv/service/cloudevent/data/ParsedCloudEventDataTest.java
new file mode 100644 (file)
index 0000000..a8e46a2
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  ============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.teiv.service.cloudevent.data;
+
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.A_SIDE;
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.B_SIDE;
+import static org.oran.smo.teiv.schema.RelationshipDataLocation.RELATION;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import org.oran.smo.teiv.schema.RelationType;
+import org.oran.smo.teiv.schema.SchemaRegistry;
+
+public class ParsedCloudEventDataTest {
+
+    @Test
+    void testSortForEntities() {
+        Entity e1 = new Entity("m", "type3", "id1", Map.of(), List.of());
+        Entity e2 = new Entity("a", "type2", "id2", Map.of(), List.of());
+        Entity e3 = new Entity("m", "type2", "id1", Map.of(), List.of());
+        Entity e4 = new Entity("m", "type5", "id1", null, null);
+        Entity e5 = new Entity("m", "type1", "id9999", Map.of(), List.of());
+        List<Entity> entities = List.of(e1, e2, e3, e4, e5);
+        ParsedCloudEventData data = new ParsedCloudEventData(entities, null);
+        data.sort();
+        assertEquals(e5, data.getEntities().get(0));
+        assertEquals(e3, data.getEntities().get(1));
+        assertEquals(e2, data.getEntities().get(2));
+        assertEquals(e1, data.getEntities().get(3));
+        assertEquals(e4, data.getEntities().get(4));
+    }
+
+    @Test
+    void testSortForRelationships() {
+        Relationship r1 = new Relationship("a", "type3", "id1", "a", "b", null);
+        Relationship r2 = new Relationship("m", "type2", "id2", "y", "a", null);
+        Relationship r3 = new Relationship("m", "type2", "id3", "a", "c", null);
+        Relationship r4 = new Relationship("m", "type2", "id4", "z", "b", null);
+        Relationship r5 = new Relationship("m", "type5", "id5", "a", "b", null);
+        Relationship r6 = new Relationship("m", "type1", "id9999", "a", "b", null);
+        List<Relationship> relationships = List.of(r1, r2, r3, r4, r5, r6);
+        ParsedCloudEventData data = new ParsedCloudEventData(null, relationships);
+
+        try (MockedStatic<SchemaRegistry> staticMock = Mockito.mockStatic(SchemaRegistry.class)) {
+            staticMock.when(() -> SchemaRegistry.getRelationTypeByName("type2")).thenReturn(RelationType.builder()
+                    .relationshipStorageLocation(A_SIDE).build());
+            data.sort();
+            assertEquals(r6, data.getRelationships().get(0));
+            assertEquals(r3, data.getRelationships().get(1));
+            assertEquals(r2, data.getRelationships().get(2));
+            assertEquals(r4, data.getRelationships().get(3));
+            assertEquals(r1, data.getRelationships().get(4));
+            assertEquals(r5, data.getRelationships().get(5));
+        }
+
+        try (MockedStatic<SchemaRegistry> staticMock = Mockito.mockStatic(SchemaRegistry.class)) {
+            staticMock.when(() -> SchemaRegistry.getRelationTypeByName("type2")).thenReturn(RelationType.builder()
+                    .relationshipStorageLocation(B_SIDE).build());
+            data.sort();
+            assertEquals(r6, data.getRelationships().get(0));
+            assertEquals(r2, data.getRelationships().get(1));
+            assertEquals(r4, data.getRelationships().get(2));
+            assertEquals(r3, data.getRelationships().get(3));
+            assertEquals(r1, data.getRelationships().get(4));
+            assertEquals(r5, data.getRelationships().get(5));
+        }
+
+        try (MockedStatic<SchemaRegistry> staticMock = Mockito.mockStatic(SchemaRegistry.class)) {
+            staticMock.when(() -> SchemaRegistry.getRelationTypeByName("type2")).thenReturn(RelationType.builder()
+                    .relationshipStorageLocation(RELATION).build());
+            data.sort();
+            assertEquals(r6, data.getRelationships().get(0));
+            assertEquals(r2, data.getRelationships().get(1));
+            assertEquals(r3, data.getRelationships().get(2));
+            assertEquals(r4, data.getRelationships().get(3));
+            assertEquals(r1, data.getRelationships().get(4));
+            assertEquals(r5, data.getRelationships().get(5));
+        }
+    }
+
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/utils/ConvertToJooqTypeUtilTest.java b/teiv/src/test/java/org/oran/smo/teiv/utils/ConvertToJooqTypeUtilTest.java
deleted file mode 100644 (file)
index d4d28fd..0000000
+++ /dev/null
@@ -1,58 +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 org.oran.smo.teiv.utils;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.jooq.JSONB;
-import org.junit.Test;
-
-import org.oran.smo.teiv.exception.InvalidFieldInYangDataException;
-import org.oran.smo.teiv.utils.schema.Geography;
-
-import static org.oran.smo.teiv.utils.ConvertToJooqTypeUtil.*;
-
-public class ConvertToJooqTypeUtilTest {
-
-    @Test
-    public void testToJsonb() {
-        assertEquals(JSONB.jsonb("{}"), toJsonb("{}"));
-        assertEquals(JSONB.jsonb("{\"key\":\"value\"}"), toJsonb("{\"key\":\"value\"}"));
-        assertEquals(JSONB.jsonb("[]"), toJsonb("[]"));
-        assertEquals(JSONB.jsonb("[1]"), toJsonb("[1]"));
-        assertEquals(JSONB.jsonb("[1,2,3]"), toJsonb("[1,2,3]"));
-        assertEquals(JSONB.jsonb("[\"value1\",\"value2\"]"), toJsonb("[\"value1\",\"value2\"]"));
-        assertEquals(JSONB.jsonb("[\"leading\",\"whitespaces\"]"), toJsonb("     [\"leading\",\"whitespaces\"]"));
-        assertEquals(JSONB.jsonb("[\"a_string\"]"), toJsonb("a_string"));
-        assertEquals(JSONB.jsonb("[\"23\"]"), toJsonb("23"));
-        assertEquals(JSONB.jsonb("[54]"), toJsonb(54L));
-        assertEquals(JSONB.jsonb("[92.13]"), toJsonb(92.13));
-    }
-
-    @Test
-    public void testToGeography() throws InvalidFieldInYangDataException {
-        assertEquals(new Geography(47.497913, 19.040236), toGeography(
-                "{\"latitude\": 47.497913,\"longitude\": 19.040236}"));
-        assertThrows(InvalidFieldInYangDataException.class, () -> toGeography("{invalidjson"));
-        assertThrows(InvalidFieldInYangDataException.class, () -> toGeography(9));
-    }
-}
index f8c1665..df2b5a7 100644 (file)
@@ -23,43 +23,75 @@ package org.oran.smo.teiv.utils;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import org.jooq.JSONB;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import lombok.Getter;
+
 public class EndToEndExpectedResults {
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
     private final JsonNode rootNode;
 
+    @Getter
+    public ArrayList<String> tables;
+
     public EndToEndExpectedResults(final String jsonPath) throws IOException {
         rootNode = OBJECT_MAPPER.readTree(Files.readString(Paths.get(jsonPath)));
+        tables = new ArrayList<>();
+        rootNode.fields().forEachRemaining(entry -> tables.add(entry.getKey()));
     }
 
     public Map<String, Object> get(final String entryId) {
-        Map<String, Object> expectedValuesMap = new HashMap<>();
         JsonNode attributesNode = rootNode.required(entryId);
-        attributesNode.fields().forEachRemaining(entry -> {
-            String key = entry.getKey();
-            JsonNode valueNode = entry.getValue();
-            if (valueNode.isContainerNode()) {
-                expectedValuesMap.put(key, JSONB.jsonb(valueNode.toString()));
-            } else if (valueNode.isTextual()) {
-                expectedValuesMap.put(key, valueNode.asText());
-            } else if (valueNode.isDouble()) {
-                expectedValuesMap.put(key, valueNode.asDouble());
-            } else if (valueNode.isNumber()) {
-                expectedValuesMap.put(key, valueNode.asLong());
-            } else if (valueNode.isBoolean()) {
-                expectedValuesMap.put(key, valueNode.asBoolean());
+        return processData(attributesNode);
+    }
+
+    public Map<String, Object> processData(JsonNode node) {
+        Map<String, Object> tableData = new HashMap<>();
+        node.fields().forEachRemaining(entry -> tableData.put(entry.getKey(), processNode(entry.getValue())));
+        return tableData;
+    }
+
+    private Object processNode(JsonNode valueNode) {
+        if (valueNode.isContainerNode()) {
+            return JSONB.jsonb(valueNode.toString());
+        } else if (valueNode.isTextual()) {
+            return valueNode.asText();
+        } else if (valueNode.isDouble()) {
+            return valueNode.asDouble();
+        } else if (valueNode.isNumber()) {
+            return valueNode.asLong();
+        } else if (valueNode.isBoolean()) {
+            return valueNode.asBoolean();
+        }
+        return null;
+    }
+
+    public List<Map<String, Object>> getTableData(String tableName) {
+        List<Map<String, Object>> tableData = new ArrayList<>();
+        JsonNode tableArrayNode = rootNode.get(tableName);
+        if (tableArrayNode != null && tableArrayNode.isArray()) {
+            for (JsonNode contentNode : tableArrayNode) {
+                tableData.add(processData(contentNode));
             }
-        });
-        return expectedValuesMap;
+        }
+        return tableData;
     }
 
-    public Map<String, Object> getAll() {
-        return EndToEndTestUtil.processNode(rootNode);
+    public List<String> getTableEntryIds(String tableName) {
+        List<String> entryIds = new ArrayList<>();
+        JsonNode tableArrayNode = rootNode.get(tableName);
+        if (tableArrayNode != null && tableArrayNode.isArray()) {
+            for (JsonNode elementNode : tableArrayNode) {
+                entryIds.add(elementNode.textValue());
+            }
+        }
+        return entryIds;
     }
 }
diff --git a/teiv/src/test/java/org/oran/smo/teiv/utils/TiesTestConstants.java b/teiv/src/test/java/org/oran/smo/teiv/utils/TiesTestConstants.java
new file mode 100644 (file)
index 0000000..7079bf5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  ============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.teiv.utils;
+
+public class TiesTestConstants {
+
+    public static final String APPLICATION_JSON = "application/json";
+
+}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/utils/exposure/PaginationVerifierTestUtil.java b/teiv/src/test/java/org/oran/smo/teiv/utils/exposure/PaginationVerifierTestUtil.java
deleted file mode 100644 (file)
index d8d8f55..0000000
+++ /dev/null
@@ -1,58 +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 org.oran.smo.teiv.utils.exposure;
-
-import org.oran.smo.teiv.exposure.spi.mapper.PageMetaData;
-
-import org.junit.jupiter.api.Assertions;
-import org.springframework.http.ResponseEntity;
-
-import java.util.Arrays;
-import java.util.Map;
-
-public class PaginationVerifierTestUtil {
-
-    public static void verifyResponse(Map<String, Object> expected, Map<String, Object> actual) {
-        String[] paginationKeys = { "next", "prev", "first", "last", "self" };
-        for (String key : expected.keySet()) {
-            if (Arrays.stream(paginationKeys).anyMatch(paginationKey -> paginationKey.equals(key))) {
-                Assertions.assertEquals(((PageMetaData) expected.get(key)).getHref(), ((PageMetaData) actual.get(key))
-                        .getHref());
-            } else {
-                Assertions.assertEquals(expected.get(key), actual.get(key));
-            }
-        }
-    }
-
-    public static void verifyResponse(ResponseEntity<Object> expected, ResponseEntity<Object> actual) {
-        Map<String, Object> expectedBody = (Map<String, Object>) expected.getBody();
-        Map<String, Object> actualBody = (Map<String, Object>) actual.getBody();
-        String[] paginationKeys = { "next", "prev", "first", "last", "self" };
-        for (String key : expectedBody.keySet()) {
-            if (Arrays.stream(paginationKeys).anyMatch(paginationKey -> paginationKey.equals(key))) {
-                Assertions.assertEquals(((PageMetaData) expectedBody.get(key)).getHref(), ((PageMetaData) actualBody.get(
-                        key)).getHref());
-            } else {
-                Assertions.assertEquals(expectedBody.get(key), actualBody.get(key));
-            }
-        }
-    }
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTest.java b/teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTest.java
deleted file mode 100644 (file)
index ccb870e..0000000
+++ /dev/null
@@ -1,1616 +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 org.oran.smo.teiv.utils.query;
-
-import org.oran.smo.teiv.exposure.utils.PaginationDTO;
-import org.oran.smo.teiv.schema.SchemaLoaderException;
-import org.oran.smo.teiv.schema.MockSchemaLoader;
-import org.oran.smo.teiv.utils.query.exception.TiesPathException;
-
-import org.jooq.Condition;
-import org.jooq.DSLContext;
-import org.jooq.Field;
-import org.jooq.Query;
-import org.jooq.Select;
-import org.jooq.impl.DSL;
-import org.jooq.tools.jdbc.MockConnection;
-import org.jooq.tools.jdbc.MockResult;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-
-import java.util.List;
-
-import static org.oran.smo.teiv.schema.SchemaRegistry.*;
-import static org.oran.smo.teiv.utils.TiesConstants.*;
-import static org.oran.smo.teiv.utils.query.QueryMonadTestUtil.*;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
-import static org.jooq.impl.DSL.condition;
-import static org.jooq.impl.DSL.field;
-
-class QueryMonadTest {
-    private static DSLContext context;
-
-    @BeforeAll
-    public static void setUp() throws SchemaLoaderException {
-        MockSchemaLoader mockSchemaLoader = new MockSchemaLoader();
-        mockSchemaLoader.loadSchemaRegistry();
-        context = DSL.using(new MockConnection(m -> new MockResult[1]));
-    }
-
-    @Test
-    void test1i_noAttributesNorFieldsGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String attributes = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, attributes, relationships);
-
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test2i_attributesGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes";
-        String attributes = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, attributes, relationships);
-        Select<?> builtWithQM = (Select<?>) underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(
-                context);
-        Select<?> reference = (Select<?>) createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")), field(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")).as(String.format(TIES_DATA,
-                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")), field(String.format(
-                                                TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                                                        "dUpLMNId")).as(String.format(TIES_DATA,
-                                                                "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                                                                        "dUpLMNId")), field(String.format(TIES_DATA,
-                                                                                "GNBDUFunction") + "." + String.format(
-                                                                                        QUOTED_STRING, "gNBDUId")).as(String
-                                                                                                .format(TIES_DATA,
-                                                                                                        "GNBDUFunction") + "." + String
-                                                                                                                .format(QUOTED_STRING,
-                                                                                                                        "gNBDUId")),
-                field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBDUId")).as(String
-                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBDUId")), field(String
-                                .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBIdLength")).as(
-                                        String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                                                "gNBIdLength")), field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "cmId")).as(
-                                                                String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                                                        .format(QUOTED_STRING, "cmId"))).from(String.format(
-                                                                                TIES_DATA, "GNBDUFunction")));
-
-        List<Field<?>> fieldsActual = builtWithQM.getSelect();
-        List<Field<?>> fieldsExpected = reference.getSelect();
-        Assertions.assertTrue(fieldsActual.containsAll(fieldsExpected));
-    }
-
-    @Test
-    void test2ii_attributesTypoException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attribute/fdn; /attributes/id; /attributes/gNBId";
-        String filter = "/attributes[contains(@fdn, \"93\")]  |  /attributes[@gNBId=4000259]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test2iii_attributesMissingSlashException() {
-        String entityType = "GNBDUFunction";
-        String fields = "attributes/fdn; /attributes/id; /attributes/gNBId";
-        String filter = "/attributes[contains(@fdn, \"93\")]  |  /attributes[@gNBId=4000259]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test3i_attributesFdnGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes(fdn)";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")), field(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME)).as(String.format(
-                                        TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME)))
-                .from(String.format(TIES_DATA, "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test3ii_attributesFdnGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes/fdn";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")), field(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME)).as(String.format(
-                                        TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, ID_COLUMN_NAME)))
-                .from(String.format(TIES_DATA, "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test3iii_attributesFdnMissingSlashException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributefdn";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    //should be empty response
-    @Test
-    void test3iv_attributesFdnTypoColumm() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes/fnd";
-        String attributes = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, attributes, relationships);
-        Select<?> builtWithQM = (Select<?>) underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(
-                context);
-        Select<?> reference = (Select<?>) createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + ".id").as(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                        "id")), field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn"))
-                                .as(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")),
-                field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "dUpLMNId")).as(String
-                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "dUpLMNId")), field(String
-                                .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBDUId")).as(
-                                        String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                                                "gNBDUId")), field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                                        .format(QUOTED_STRING, "gNBId")).as(String.format(TIES_DATA,
-                                                                "GNBDUFunction") + "." + String.format(QUOTED_STRING,
-                                                                        "gNBId")), field(String.format(TIES_DATA,
-                                                                                "GNBDUFunction") + "." + String.format(
-                                                                                        QUOTED_STRING, "gNBIdLength")).as(
-                                                                                                String.format(TIES_DATA,
-                                                                                                        "GNBDUFunction") + "." + String
-                                                                                                                .format(QUOTED_STRING,
-                                                                                                                        "gNBIdLength")),
-                field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "cmId")).as(String
-                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "cmId"))).from(String
-                                .format(TIES_DATA, "GNBDUFunction")));
-
-        List<Field<?>> fieldsActual = builtWithQM.getSelect();
-        List<Field<?>> fieldsExpected = reference.getSelect();
-        Assertions.assertTrue(fieldsActual.containsAll(fieldsExpected));
-    }
-
-    @Test
-    void test3v_attributesFdnMissingOpeningBracketException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributefdn)";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test3vi_attributesFdnMissingClosingBracketException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attribute(fdn";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test4i_attributesFdnIdGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes(fdn)";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")), field(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(
-                                                TIES_DATA, "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test4ii_attributesFdnIdGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attributes/fdn";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "fdn")), field(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(
-                                                TIES_DATA, "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test4iii_attributesFdnIdMissingCommaException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attribute(fdn id)";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test4iv_attributesFdnIdMissingSemiColonException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attribute/fdn /attribute/id";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test4v_attributesFdnIdMissingSecondSlashException() {
-        String entityType = "GNBDUFunction";
-        String fields = "/attribute/fdn; attribute/id";
-        String filter = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test5i_attributesContainsGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String attributes = "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, fields, attributes, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).where(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                        .format(QUOTED_STRING, "fdn")).contains("/SubNetwork=Ireland/")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = { "/attributescontains (@fdn, \"/SubNetwork=Ireland/\")]",
-            "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\")",
-            "/attributes[contains (fdn, \"/SubNetwork=Ireland/\")]",
-            "/attributes[contans (@fdn, \"/SubNetwork=Ireland/\")]",
-            "/attributes[contains @fdn, \"/SubNetwork=Ireland/\")]",
-            "/attributes[contains (@fdn, \"/SubNetwork=Ireland/\"]",
-            "/attributes[contains (@fdn \"/SubNetwork=Ireland/\")]", "/attributes[contains (@fdn, /SubNetwork=Ireland/\")]",
-            "/attributes[contains (@fdn, \"/SubNetwork=Ireland/)]" })
-    void test5ii_ix_attributesException(String scope) {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test5x_attributesColumnTypoEmptyList() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[contains (@fnd, \"/SubNetwork=Ireland/\")]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test5xi_attributesContainsWrongValueEmptyList() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[contains (@fdn, \"/SubNetwork Ireland/\")]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).where(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                        .format(QUOTED_STRING, "fdn")).contains("/SubNetwork Ireland/")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test6i_attributesEqualsGood() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[@gNBIdLength=3]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).where(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                        .format(QUOTED_STRING, "gNBIdLength")).eq(3)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test6iii_attributesMissingEquationSignException() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[@gNBIdLength 3]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test7i_attributesEqualsGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String attributes = "/attributes[@gNBIdLength=3 and @gNBId=111]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, fields, attributes, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).where((field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                        .format(QUOTED_STRING, "gNBIdLength")).eq(3)).and(field(String.format(TIES_DATA,
-                                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBId")).eq(111))));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test7iii_attributesMissingAndException() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String filter = "/attributes[@gNBIdLength=3  @gNBId=-1]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test7iv_attributesTypoAndException() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String filter = "/attributes[@gNBIdLength=3 adn @gNBId=111]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test8i_attributesEqualBarEqualGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String attributes = "/attributes[@gNBIdLength=3 and @gNBId=111] | /attributes[@gNBIdLength=3 and @gNBId=112]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, fields, attributes, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).where(((field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                        .format(QUOTED_STRING, "gNBIdLength")).eq(3)).and(field(String.format(TIES_DATA,
-                                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "gNBId")).eq(111)))
-                                                        .or((field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                                                                .format(QUOTED_STRING, "gNBIdLength")).eq(3)).and(field(
-                                                                        String.format(TIES_DATA,
-                                                                                "GNBDUFunction") + "." + String.format(
-                                                                                        QUOTED_STRING, "gNBId")).eq(
-                                                                                                112)))));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test8ii_attributesEqualBarEqualMissingBarException() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String filter = "/attributes[@gNBIdLength=3 and @gNBId=111]  /attributes[@gNBIdLength=3 and @gNBId=112]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test9i_attributesContainEqualGood() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String attributes = "/attributes[contains (@fdn, \"SubNetwork=Ireland\")] ; /attributes[@gNBIdLength=3]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, fields, attributes, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test9ii_attributesMissingSemiColonException() {
-        String entityType = "GNBDUFunction";
-        String fields = "";
-        String filter = "/attributes[contains (@fdn, \"SubNetwork=Ireland\")]  /attributes[@gNBIdLength=3]";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, fields, filter, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test10i_targetGood() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCellDU";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("NRCellDU")
-                .getField("id", null, null).getType()).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(
-                                TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                        "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id")).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(TIES_DATA,
-                                        "NRCellDU")).on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String
-                                                .format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String
-                                                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                QUOTED_STRING, "id"))))).where(joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test10ii_targetTypoGood() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCelldu";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test11i_targetHopsGood() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCellDU ; /NRSectorCarrier";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull()).and(field(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(
-                        QUOTED_STRING, "id")).isNotNull());
-        // spotless:off
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("NRCellDU").getField("id",null,null).getType()).as(String.format(
-                TIES_DATA,
-                "NRCellDU") + "." + String.format(QUOTED_STRING, "id")), field("null").cast(getEntityTypeByName("NRSectorCarrier").getField("id",null,null).getType()).as(String.format(
-                TIES_DATA,
-                "NRSectorCarrier") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                "GNBDUFunction")).
-                leftJoin(String.format(TIES_DATA, "NRCellDU")).on(condition(field(String
-                .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-            .leftJoin(String.format(TIES_DATA, "NRSectorCarrier")).on(condition(field(String.format(TIES_DATA,
-                "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))).where(joinFilter)
-            .union(context.select(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                    "id")).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING, "id")), field(
-                    "null").cast(getEntityTypeByName("NRSectorCarrier").getField("id",null,null).getType()).as(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                    "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).
-                    leftJoin(String.format(TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                    "NRCellDU") + "." + String.format(QUOTED_STRING,
-                    "REL_FK_provided-by-gnbduFunction")).eq(field(String
-                    .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))).
-                    leftJoin(String.format(TIES_DATA, "NRSectorCarrier")).on(condition(field(String.format(TIES_DATA,
-                    "NRSectorCarrier") + "." + String.format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(
-                    String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter)).union(context.select(field("null").cast(getEntityTypeByName("NRCellDU").getField("id",null,null).getType()).as(String.format(
-                    TIES_DATA,
-                    "NRCellDU") + "." + String.format(QUOTED_STRING, "id")), field(String.format(TIES_DATA,
-                    "NRSectorCarrier") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(QUOTED_STRING, "id")))
-                .from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(TIES_DATA,
-                    "NRCellDU")).on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String
-                    .format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction")
-                    + "." + String.format(QUOTED_STRING, "id"))))).leftJoin(String.format(TIES_DATA,
-                    "NRSectorCarrier")).on(condition(field(String.format(TIES_DATA,
-                    "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                    "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." +
-                    String.format(QUOTED_STRING, "id"))))).where(joinFilter)));
-        // spotless:on
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test11ii_targetHopTypo() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCellDU ; /NRSectorCarier";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("NRCellDU")
-                .getField("id", null, null).getType()).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(
-                                TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                        "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id")).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(TIES_DATA,
-                                        "NRCellDU")).on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String
-                                                .format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String
-                                                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                QUOTED_STRING, "id"))))).where(joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test12i_TargetGoodWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU";
-        String target = "";
-        String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Condition relationFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).isNotNull()).and(field(String.format(TIES_DATA,
-                        "NRCellDU") + "." + String.format(QUOTED_STRING, "id")).isNotNull()).and(field(String.format(
-                                TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String.format(
-                                        TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))
-                .where(relationFilter).and(joinFilter).union(context.select(field("null").cast(getEntityTypeByName(
-                        "GNBDUFunction").getField("id", null, null).getType()).as(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                        "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String
-                                                .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(
-                                                                TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                        QUOTED_STRING, "id")))).where(relationFilter).and(
-                                                                                joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test12ii_relationshipWrongException() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCellDU";
-        String scope = "";
-        String relationships = "USES";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Invalid relationship name");
-    }
-
-    @Test
-    void test13i_RelationshipsGoodWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU | /CloudNativeApplication";
-        String target = "";
-        String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU, GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull()).and(field(String.format(TIES_DATA, "CloudNativeApplication") + "." + String.format(
-                        QUOTED_STRING, "id")).isNotNull());
-
-        Condition relationFilter1 = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).isNotNull()).and(field(String.format(TIES_DATA,
-                        "NRCellDU") + "." + String.format(QUOTED_STRING, "id")).isNotNull()).and(field(String.format(
-                                TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU")).isNotNull());
-
-        Condition relationFilter2 = condition(field(String.format(TIES_DATA,
-                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(QUOTED_STRING,
-                        "aSide_GNBDUFunction")).isNotNull()).and(field(String.format(TIES_DATA,
-                                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(QUOTED_STRING,
-                                        "bSide_CloudNativeApplication")).isNotNull()).and(field(String.format(TIES_DATA,
-                                                "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(
-                                                        QUOTED_STRING, "id")).isNotNull());
-
-        // spotless:off
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction"))
-                .eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))).
-                join(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"))
-            .on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String
-                .format(QUOTED_STRING, "aSide_GNBDUFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." +
-                String.format(QUOTED_STRING, "id")))).leftJoin(String.format(TIES_DATA, "CloudNativeApplication"))
-            .on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(
-                QUOTED_STRING, "bSide_CloudNativeApplication")).eq(field(String.format(TIES_DATA, "CloudNativeApplication") + "." + String.format(QUOTED_STRING, "id"))))
-
-            .where(relationFilter1).and(relationFilter2).and(joinFilter).union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField("id",null,null).getType()).as(String
-                    .format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).
-                    leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String.format(TIES_DATA,
-                    "NRCellDU") + "." + String.format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))
-                .join(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"))
-                .on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." +
-                    String.format(QUOTED_STRING, "aSide_GNBDUFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                    .format(QUOTED_STRING, "id")))).leftJoin(String.format(TIES_DATA,
-                    "CloudNativeApplication"))
-                .on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String
-                    .format(QUOTED_STRING, "bSide_CloudNativeApplication")).eq(field(String.format(TIES_DATA,
-                    "CloudNativeApplication") + "." + String
-                    .format(QUOTED_STRING, "id"))))
-
-                .where(relationFilter1).and(relationFilter2).and(joinFilter)).union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField("id",null,null).getType()).as(String.format(
-                    TIES_DATA, "GNBDUFunction") +
-                    "." + String.format(QUOTED_STRING, "id")))
-                .from(String.format(TIES_DATA, "GNBDUFunction"))
-                .leftJoin(String.format(TIES_DATA, "NRCellDU")).
-                    on(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction"))
-                    .eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))
-                .join(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION"))
-                .on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String.format(QUOTED_STRING, "aSide_GNBDUFunction"))
-                    .eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))
-                .leftJoin(String.format(TIES_DATA, "CloudNativeApplication")).on(field(String.format(TIES_DATA, "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION") + "." + String
-                    .format(QUOTED_STRING, "bSide_CloudNativeApplication"))
-                    .eq(field(String.format(TIES_DATA, "CloudNativeApplication") + "." + String.format(QUOTED_STRING, "id"))))
-                .where(relationFilter1).and(relationFilter2).and(joinFilter)));
-        // spotless:on
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test13ii_RelationshipsOnlyOneGoodWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU | /CloudNativeApplication";
-        String target = "";
-        String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-        Condition relationFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).isNotNull()).and(field(String.format(TIES_DATA,
-                        "NRCellDU") + "." + String.format(QUOTED_STRING, "id")).isNotNull()).and(field(String.format(
-                                TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String.format(
-                                        TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))))
-                .where(relationFilter).and(joinFilter).union(context.select(field("null").cast(getEntityTypeByName(
-                        "GNBDUFunction").getField("id", null, null).getType()).as(String.format(TIES_DATA,
-                                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                        "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(field(String
-                                                .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(
-                                                                TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                        QUOTED_STRING, "id")))).where(relationFilter).and(
-                                                                                joinFilter)).union(context.select(field(
-                                                                                        "null").cast(getEntityTypeByName(
-                                                                                                "GNBDUFunction").getField(
-                                                                                                        "id", null, null)
-                                                                                                        .getType()).as(
-                                                                                                                String.format(
-                                                                                                                        TIES_DATA,
-                                                                                                                        "GNBDUFunction") + "." + String
-                                                                                                                                .format(QUOTED_STRING,
-                                                                                                                                        "id")))
-                                                                                        .from(String.format(TIES_DATA,
-                                                                                                "GNBDUFunction")).leftJoin(
-                                                                                                        String.format(
-                                                                                                                TIES_DATA,
-                                                                                                                "NRCellDU"))
-                                                                                        .on(field(String.format(TIES_DATA,
-                                                                                                "NRCellDU") + "." + String
-                                                                                                        .format(QUOTED_STRING,
-                                                                                                                "REL_FK_provided-by-gnbduFunction"))
-                                                                                                                        .eq(field(
-                                                                                                                                String.format(
-                                                                                                                                        TIES_DATA,
-                                                                                                                                        "GNBDUFunction") + "." + String
-                                                                                                                                                .format(QUOTED_STRING,
-                                                                                                                                                        "id"))))
-                                                                                        .where(relationFilter).and(
-                                                                                                joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test13iii_RelationshipsInvalidWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU | /CloudNativeApplication";
-        String target = "";
-        String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU_2";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Invalid relationship name");
-    }
-
-    @Test
-    void test13iv_RelationshipsInvalidWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU | /CloudNativeApplication";
-        String target = "";
-        String relationships = "GNBDUFUNCTION_PROVIDES_NRCELLDU GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Invalid relationship name");
-    }
-
-    @Test
-    void test14i_ScopeGoodWithHop() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(condition(field(String
-                                        .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField(
-                        "id", null, null).getType()).as(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String
-                                        .format(TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                                "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(
-                                                                TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                        QUOTED_STRING, "id"))))).where(joinFilter)));
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test14ii_ScopeInvalidWithHop() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRCellDU_2";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test14iii_ScopeInvalidWithHop() {
-        String entityType = "GNBDUFunction";
-        String scope = "/AntennaCapability";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test15i_FilterOrGoodWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/NRSectorCarrier | /NRCellDU";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(
-                QUOTED_STRING, "id")).isNotNull()).and(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id")).isNotNull());
-        // spotless:off
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))
-            .from(String.format(TIES_DATA, "GNBDUFunction"))
-            .leftJoin(String.format(TIES_DATA, "NRSectorCarrier"))
-            .on(condition(field(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." +
-                String.format(QUOTED_STRING, "id")))))
-            .leftJoin(String.format(TIES_DATA, "NRCellDU"))
-            .on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-            .where(joinFilter)
-            .union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField("id",null,null).getType()).as(String.format(
-                    TIES_DATA, "GNBDUFunction") + "." +
-                    String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction"))
-                .leftJoin(String.format(TIES_DATA, "NRSectorCarrier"))
-                .on(condition(field(String.format(TIES_DATA, "NRSectorCarrier") + "." + String.format(
-                    QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .leftJoin(String.format(TIES_DATA, "NRCellDU"))
-                .on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                    "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") +
-                    "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter))
-            .union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField("id",null,null).getType()).as(String.format(
-                    TIES_DATA, "GNBDUFunction") + "." +
-                    String.format(QUOTED_STRING, "id")))
-                .from(String.format(TIES_DATA, "GNBDUFunction"))
-                .leftJoin(String.format(TIES_DATA, "NRSectorCarrier"))
-                .on(condition(field(String.format(TIES_DATA, "NRSectorCarrier") + "." +
-                    String.format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(
-                    String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .leftJoin(String.format(TIES_DATA, "NRCellDU"))
-                .on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                    "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA, "GNBDUFunction") + "." + String
-                    .format(QUOTED_STRING, "id")))))
-                .where(joinFilter)));
-        // spotless:on
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test15ii_ScopeOrOneGoodWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/AntennaCapability | /NRCellDU";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(condition(field(String
-                                        .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField(
-                        "id", null, null).getType()).as(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String
-                                        .format(TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                                "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(
-                                                                TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                        QUOTED_STRING, "id"))))).where(joinFilter)));
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test15iii_ScopeTypoWithHops() {
-        String entityType = "GNBDUFunction";
-        String scope = "/AntennaCapability2 | /NRCellDU";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")).leftJoin(String.format(TIES_DATA, "NRCellDU")).on(condition(field(String
-                                        .format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field("null").cast(getEntityTypeByName("GNBDUFunction").getField(
-                        "id", null, null).getType()).as(String.format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String
-                                        .format(TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                                "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(
-                                                                TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                        QUOTED_STRING, "id"))))).where(joinFilter)));
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = { "//attributes", "///attributes" })
-    void test16i_targetSlashes(String target) {
-        String entityType = "GNBDUFunction";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = { "//attributes", "///attributes" })
-    void test16i_scopeSlashes(String scope) {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @ParameterizedTest
-    @ValueSource(strings = { "/attributes[@gNBIdLength>3]", "/attributes[@gNBIdLength<3]" })
-    void test17i_scopeConditions(String scope) {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test18i_scopeOr() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attribute[@gNBIdLength=3 or @gNBIdLength=4]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test19i_targetWrongColumn() {
-        String entityType = "GNBDUFunction";
-        String target = "/attribute(gnbidLength)";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test19i_scopeWrongColumn() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attribute[@gnbiLength=3]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test20i_wrongTargetEntity() {
-        String entityType = "GNBDUFunction";
-        String target = "/AntennaCapability";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Objects are not related");
-    }
-
-    @Test
-    void test21_manyToOneTest() {
-        String entityType = "NRSectorCarrier";
-        String target = "/AntennaCapability";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "AntennaCapability") + "." + String.format(
-                QUOTED_STRING, "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("NRCellDU")
-                .getField("id", null, null).getType()).as(String.format(TIES_DATA, "AntennaCapability") + "." + String
-                        .format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "NRSectorCarrier")).leftJoin(String
-                                .format(TIES_DATA, "AntennaCapability")).on(condition(field(String.format(TIES_DATA,
-                                        "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_used-antennaCapability")).eq(field(String.format(TIES_DATA,
-                                                        "AntennaCapability") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field(String.format(TIES_DATA, "AntennaCapability") + "." + String
-                        .format(QUOTED_STRING, "id")).as(String.format(TIES_DATA, "AntennaCapability") + "." + String
-                                .format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "NRSectorCarrier")).leftJoin(
-                                        String.format(TIES_DATA, "AntennaCapability")).on(condition(field(String.format(
-                                                TIES_DATA, "NRSectorCarrier") + "." + String.format(QUOTED_STRING,
-                                                        "REL_FK_used-antennaCapability")).eq(field(String.format(TIES_DATA,
-                                                                "AntennaCapability") + "." + String.format(QUOTED_STRING,
-                                                                        "id"))))).where(joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test22i_processTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/id/fdn";
-        String scope = "/attributes[@gNBId=3000696]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test22ii_processTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/fdn";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test22iii_processTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/dummyText/fdn";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test23i_processTargetAttribute() {
-        String entityType = "GNBDUFunction";
-        String target = "/id";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "GNBDUFunction")));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test23ii_processTargetAttribute() {
-        String entityType = "GNBDUFunction";
-        String target = "/NRCellDU/id";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-        Query builtWithQM = qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("NRCellDU")
-                .getField("id", null, null).getType()).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(
-                                TIES_DATA, "NRCellDU")).on(condition(field(String.format(TIES_DATA,
-                                        "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                                "REL_FK_provided-by-gnbduFunction")).eq(field(String.format(TIES_DATA,
-                                                        "GNBDUFunction") + "." + String.format(QUOTED_STRING, "id")))))
-                .where(joinFilter).union(context.select(field(String.format(TIES_DATA, "NRCellDU") + "." + String.format(
-                        QUOTED_STRING, "id")).as(String.format(TIES_DATA, "NRCellDU") + "." + String.format(QUOTED_STRING,
-                                "id"))).from(String.format(TIES_DATA, "GNBDUFunction")).leftJoin(String.format(TIES_DATA,
-                                        "NRCellDU")).on(condition(field(String.format(TIES_DATA, "NRCellDU") + "." + String
-                                                .format(QUOTED_STRING, "REL_FK_provided-by-gnbduFunction")).eq(field(String
-                                                        .format(TIES_DATA, "GNBDUFunction") + "." + String.format(
-                                                                QUOTED_STRING, "id"))))).where(joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test24i_addTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/id(fdn)";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test24ii_addTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/attributes(id)";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test24iii_addTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/attributes(notExistingColumn)";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test24iiii_addTargetAttributeError() {
-        String entityType = "GNBDUFunction";
-        String target = "/attr(fdn)";
-        String scope = "";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test25_checkIdAttributesError() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attr[@fdn=\"Solar\"]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test26i_checkIdExpressionsError() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[@id=\"123\"]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test26ii_checkIdExpressionsError() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/id[@gNBId=12]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test26iii_checkIdExpressionsError() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/id[contains (@fdn,\"12\")]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test26iiii_checkIdExpressionsError() {
-        String entityType = "GNBDUFunction";
-        String target = "";
-        String scope = "/attributes[contains (@id,\"987\")]";
-        String relationships = "";
-
-        QueryMonad qm = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test27i_getTopologyByTargetFilterError() {
-        String entityType = null;
-        String target = "/CloudSite/attributes/";
-        String scope = "";
-        String relationships = "";
-        String domain = "RAN_LOGICAL";
-
-        QueryMonad qm = getQueryMonadWithDomain(entityType, target, scope, relationships, domain);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test27ii_getTopologyByTargetFilterError() {
-        String entityType = null;
-        String target = "/attributes";
-        String scope = "";
-        String relationships = "SECTOR_GROUPS_ANTENNAMODULE";
-        String domain = "RAN";
-
-        QueryMonad qm = getQueryMonadWithDomain(entityType, target, scope, relationships, domain);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Objects are not related");
-    }
-
-    @Test
-    void test27iii_getTopologyByTargetFilterError() {
-        String entityType = null;
-        String target = "/NRCellDU";
-        String scope = "";
-        String relationships = "SECTOR_GROUPS_ANTENNAMODULE";
-        String domain = "RAN";
-
-        QueryMonad qm = getQueryMonadWithDomain(entityType, target, scope, relationships, domain);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Objects are not related");
-    }
-
-    @Test
-    void test27iiii_getTopologyByTargetFilterError() {
-        String entityType = null;
-        String target = "/attributes/name";
-        String scope = "";
-        String relationships = "";
-        String domain = "RAN";
-
-        QueryMonad qm = getQueryMonadWithDomain(entityType, target, scope, relationships, domain);
-
-        assertThatThrownBy(() -> qm.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar error");
-    }
-
-    @Test
-    void test27iiiii_getTopologyByTargetFilterError() {
-        String entityType = "CloudNativeApplication";
-        String target1 = "/attributes/id";
-        String target2 = "/attributes(id)";
-        String scope = "";
-        String relationships = "";
-        String domain = "RAN_LOGICAL";
-
-        QueryMonad qm1 = getQueryMonadWithDomain(entityType, target1, scope, relationships, domain);
-        QueryMonad qm2 = getQueryMonadWithDomain(entityType, target2, scope, relationships, domain);
-
-        assertThatThrownBy(() -> qm1.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-
-        assertThatThrownBy(() -> qm2.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Grammar Error");
-    }
-
-    @Test
-    void test28i_getTopologyByTargetFilter() {
-        String entityType = null;
-        String target = "/Sector/id";
-        String scope = "";
-        String relationships = "";
-        String domain = "EQUIPMENT_TO_RAN";
-
-        QueryMonad underTest = getQueryMonadWithDomain(entityType, target, scope, relationships, domain);
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Query reference = createDistinctQuery(context, context.select(field("null").cast(getEntityTypeByName("Sector")
-                .getField("id", null, null).getType()).as(String.format(TIES_DATA, "Sector") + "." + String.format(
-                        QUOTED_STRING, "id"))).from("(SELECT '') as dual_table").leftJoin(String.format(TIES_DATA,
-                                "Sector")).on(condition(field(String.format(TIES_DATA, "Sector") + "." + "id").eq(field(
-                                        "(SELECT '')")))).where(field(String.format(TIES_DATA, "Sector") + "." + String
-                                                .format(QUOTED_STRING, "id")).isNotNull()).union(context.select(field(String
-                                                        .format(TIES_DATA, "Sector") + "." + String.format(QUOTED_STRING,
-                                                                "id")).as(String.format(TIES_DATA, "Sector") + "." + String
-                                                                        .format(QUOTED_STRING, "id"))).from(
-                                                                                "(SELECT '') as dual_table").rightJoin(
-                                                                                        String.format(TIES_DATA, "Sector"))
-                                                        .on(condition(field(String.format(TIES_DATA, "Sector") + "." + "id")
-                                                                .eq(field("(SELECT '')")))).where(field(String.format(
-                                                                        TIES_DATA, "Sector") + "." + String.format(
-                                                                                QUOTED_STRING, "id")).isNotNull()))
-
-        );
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test50_relConnectingSameEntityTest() {
-        String entityType = "AntennaModule";
-        String target = "/AntennaModule";
-        String scope = "";
-        String relationships = "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-
-        Query builtWithQM = underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context);
-
-        Condition joinFilter = condition(field(String.format(TIES_DATA, "AntennaModule") + "." + String.format(
-                QUOTED_STRING, "id")).isNotNull());
-
-        Condition relationFilter = condition(field(String.format(TIES_DATA,
-                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String.format(QUOTED_STRING, "aSide_AntennaModule"))
-                        .isNotNull()).and(field(String.format(TIES_DATA,
-                                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String.format(QUOTED_STRING,
-                                        "bSide_AntennaModule")).isNotNull()).and(field(String.format(TIES_DATA,
-                                                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String.format(
-                                                        QUOTED_STRING, "id")).isNotNull());
-
-        Query reference = createDistinctQuery(context, context.select(field(String.format(TIES_DATA,
-                "AntennaModule") + "." + String.format(QUOTED_STRING, "id")).as(String.format(TIES_DATA,
-                        "AntennaModule") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                "AntennaModule")).join(String.format(TIES_DATA, "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE"))
-                .on(field(String.format(TIES_DATA, "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String.format(
-                        QUOTED_STRING, "bSide_AntennaModule")).eq(field(String.format(TIES_DATA,
-                                "AntennaModule") + "." + String.format(QUOTED_STRING, "id")))).or(field(String.format(
-                                        TIES_DATA, "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String.format(
-                                                QUOTED_STRING, "aSide_AntennaModule")).eq(field(String.format(TIES_DATA,
-                                                        "AntennaModule") + "." + String.format(QUOTED_STRING, "id"))))
-                .where(relationFilter).and(joinFilter).union(context.select(field("null").cast(getEntityTypeByName(
-                        "AntennaModule").getField("id", null, null).getType()).as(String.format(TIES_DATA,
-                                "AntennaModule") + "." + String.format(QUOTED_STRING, "id"))).from(String.format(TIES_DATA,
-                                        "AntennaModule")).join(String.format(TIES_DATA,
-                                                "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE")).on(field(String.format(
-                                                        TIES_DATA, "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String
-                                                                .format(QUOTED_STRING, "bSide_AntennaModule")).eq(field(
-                                                                        String.format(TIES_DATA,
-                                                                                "AntennaModule") + "." + String.format(
-                                                                                        QUOTED_STRING, "id")))).or(field(
-                                                                                                String.format(TIES_DATA,
-                                                                                                        "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE") + "." + String
-                                                                                                                .format(QUOTED_STRING,
-                                                                                                                        "aSide_AntennaModule"))
-                                                                                                                                .eq(field(
-                                                                                                                                        String.format(
-                                                                                                                                                TIES_DATA,
-                                                                                                                                                "AntennaModule") + "." + String
-                                                                                                                                                        .format(QUOTED_STRING,
-                                                                                                                                                                "id"))))
-                        .where(relationFilter).and(joinFilter)));
-
-        Assertions.assertEquals(reference, builtWithQM);
-    }
-
-    @Test
-    void test50_relConnectingSameEntityTest_unrelatedEntities() {
-        String entityType = "AntennaModule";
-        String target = "/AntennaModule";
-        String scope = "";
-        String relationships = "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION";
-
-        QueryMonad underTest = getQueryMonad(entityType, target, scope, relationships);
-
-        assertThatThrownBy(() -> underTest.withSchema(PaginationDTO.builder().offset(0).limit(5).build()).apply(context))
-                .isInstanceOf(TiesPathException.class).hasMessage("Objects are not related");
-    }
-
-}
diff --git a/teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTestUtil.java b/teiv/src/test/java/org/oran/smo/teiv/utils/query/QueryMonadTestUtil.java
deleted file mode 100644 (file)
index a8c02ec..0000000
+++ /dev/null
@@ -1,46 +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 org.oran.smo.teiv.utils.query;
-
-import org.jooq.DSLContext;
-import org.jooq.Query;
-import org.jooq.Select;
-
-import static org.jooq.impl.DSL.asterisk;
-import static org.jooq.impl.DSL.one;
-
-public class QueryMonadTestUtil {
-    public static QueryMonad getQueryMonad(String entityType, String fields, String attributes, String relationships) {
-        return QueryMonad.builder().managedObject(entityType).targets(fields).scope(attributes).relationships(relationships)
-                .build();
-    }
-
-    public static Query createDistinctQuery(DSLContext context, Select query) {
-        return context.selectDistinct(asterisk()).from(query.asTable("TiesPathQuery")).orderBy(one().asc()).limit(0, 5);
-    }
-
-    public static QueryMonad getQueryMonadWithDomain(String entityType, String fields, String attributes,
-            String relationships, String domain) {
-        return QueryMonad.builder().managedObject(entityType).targets(fields).scope(attributes).relationships(relationships)
-                .domain(domain).build();
-    }
-
-}
index ad17d91..a1f8f94 100644 (file)
@@ -60,6 +60,8 @@ spring.datasource.read.maximum-pool-size: 2
 spring.datasource.write.maximum-pool-size: 2
 spring.caching.consumer-data-ttl-ms: 60000
 
+consumer-data.batch-size: 50
+
 kafka:
   server:
     bootstrap-server-host: kafka
@@ -74,12 +76,13 @@ kafka:
     retry-attempts: 3
     retry-interval-ms: 1000
   topology-ingestion:
+    topic:
+      name: topology-inventory-ingestion
+      partitions: 4
+      replicas: 1
+      retention-ms: 7200000
+      retention-bytes: 104857600
     consumer:
-      topic:
-        name: topology-inventory-ingestion
-        partitions: 4
-        replicas: 1
-        retention-ms: 86400000
       group-id: topology-inventory-ingestion-consumer
       auto-offset-reset: earliest
       max-poll-records: 500
@@ -94,7 +97,4 @@ database:
   retry-policies:
     deadlock:
       retry-attempts: 3
-      retry-backoff-ms: 200
-
-feature_flags:
-  use_alternate_delete_logic: false
\ No newline at end of file
+      retry-backoff-ms: 200
\ No newline at end of file
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-arrays.json b/teiv/src/test/resources/cloudeventdata/common/ce-arrays.json
new file mode 100644 (file)
index 0000000..de0237f
--- /dev/null
@@ -0,0 +1,53 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:AntennaCapability": [
+                    {
+                        "id": "entityId_0",
+                        "attributes": {
+                            "eUtranFqBands": [
+                                "a",
+                                "b",
+                                "c"
+                            ]
+                        }
+                    },
+                    {
+                        "id": "entityId_1",
+                        "attributes": {
+                            "eUtranFqBands": [
+                                "a",
+                                "b"
+                            ]
+                        }
+                    },
+                    {
+                        "id": "entityId_2",
+                        "attributes": {
+                            "geranFqBands": [
+                                "a"
+                            ]
+                        }
+                    },
+                    {
+                        "id": "entityId_3",
+                        "attributes": {
+                            "eUtranFqBands": [
+                                "q"
+                            ],
+                            "nRFqBands": []
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-data-only.json b/teiv/src/test/resources/cloudeventdata/common/ce-data-only.json
deleted file mode 100644 (file)
index a02d18f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-{
-    "entities": [
-        {
-            "o-ran-smo-teiv-ran:NRCellDU": [
-                {
-                    "id": "entityId_1",
-                    "attributes": {
-                        "cellLocalId": 4589,
-                        "nRPCI": 12,
-                        "nRTAC": 310,
-                        "primitiveArray": [
-                            1,
-                            2,
-                            3
-                        ],
-                        "singleList": [
-                            "12"
-                        ],
-                        "jsonObjectArray": [
-                            {
-                                "test1": "128",
-                                "test2": "49"
-                            },
-                            {
-                                "test1": "129",
-                                "test2": "50"
-                            }
-                        ]
-                    }
-                },
-                {
-                    "id": "entityId_3",
-                    "attributes": {
-                        "cellLocalId": 45891,
-                        "nRPCI": 121,
-                        "nRTAC": 3101,
-                        "primitiveArray": [
-                            1,
-                            2,
-                            3
-                        ],
-                        "singleList": [
-                            "121"
-                        ],
-                        "jsonObjectArray": [
-                            {
-                                "test1": "1281",
-                                "test2": "491"
-                            },
-                            {
-                                "test1": "1291",
-                                "test2": "501"
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "o-ran-smo-teiv-ran:NRSectorCarrier": [
-                {
-                    "id": "entityId_2",
-                    "attributes": {
-                        "arfcnDL": 4590,
-                        "testDouble": 32.5,
-                        "testBoolean": true,
-                        "cmId": {
-                            "option1": "test_option1",
-                            "option2": "test_option2"
-                        }
-                    }
-                }
-            ]
-        }
-    ],
-    "relationships": [
-        {
-            "o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER": [
-                {
-                    "id": "relationshipId",
-                    "aSide": "entityId_1",
-                    "bSide": "entityId_2"
-                },
-                {
-                    "id": "relationshipId2",
-                    "aSide": "entityId_3",
-                    "bSide": "entityId_4"
-                }
-            ],
-            "o-ran-smo-teiv-ran:GNBDUFunctionRealisedByCloudNativeApplication": [
-                {
-                    "id": "relationshipId3",
-                    "aSide": "entityId_5",
-                    "bSide": "entityId_6"
-                },
-                {
-                    "id": "relationshipId4",
-                    "aSide": "entityId_5",
-                    "bSide": "entityId_7"
-                }
-            ]
-        }
-    ]
-}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-invalid-entity-attribute.json b/teiv/src/test/resources/cloudeventdata/common/ce-invalid-entity-attribute.json
new file mode 100644 (file)
index 0000000..b5a6593
--- /dev/null
@@ -0,0 +1,24 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                    {
+                        "id": "id1",
+                        "attributes": {
+                            "gNBId": -1.0
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": []
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module-type-pair.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module-type-pair.json
new file mode 100644 (file)
index 0000000..86042ea
--- /dev/null
@@ -0,0 +1,28 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRCELLDU_USES_NRSECTORCARRIER": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-module.json
new file mode 100644 (file)
index 0000000..7ff15ea
--- /dev/null
@@ -0,0 +1,28 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-type.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-invalid-type.json
new file mode 100644 (file)
index 0000000..a23cf1c
--- /dev/null
@@ -0,0 +1,28 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORSES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-a-side.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-a-side.json
new file mode 100644 (file)
index 0000000..a51d004
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-b-side.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-b-side.json
new file mode 100644 (file)
index 0000000..aa53179
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-both-sides.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-both-sides.json
new file mode 100644 (file)
index 0000000..5e5eae1
--- /dev/null
@@ -0,0 +1,26 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "relation_3"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-id.json b/teiv/src/test/resources/cloudeventdata/common/ce-relationship-missing-id.json
new file mode 100644 (file)
index 0000000..ceba2c1
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    },
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
index ef26639..73821da 100644 (file)
                 "o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER": [
                     {
                         "id": "relationshipId",
-                        "aSide": "entityId_1",
+                        "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR004,ManagedElement=me04,GNBDUFunction=gnbdu04,NRCellDU=NR-Cell-07",
                         "bSide": "entityId_2"
                     },
                     {
                         "id": "relationshipId2",
                         "aSide": "entityId_3",
-                        "bSide": "entityId_4"
+                        "bSide": "entityId_4",
+                        "sourceIds": [
+                            "source10",
+                            "source20"
+                        ]
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFunctionRealisedByCloudNativeApplication": [
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
                     {
-                        "id": "relationshipId3",
+                        "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=89FE9A4ED8451D779865C389900E247B13E360B0A4175EBA80AA9B384BFA4C688F17865AFD934085B0235BCA66128F2E6D4CE6953EAAB2EDEBD94B3683C1A064",
                         "aSide": "entityId_5",
-                        "bSide": "entityId_6"
+                        "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR004,ManagedElement=me04,GNBDUFunction=gnbdu04,NRCellDU=NR-Cell-07"
                     },
                     {
                         "id": "relationshipId4",
                         "aSide": "entityId_5",
-                        "bSide": "entityId_7"
+                        "bSide": "entityId_3",
+                        "sourceIds": [
+                            "source21"
+                        ]
                     }
                 ]
             }
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids.json b/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids.json
new file mode 100644 (file)
index 0000000..2d3a410
--- /dev/null
@@ -0,0 +1,75 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:NRCellDU": [
+                    {
+                        "id": "entityId_1",
+                        "attributes": {
+                            "cellLocalId": 4589,
+                            "nRPCI": 12,
+                            "nRTAC": 310,
+                            "primitiveArray": [
+                                1,
+                                2,
+                                3
+                            ],
+                            "singleList": [
+                                "12"
+                            ],
+                            "jsonObjectArray": [
+                                {
+                                    "test1": "128",
+                                    "test2": "49"
+                                },
+                                {
+                                    "test1": "129",
+                                    "test2": "50"
+                                }
+                            ]
+                        },
+                        "sourceIds": [
+                            "source1",
+                            "source2"
+                        ]
+                    },
+                    {
+                        "id": "entityId_2",
+                        "attributes": {
+                            "nCI": 123,
+                            "nRTAC": 32
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                        "id": "invalid_relationshipId<3",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_5",
+                        "aSide": "entityId?5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_6",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId[1]"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids2.json b/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids2.json
new file mode 100644 (file)
index 0000000..0b0a0b4
--- /dev/null
@@ -0,0 +1,75 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:NRCellDU": [
+                    {
+                        "id": "entityId_1",
+                        "attributes": {
+                            "cellLocalId": 4589,
+                            "nRPCI": 12,
+                            "nRTAC": 310,
+                            "primitiveArray": [
+                                1,
+                                2,
+                                3
+                            ],
+                            "singleList": [
+                                "12"
+                            ],
+                            "jsonObjectArray": [
+                                {
+                                    "test1": "128",
+                                    "test2": "49"
+                                },
+                                {
+                                    "test1": "129",
+                                    "test2": "50"
+                                }
+                            ]
+                        },
+                        "sourceIds": [
+                            "source1",
+                            "source2"
+                        ]
+                    },
+                    {
+                        "id": "entityId_2",
+                        "attributes": {
+                            "nCI": 123,
+                            "nRTAC": 32
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                        "id": "relationshipId_3",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_5",
+                        "aSide": "invalid_entityId?5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_6",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids3.json b/teiv/src/test/resources/cloudeventdata/common/ce-with-invalid-relationship-ids3.json
new file mode 100644 (file)
index 0000000..13df9ff
--- /dev/null
@@ -0,0 +1,75 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:NRCellDU": [
+                    {
+                        "id": "entityId_1",
+                        "attributes": {
+                            "cellLocalId": 4589,
+                            "nRPCI": 12,
+                            "nRTAC": 310,
+                            "primitiveArray": [
+                                1,
+                                2,
+                                3
+                            ],
+                            "singleList": [
+                                "12"
+                            ],
+                            "jsonObjectArray": [
+                                {
+                                    "test1": "128",
+                                    "test2": "49"
+                                },
+                                {
+                                    "test1": "129",
+                                    "test2": "50"
+                                }
+                            ]
+                        },
+                        "sourceIds": [
+                            "source1",
+                            "source2"
+                        ]
+                    },
+                    {
+                        "id": "entityId_2",
+                        "attributes": {
+                            "nCI": 123,
+                            "nRTAC": 32
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                        "id": "relationshipId_3",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_5",
+                        "aSide": "entityId_5",
+                        "bSide": "entityId_1"
+                    },
+                    {
+                        "id": "relationshipId_6",
+                        "aSide": "entityId_5",
+                        "bSide": "invalid_entityId[1]"
+                    }
+                ]
+            }
+        ]
+    }
+}
index 834c647..a8eaaae 100644 (file)
@@ -9,9 +9,13 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-cloud:CloudSite": [
+                "o-ran-smo-teiv-ran-cloud:CloudSite": [
                     {
                         "id": "CloudSite1",
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ],
                         "attributes": {
                             "name": "geo-location1",
                             "geo-location": {
index 99507d6..64e35a4 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-cloud:CloudNativeApplication": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeApplication": [
                     {
                         "id": "CloudNativeApplication_1",
                         "attributes": {
@@ -31,7 +31,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBDUFunction": [
                     {
                         "id": "GNBDU_1",
                         "attributes": {
@@ -52,7 +52,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBCUUPFunction": [
                     {
                         "id": "GNBCUUP_1",
                         "attributes": {
@@ -68,7 +68,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBCUCPFunction": [
                     {
                         "id": "GNBCUCP_1",
                         "attributes": {
@@ -91,7 +91,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_1",
                         "aSide": "GNBDU_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_2",
                         "aSide": "GNBCUUP_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_3",
                         "aSide": "GNBCUCP_1",
index 2729d70..65fe5ed 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-cloud:NodeCluster": [
+                "o-ran-smo-teiv-ran-cloud:NodeCluster": [
                     {
                         "id": "NodeCluster_1",
                         "attributes": {
@@ -19,7 +19,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:AntennaCapability": [
+                "o-ran-smo-teiv-ran-logical:AntennaCapability": [
                     {
                         "id": "AntennaCapability_1",
                         "attributes": {
@@ -32,7 +32,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:NRSectorCarrier": [
+                "o-ran-smo-teiv-ran-logical:NRSectorCarrier": [
                     {
                         "id": "NRSectorCarrier_1",
                         "attributes": {
@@ -42,7 +42,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudSite": [
+                "o-ran-smo-teiv-ran-cloud:CloudSite": [
                     {
                         "id": "CloudSite_1",
                         "attributes": {
@@ -54,7 +54,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
+                "o-ran-smo-teiv-ran-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
                     {
                         "id": "relation_1",
                         "aSide": "NodeCluster_1",
@@ -63,7 +63,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
                     {
                         "id": "relation_10",
                         "aSide": "NRSectorCarrier_1",
index 2b8d3aa..ed4c895 100644 (file)
@@ -9,31 +9,37 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_1",
                         "attributes": {
 
                         },
-                        "sourceIds": []
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:ENodeBFunction": [
+                "o-ran-smo-teiv-ran-logical:ENodeBFunction": [
                     {
                         "id": "ENodeBFunction_1",
                         "attributes": {
 
                         },
-                        "sourceIds": []
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
                     }
                 ]
             }
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
                     {
                         "id": "relation_1",
                         "aSide": "ManagedElement_1",
index 4c4cdb1..defebbb 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_2",
                         "attributes": {
@@ -25,7 +25,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
                     {
                         "id": "CloudNativeSystem_2",
                         "attributes": {
@@ -43,7 +43,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
                     {
                         "id": "relation_11",
                         "aSide": "ManagedElement_2",
index a411b47..32d571f 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-equipment:AntennaModule": [
+                "o-ran-smo-teiv-ran-equipment:AntennaModule": [
                     {
                         "id": "AntennaModule_1",
                         "attributes": {
@@ -25,7 +25,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                "o-ran-smo-teiv-ran-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
                     {
                         "id": "AntennaModule_3",
                         "attributes": {
@@ -55,7 +55,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE": [
                     {
                         "id": "many_to_many_relation_1",
                         "aSide": "AntennaModule_1",
@@ -64,7 +64,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "one_to_many_relation_1",
                         "aSide": "AntennaModule_3",
@@ -73,7 +73,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "one_to_one_relation_1",
                         "aSide": "AntennaModule_5",
index fd427e6..09f4494 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-ran:CloudNativeApplication": [
+                "o-ran-smo-teiv-ran-logical:CloudNativeApplication": [
                     {
                         "id": "CNA_SED_1",
                         "attributes": {
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBDUFunction": [
                     {
                         "id": "GNBDU_SED_1",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
                         "attributes": {
                             "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
                             "dUpLMNId": {
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBCUCPFunction": [
                     {
                         "id": "GNBCUCP_SED_1",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
                         "attributes": {
                             "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
                             "gNBCUName": "Test_sed_gNBCU",
                     },
                     {
                         "id": "GNBCUCP_SED_2",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=2",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
                         "attributes": {
                             "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=2",
                             "gNBCUName": "Test_sed_gNBCU2",
@@ -80,7 +92,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_sed_1",
                         "aSide": "GNBDU_SED_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_sed_2",
                         "aSide": "GNBCUCP_SED_1",
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-managed-element.json b/teiv/src/test/resources/cloudeventdata/end-to-end/ce-delete-managed-element.json
new file mode 100644 (file)
index 0000000..8d460bb
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
index 8b5797b..de99897 100644 (file)
@@ -9,14 +9,14 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-ran:CloudNativeApplication": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeApplication": [
                     {
                         "id": "CloudNativeApplication_3"
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBCUCPFunction": [
                     {
                         "id": "GNBCUCP_1"
                     }
@@ -25,7 +25,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
                     {
                         "id": "relation_1"
                     }
index 6ba8fc8..ba43673 100644 (file)
@@ -9,14 +9,14 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-cloud:NodeCluster": [
+                "o-ran-smo-teiv-ran-cloud:NodeCluster": [
                     {
                         "id": "NodeCluster_1"
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudSite": [
+                "o-ran-smo-teiv-ran-cloud:CloudSite": [
                     {
                         "id": "CloudSite_1"
                     }
@@ -25,7 +25,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
+                "o-ran-smo-teiv-ran-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
                     {
                         "id": "relation_1"
                     }
index b3d93ee..3a0f983 100644 (file)
@@ -9,14 +9,14 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_1"
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:ENodeBFunction": [
+                "o-ran-smo-teiv-ran-logical:ENodeBFunction": [
                     {
                         "id": "ENodeBFunction_1"
                     }
@@ -25,7 +25,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-logical:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
                     {
                         "id": "relation_1"
                     }
index ccd5081..54ac71d 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_2"
                     }
@@ -18,7 +18,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
                     {
                         "id": "relation_12"
                     }
index e4844a0..9d481a4 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-equipment:AntennaModule": [
+                "o-ran-smo-teiv-ran-equipment:AntennaModule": [
                     {
                         "id": "AntennaModule_1"
                     },
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "one_to_many_relation_1"
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "one_to_one_relation_1"
                     }
index ee90fb1..0447e9d 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-cloud:Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                "o-ran-smo-teiv-ran-cloud:Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
                     {
                         "id": "Namespace_1",
                         "attributes": {
@@ -25,7 +25,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-oam:ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt": [
+                "o-ran-smo-teiv-ran-oam:ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt": [
                     {
                         "id": "ManagedElement_1",
                         "attributes": {
@@ -59,7 +59,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm": [
                     {
                         "id": "CloudNativeSystem_1",
                         "attributes": {
@@ -81,7 +81,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
                     {
                         "id": "CloudNativeApplication_1",
                         "attributes": {
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
+                "o-ran-smo-teiv-ran-logical:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
                     {
                         "id": "GNBDUFunction_1",
                         "attributes": {
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU": [
+                "o-ran-smo-teiv-ran-logical:NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU": [
                     {
                         "id": "NRCellDU_1",
                         "attributes": {
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                "o-ran-smo-teiv-ran-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
                     {
                         "id": "AntennaModule_1",
                         "attributes": {
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE": [
                     {
                         "id": "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE_relation_1",
                         "aSide": "CloudNativeApplication_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM": [
                     {
                         "id": "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_relation_1",
                         "aSide": "ManagedElement_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN": [
                     {
                         "id": "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_1",
                         "aSide": "ManagedElement_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-ran-to-cloud:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN": [
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN": [
                     {
                         "id": "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_1",
                         "aSide": "GNBDUFunction_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN": [
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN": [
                     {
                         "id": "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION_relation_1",
                         "aSide": "ManagedElement_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU": [
+                "o-ran-smo-teiv-ran-logical:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU": [
                     {
                         "id": "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_1",
                         "aSide": "GNBDUFunction_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_relation_1",
                         "aSide": "AntennaModule_1",
                 ]
             },
             {
-                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
                     {
                         "id": "ANTENNAMODULE_DEPLOYED_ON_ANTENNAMODULE_relation_1",
                         "aSide": "AntennaModule_5",
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/ce-merge-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/ce-merge-one-to-many.json
new file mode 100644 (file)
index 0000000..0ca2788
--- /dev/null
@@ -0,0 +1,101 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0002",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.merge",
+    "time": "2023-10-25T13:30:12Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:GNBDUFunction": [
+                    {
+                        "id": "GNBDU_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
+                            "dUpLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "gNBDUId": 12,
+                            "gNBId": 1234,
+                            "gNBIdLength": 4,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-logical:NRCellDU": [
+                    {
+                        "id": "NRCellDU_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
+                            "cellLocalId": 4589,
+                            "nCI": 1,
+                            "nRPCI": 12,
+                            "nRTAC": 310,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "NRCellDU_2",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
+                            "cellLocalId": 45891,
+                            "nCI": 2,
+                            "nRPCI": 121,
+                            "nRTAC": 3101,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "NRCellDU_3",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
+                            "cellLocalId": 469,
+                            "nCI": 3,
+                            "nRPCI": 15,
+                            "nRTAC": 301,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
+                            }
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                        "id": "relation_7",
+                        "aSide": "GNBDU_1",
+                        "bSide": "NRCellDU_1"
+                    },
+                    {
+                        "id": "relation_8",
+                        "aSide": "GNBDU_1",
+                        "bSide": "NRCellDU_2"
+                    },
+                    {
+                        "id": "relation_9",
+                        "aSide": "GNBDU_1",
+                        "bSide": "NRCellDU_3"
+                    }
+                ]
+            }
+        ]
+    }
+}
index 6032e29..df8a16c 100644 (file)
@@ -9,51 +9,55 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_1",
                         "attributes": {
 
                         },
-                        "sourceIds": []
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
                     },
                     {
                         "id": "ManagedElement_2",
                         "attributes": {
 
                         },
-                        "sourceIds": []
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
                     {
                         "id": "CloudNativeSystem_1",
                         "attributes": {
 
                         },
-                        "sourceIds": []
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
                     }
                 ]
             },
             {
-                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                "o-ran-smo-teiv-ran-logical:GNBDUFunction": [
                     {
                         "id": "GNBDU_1",
                         "attributes": {
-                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1",
                             "dUpLMNId": {
                                 "mcc": 110,
                                 "mnc": 210
                             },
                             "gNBDUId": 111,
                             "gNBId": 123,
-                            "gNBIdLength": 3,
-                            "cmId": {
-                                "cmHandle": "395221E080CCF0FD1924103B15873814",
-                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
-                            }
+                            "gNBIdLength": 3
                         },
                         "sourceIds": [
                             "urn:3gpp:dn:/SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR01gNodeBRadio00001/ManagedElement=NR01gNodeBRadio00001/GNBDUFunction=1",
@@ -65,7 +69,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
                     {
                         "id": "relation_1",
                         "aSide": "ManagedElement_1",
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-many.json
deleted file mode 100644 (file)
index fe79568..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_6": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_6\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_3": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_3\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_1": "{\"o-ran-smo-teiv-ran:GNBCUCPFunction\":[{\"id\":\"GNBCUCP_1\",\"sourceIds\":[],\"attributes\":{\"gNBIdLength\":3,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1\",\"pLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBCUName\":\"Test_gNBCU\",\"gNBId\":123}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_3": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_3\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_3\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_2": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_2\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_2\"}}]}",
-    "TEIV/entity-types/CloudNativeApplication/entities/CloudNativeApplication_1": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_1\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_1\"}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_4": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_4\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBDUFunction/entities/GNBDU_1": "{\"o-ran-smo-teiv-ran:GNBDUFunction\":[{\"id\":\"GNBDU_1\",\"sourceIds\":[],\"attributes\":{\"gNBIdLength\":3,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1\",\"dUpLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBDUId\":111,\"gNBId\":123}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_2": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_2\",\"sourceIds\":[]}]}",
-    "TEIV/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_1": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_1\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_5": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_5\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBCUUPFunction/entities/GNBCUUP_1": "{\"o-ran-smo-teiv-ran:GNBCUUPFunction\":[{\"id\":\"GNBCUUP_1\",\"sourceIds\":[],\"attributes\":{\"gNBId\":123,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1\",\"gNBIdLength\":3}}]}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-many-to-one.json
deleted file mode 100644 (file)
index 154a265..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "CLOUD/entity-types/NodeCluster/entities/NodeCluster_1": "{\"o-ran-smo-teiv-cloud:NodeCluster\":[{\"id\":\"NodeCluster_1\",\"sourceIds\":[],\"attributes\":{\"name\":null}}]}",
-    "CLOUD/entity-types/CloudSite/entities/CloudSite_1": "{\"o-ran-smo-teiv-cloud:CloudSite\":[{\"id\":\"CloudSite_1\",\"sourceIds\":[],\"attributes\":{\"geo-location\":null,\"name\":null}}]}",
-    "CLOUD/relationship-types/NODECLUSTER_LOCATED_AT_CLOUDSITE/relationships/relation_1": "{\"o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE\":[{\"bSide\":\"CloudSite_1\",\"aSide\":\"NodeCluster_1\",\"id\":\"relation_1\",\"sourceIds\":[]}]}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-one-to-many.json
deleted file mode 100644 (file)
index 55b15db..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "RAN/entity-types/ENodeBFunction/entities/ENodeBFunction_1": "{\"o-ran-smo-teiv-ran:ENodeBFunction\":[{\"id\":\"ENodeBFunction_1\",\"sourceIds\":[],\"attributes\":{\"eNodeBPlmnId\":null,\"fdn\":null,\"eNBId\":null,\"cmId\":null},\"id\":\"ENodeBFunction_1\"}]}",
-    "OAM_TO_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships/relation_1": "{\"o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION\":[{\"bSide\":\"ENodeBFunction_1\",\"aSide\":\"ManagedElement_1\",\"id\":\"relation_1\",\"sourceIds\":[\"fdn_1\",\"cmHandleId_1\"]}]}",
-    "OAM/entity-types/ManagedElement/entities/ManagedElement_1": "{\"o-ran-smo-teiv-oam:ManagedElement\":[{\"id\":\"ManagedElement_1\",\"sourceIds\":[],\"attributes\":{\"fdn\":null,\"cmId\":null}}]}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-relationship-connecting-same-entity.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-relationship-connecting-same-entity.json
deleted file mode 100644 (file)
index 08a8ef1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-    "EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships/many_to_many_relation_1": "{\"o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE\":[{\"bSide\":\"AntennaModule_2\",\"aSide\":\"AntennaModule_1\",\"id\":\"many_to_many_relation_1\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/relationship-types/ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE/relationships/one_to_many_relation_1": "{\"o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE\":[{\"bSide\":\"AntennaModule_4\",\"aSide\":\"AntennaModule_3\",\"id\":\"one_to_many_relation_1\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/relationship-types/ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE/relationships/one_to_one_relation_1": "{\"o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE\":[{\"bSide\":\"AntennaModule_6\",\"aSide\":\"AntennaModule_5\",\"id\":\"one_to_one_relation_1\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/entity-types/AntennaModule/entities/AntennaModule_1": "{\"o-ran-smo-teiv-equipment:AntennaModule\":[{\"id\":\"AntennaModule_1\",\"sourceIds\":[],\"attributes\":{\"totalTilt\":null,\"mechanicalAntennaBearing\":null,\"fdn\":null,\"antennaModelNumber\":null,\"mechanicalAntennaTilt\":null,\"positionWithinSector\":null,\"cmId\":null,\"electricalAntennaTilt\":null}}]}",
-    "EQUIPMENT/entity-types/AntennaModule/entities/AntennaModule_2": "{\"o-ran-smo-teiv-equipment:AntennaModule\":[{\"id\":\"AntennaModule_2\",\"sourceIds\":[],\"attributes\":{\"totalTilt\":null,\"mechanicalAntennaBearing\":null,\"fdn\":null,\"antennaModelNumber\":null,\"mechanicalAntennaTilt\":null,\"positionWithinSector\":null,\"cmId\":null,\"electricalAntennaTilt\":null}}]}",
-    "EQUIPMENT/entity-types/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/entities/AntennaModule_3": "{\"o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":[{\"attributes\":{\"fdn\":\"AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=21\"},\"id\":\"AntennaModule_3\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/entity-types/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/entities/AntennaModule_4": "{\"o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":[{\"attributes\":{\"fdn\":\"AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=22\"},\"id\":\"AntennaModule_4\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/entity-types/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/entities/AntennaModule_5": "{\"o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":[{\"attributes\":{\"fdn\":\"AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=31\"},\"id\":\"AntennaModule_5\",\"sourceIds\":[]}]}",
-    "EQUIPMENT/entity-types/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/entities/AntennaModule_6": "{\"o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\":[{\"attributes\":{\"fdn\":\"AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=32\"},\"id\":\"AntennaModule_6\",\"sourceIds\":[]}]}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-second-case.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-create-second-case.json
deleted file mode 100644 (file)
index ac685fe..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_1": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_1\",\"sourceIds\":[],\"attributes\":{\"nCI\":1,\"nRTAC\":310,\"cellLocalId\":4589,\"nRPCI\":12,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1\"}}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_2": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_2\",\"sourceIds\":[],\"attributes\":{\"nCI\":2,\"nRTAC\":3101,\"cellLocalId\":45891,\"nRPCI\":121,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2\"}}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_3": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_3\",\"sourceIds\":[],\"attributes\":{\"nCI\":3,\"nRTAC\":301,\"cellLocalId\":469,\"nRPCI\":15,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CNA_SED_1": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CNA_SED_1\",\"sourceIds\":[],\"attributes\":{\"name\":\"CNA_1\"}}]}",
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_1": "{\"o-ran-smo-teiv-ran:GNBCUCPFunction\":[{\"id\":\"GNBCUCP_1\",\"sourceIds\":[],\"attributes\":{\"pLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBCUName\":\"Test_gNBCU\",\"gNBId\":123,\"gNBIdLength\":3,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_3": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_3\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_3\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_2": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_2\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_2\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_1": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_1\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_1\"}}]}",
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_SED_1": "{\"o-ran-smo-teiv-ran:GNBCUCPFunction\":[{\"id\":\"GNBCUCP_SED_1\",\"sourceIds\":[],\"attributes\":{\"pLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBCUName\":\"Test_sed_gNBCU\",\"gNBId\":123,\"gNBIdLength\":3,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1929103B15999999\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1\"}}]}",
-    "RAN/entity-types/GNBDUFunction/entities/GNBDU_1": "{\"o-ran-smo-teiv-ran:GNBDUFunction\":[{\"id\":\"GNBDU_1\",\"sourceIds\":[],\"attributes\":{\"dUpLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBDUId\":12,\"gNBId\":1234,\"gNBIdLength\":4,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]\"}}]}",
-    "RAN/entity-types/GNBCUUPFunction/entities/GNBCUUP_1": "{\"o-ran-smo-teiv-ran:GNBCUUPFunction\":[{\"id\":\"GNBCUUP_1\",\"sourceIds\":[],\"attributes\":{\"gNBId\":123,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1\",\"gNBIdLength\":3}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_6": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_6\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_3": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_3\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_sed_2": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CNA_SED_1\",\"aSide\":\"GNBCUCP_SED_1\",\"id\":\"relation_sed_2\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_4": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_4\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_2": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_2\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_1": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_1\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_5": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_5\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_sed_1": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CNA_SED_1\",\"aSide\":\"GNBDU_SED_1\",\"id\":\"relation_sed_1\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_1/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_1\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_7\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"}}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_2/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_2\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_8\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"}}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_3/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_3\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_9\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"}}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-many.json
deleted file mode 100644 (file)
index 6b66aaa..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_3": {
-
-    },
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_1": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_1": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_5": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_3": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_6": {
-
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-many-to-one.json
deleted file mode 100644 (file)
index cc9c604..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-    "CLOUD/entity-types/NodeCluster/entities/NodeCluster_1": {
-
-    },
-    "CLOUD/entity-types/CloudSite/entities/CloudSite_1": {
-
-    },
-    "CLOUD/relationship-types/NODECLUSTER_LOCATED_AT_CLOUDSITE/relationships/relation_1": {
-
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-one-to-many.json
deleted file mode 100644 (file)
index d8bc339..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-    "RAN/entity-types/ENodeBFunction/entities/ENodeBFunction_1": {
-
-    },
-    "OAM_TO_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships/relation_1": {
-
-    },
-    "OAM/entity-types/ManagedElement/entities/ManagedElement_1": {
-
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-relationship-connecting-same-entity.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-delete-relationship-connecting-same-entity.json
deleted file mode 100644 (file)
index 66c6280..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "EQUIPMENT/entity-types/AntennaModule/entities/AntennaModule_1": {
-
-    },
-    "EQUIPMENT/entity-types/AntennaModule/entities/AntennaModule_2": {
-
-    },
-    "EQUIPMENT/relationship-types/ANTENNAMODULE_REALISED_BY_ANTENNAMODULE/relationships/many_to_many_relation_1": {
-
-    },
-    "EQUIPMENT/relationship-types/ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE/relationships/one_to_many_relation_1": {
-
-    },
-    "EQUIPMENT/relationship-types/ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE/relationships/one_to_one_relation_1": {
-
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-merge-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-merge-one-to-many.json
deleted file mode 100644 (file)
index 434b0b4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_1": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_1\",\"sourceIds\":[],\"attributes\":{\"nRPCI\":12,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1\",\"nCI\":1,\"nRTAC\":310,\"cellLocalId\":4589}}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_2": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_2\",\"sourceIds\":[],\"attributes\":{\"nRPCI\":121,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2\",\"nCI\":2,\"nRTAC\":3101,\"cellLocalId\":45891}}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_3": "{\"o-ran-smo-teiv-ran:NRCellDU\":[{\"id\":\"NRCellDU_3\",\"sourceIds\":[],\"attributes\":{\"nRPCI\":15,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3\",\"nCI\":3,\"nRTAC\":301,\"cellLocalId\":469}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_6": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_6\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_3": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUCP_1\",\"id\":\"relation_3\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_1": "{\"o-ran-smo-teiv-ran:GNBCUCPFunction\":[{\"id\":\"GNBCUCP_1\",\"sourceIds\":[],\"attributes\":{\"gNBIdLength\":3,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1\",\"pLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBCUName\":\"Test_gNBCU\",\"gNBId\":123}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_3": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_3\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_3\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_2": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_2\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_2\"}}]}",
-    "CLOUD/entity-types/CloudNativeApplication/entities/CloudNativeApplication_1": "{\"o-ran-smo-teiv-cloud:CloudNativeApplication\":[{\"id\":\"CloudNativeApplication_1\",\"sourceIds\":[],\"attributes\":{\"name\":\"Test_CloudNativeApplication_1\"}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_4": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_4\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBDUFunction/entities/GNBDU_1": "{\"o-ran-smo-teiv-ran:GNBDUFunction\":[{\"id\":\"GNBDU_1\",\"sourceIds\":[],\"attributes\":{\"gNBIdLength\":4,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]\",\"dUpLMNId\":{\"mcc\":\"110\",\"mnc\":\"210\"},\"gNBDUId\":12,\"gNBId\":1234}}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_2": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_2\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_2\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_1": "{\"o-ran-smo-teiv-cloud-to-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_1\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_1\",\"sourceIds\":[]}]}",
-    "CLOUD_TO_RAN/relationship-types/GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_5": "{\"o-ran-smo-teiv-cloud-to-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION\":[{\"bSide\":\"CloudNativeApplication_3\",\"aSide\":\"GNBCUUP_1\",\"id\":\"relation_5\",\"sourceIds\":[]}]}",
-    "RAN/entity-types/GNBCUUPFunction/entities/GNBCUUP_1": "{\"o-ran-smo-teiv-ran:GNBCUUPFunction\":[{\"id\":\"GNBCUUP_1\",\"sourceIds\":[],\"attributes\":{\"gNBId\":123,\"cmId\":{\"cmHandle\":\"395221E080CCF0FD1924103B15873814\",\"resourceIdentifier\":\"/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]\"},\"fdn\":\"SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1\",\"gNBIdLength\":3}}]}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_1/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_1\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_7\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_1\\/relationships?offset=0&limit=500\"}}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_2/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_2\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_8\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_2\\/relationships?offset=0&limit=500\"}}",
-    "RAN/entity-types/NRCellDU/entities/NRCellDU_3/relationships": "{\"next\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"last\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"prev\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"self\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"},\"totalCount\":1,\"items\":[{\"o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU\":[{\"bSide\":\"NRCellDU_3\",\"aSide\":\"GNBDU_1\",\"id\":\"relation_9\"}]}],\"first\":{\"href\":\"\\/domains\\/RAN\\/entity-types\\/NRCellDU\\/entities\\/NRCellDU_3\\/relationships?offset=0&limit=500\"}}"
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-source-entity-delete-cm-handle.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/api/exp-source-entity-delete-cm-handle.json
deleted file mode 100644 (file)
index 5828231..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "RAN/entity-types/GNBDUFunction/entities/GNBDU_SED_1": {
-
-    },
-    "RAN/entity-types/GNBCUCPFunction/entities/GNBCUCP_SED_1": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_sed_1": {
-
-    },
-    "CLOUD_TO_RAN/relationship-types/GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION/relationships/relation_sed_2": {
-
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-many.json
deleted file mode 100644 (file)
index d2a873a..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-{
-    "entity_map_CNA_1": {
-        "id": "CloudNativeApplication_1",
-        "name": "Test_CloudNativeApplication_1"
-    },
-    "entity_map_CNA_2": {
-        "id": "CloudNativeApplication_2",
-        "name": "Test_CloudNativeApplication_2"
-    },
-    "entity_map_CNA_3": {
-        "id": "CloudNativeApplication_3",
-        "name": "Test_CloudNativeApplication_3"
-    },
-    "entity_map_GNBDU_1": {
-        "id": "GNBDU_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1",
-        "dUpLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "gNBDUId": 111,
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUUP_1": {
-        "id": "GNBCUUP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUCP_1": {
-        "id": "GNBCUCP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
-        "gNBCUName": "Test_gNBCU",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "pLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
-        }
-    },
-    "relation_map_GNBDU_CNA_1": {
-        "id": "relation_1",
-        "aSide_GNBDUFunction": "GNBDU_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_1"
-    },
-    "relation_map_GNBCUUP_CNA_2": {
-        "id": "relation_2",
-        "aSide_GNBCUUPFunction": "GNBCUUP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUCP_CNA_3": {
-        "id": "relation_3",
-        "aSide_GNBCUCPFunction": "GNBCUCP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBDU_CNA_4": {
-        "id": "relation_4",
-        "aSide_GNBDUFunction": "GNBDU_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUUP_CNA_5": {
-        "id": "relation_5",
-        "aSide_GNBCUUPFunction": "GNBCUUP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBCUCP_CNA_6": {
-        "id": "relation_6",
-        "aSide_GNBCUCPFunction": "GNBCUCP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_1"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one2.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one2.json
deleted file mode 100644 (file)
index e9337b0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "entity_map_NRSectorCarrier_1": {
-        "id": "NRSectorCarrier_1"
-    },
-    "entity_map_AntennaCapability_1": {
-        "id": "AntennaCapability_1",
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873820",
-            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
-        }
-    },
-    "relation_map_NRSC_AC_1": {
-        "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY": "relation_1",
-        "id": "NRSectorCarrier_1",
-        "REL_FK_used-antennaCapability": "AntennaCapability_1"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one3.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one3.json
deleted file mode 100644 (file)
index bbe2ca7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "entity_map_NRSectorCarrier_1": {
-        "id": "NRSectorCarrier_1"
-    },
-    "entity_map_AntennaCapability_1": {
-        "id": "AntennaCapability_1"
-    },
-    "relation_map_NRSC_AC_1": {
-        "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY": "relation_1",
-        "id": "NRSectorCarrier_1",
-        "REL_FK_used-antennaCapability": "AntennaCapability_1"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one5.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-many-to-one5.json
deleted file mode 100644 (file)
index 6c49856..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "entity_map_AntennaCapability_2": {
-        "id": "AntennaCapability_2",
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873820",
-            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
-        }
-    },
-    "relation_map_NRSC_AC_2": {
-        "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY": "relation_2",
-        "id": "NRSectorCarrier_2",
-        "REL_FK_used-antennaCapability": "AntennaCapability_2"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-one-to-one.json
deleted file mode 100644 (file)
index aeb6ab3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "entity_map_CNS_1": {
-        "id": "CloudNativeSystem_2"
-    },
-    "entity_map_ME_1": {
-        "id": "ManagedElement_2",
-        "REL_FK_deployed-as-cloudNativeSystem": "CloudNativeSystem_2",
-        "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": "relation_11"
-    },
-    "entity_map_CNS_2": {
-        "id": "CloudNativeSystem_3"
-    },
-    "entity_map_ME_2": {
-        "id": "ManagedElement_3",
-        "REL_FK_deployed-as-cloudNativeSystem": "CloudNativeSystem_3",
-        "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": "relation_12"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-second-case.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-create-second-case.json
deleted file mode 100644 (file)
index 8e8a229..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-{
-    "entity_map_CNA_1": {
-        "id": "CloudNativeApplication_1",
-        "name": "Test_CloudNativeApplication_1"
-    },
-    "entity_map_CNA_2": {
-        "id": "CloudNativeApplication_2",
-        "name": "Test_CloudNativeApplication_2"
-    },
-    "entity_map_CNA_3": {
-        "id": "CloudNativeApplication_3",
-        "name": "Test_CloudNativeApplication_3"
-    },
-    "entity_map_CNA_4": {
-        "id": "CNA_SED_1",
-        "name": "CNA_1"
-    },
-    "entity_map_GNBDU_1": {
-        "id": "GNBDU_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
-        "dUpLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "gNBDUId": 12,
-        "gNBId": 1234,
-        "gNBIdLength": 4,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBDU_2": {
-        "id": "GNBDU_SED_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
-        "dUpLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "gNBDUId": 111,
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1929103B15999999",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUUP_1": {
-        "id": "GNBCUUP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUCP_1": {
-        "id": "GNBCUCP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
-        "gNBCUName": "Test_gNBCU",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "pLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUCP_2": {
-        "id": "GNBCUCP_SED_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
-        "gNBCUName": "Test_sed_gNBCU",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "pLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1929103B15999999",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
-        }
-    },
-    "entity_map_NRCellDU_1": {
-        "id": "NRCellDU_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
-        "cellLocalId": 4589,
-        "nCI": 1,
-        "nRPCI": 12,
-        "nRTAC": 310,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
-        }
-    },
-    "entity_map_NRCellDU_2": {
-        "id": "NRCellDU_2",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
-        "cellLocalId": 45891,
-        "nCI": 2,
-        "nRPCI": 121,
-        "nRTAC": 3101,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
-        }
-    },
-    "entity_map_NRCellDU_3": {
-        "id": "NRCellDU_3",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
-        "cellLocalId": 469,
-        "nCI": 3,
-        "nRPCI": 15,
-        "nRTAC": 301,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
-        }
-    },
-    "relation_map_GNBDU_CNA_1": {
-        "id": "relation_1",
-        "aSide_GNBDUFunction": "GNBDU_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_1"
-    },
-    "relation_map_GNBCUUP_CNA_2": {
-        "id": "relation_2",
-        "aSide_GNBCUUPFunction": "GNBCUUP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUCP_CNA_3": {
-        "id": "relation_3",
-        "aSide_GNBCUCPFunction": "GNBCUCP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBDU_CNA_4": {
-        "id": "relation_4",
-        "aSide_GNBDUFunction": "GNBDU_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUUP_CNA_5": {
-        "id": "relation_5",
-        "aSide_GNBCUUPFunction": "GNBCUUP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBCUCP_CNA_6": {
-        "id": "relation_6",
-        "aSide_GNBCUCPFunction": "GNBCUCP_1",
-        "bSide_CloudNativeApplication": "CloudNativeApplication_1"
-    },
-    "relation_map_GNBDU_NRCellDU_1": {
-        "id": "NRCellDU_1",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_7"
-    },
-    "relation_map_GNBDU_NRCellDU_2": {
-        "id": "NRCellDU_2",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_8"
-    },
-    "relation_map_GNBDU_NRCellDU_3": {
-        "id": "NRCellDU_3",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_9"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-delete-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-delete-one-to-one.json
deleted file mode 100644 (file)
index daad7a1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "entity_map_CNS_1": {
-        "id": "CloudNativeSystem_2",
-        "REL_FK_deployed-managedElement": null
-    },
-    "entity_map_CNS_2": {
-        "id": "CloudNativeSystem_3",
-        "REL_FK_deployed-managedElement": null
-    },
-    "entity_map_ME_2": {
-        "id": "ManagedElement_3",
-        "REL_FK_deployed-as-cloudNativeSystem": null,
-        "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": null
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-merge-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/db/exp-merge-one-to-many.json
deleted file mode 100644 (file)
index c889cf2..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-{
-    "entity_map_CNA_1": {
-        "id": "CloudNativeApplication_1",
-        "name": "Test_CloudNativeApplication_1"
-    },
-    "entity_map_CNA_2": {
-        "id": "CloudNativeApplication_2",
-        "name": "Test_CloudNativeApplication_2"
-    },
-    "entity_map_CNA_3": {
-        "id": "CloudNativeApplication_3",
-        "name": "Test_CloudNativeApplication_3"
-    },
-    "entity_map_GNBDU_1": {
-        "id": "GNBDU_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
-        "dUpLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "gNBDUId": 12,
-        "gNBId": 1234,
-        "gNBIdLength": 4,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUUP_1": {
-        "id": "GNBCUUP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
-        }
-    },
-    "entity_map_GNBCUCP_1": {
-        "id": "GNBCUCP_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
-        "gNBCUName": "Test_gNBCU",
-        "gNBId": 123,
-        "gNBIdLength": 3,
-        "pLMNId": {
-            "mcc": "110",
-            "mnc": "210"
-        },
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
-        }
-    },
-    "entity_map_NRCellDU_1": {
-        "id": "NRCellDU_1",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
-        "cellLocalId": 4589,
-        "nCI": 1,
-        "nRPCI": 12,
-        "nRTAC": 310,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
-        }
-    },
-    "entity_map_NRCellDU_2": {
-        "id": "NRCellDU_2",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
-        "cellLocalId": 45891,
-        "nCI": 2,
-        "nRPCI": 121,
-        "nRTAC": 3101,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
-        }
-    },
-    "entity_map_NRCellDU_3": {
-        "id": "NRCellDU_3",
-        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
-        "cellLocalId": 469,
-        "nCI": 3,
-        "nRPCI": 15,
-        "nRTAC": 301,
-        "cmId": {
-            "cmHandle": "395221E080CCF0FD1924103B15873814",
-            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
-        }
-    },
-    "relation_map_GNBDU_CNA_1": {
-        "id": "relation_1",
-        "gnbdufunction": "GNBDU_1",
-        "cloudnativeapplication": "CloudNativeApplication_1"
-    },
-    "relation_map_GNBCUUP_CNA_2": {
-        "id": "relation_2",
-        "gnbcuupfunction": "GNBCUUP_1",
-        "cloudnativeapplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUCP_CNA_3": {
-        "id": "relation_3",
-        "gnbcucpfunction": "GNBCUCP_1",
-        "cloudnativeapplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBDU_CNA_4": {
-        "id": "relation_4",
-        "gnbdufunction": "GNBDU_1",
-        "cloudnativeapplication": "CloudNativeApplication_2"
-    },
-    "relation_map_GNBCUUP_CNA_5": {
-        "id": "relation_5",
-        "gnbcuupfunction": "GNBCUUP_1",
-        "cloudnativeapplication": "CloudNativeApplication_3"
-    },
-    "relation_map_GNBCUCP_CNA_6": {
-        "id": "relation_6",
-        "gnbcucpfunction": "GNBCUCP_1",
-        "cloudnativeapplication": "CloudNativeApplication_1"
-    },
-    "relation_map_GNBDU_NRCellDU_1": {
-        "id": "NRCellDU_1",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_7"
-    },
-    "relation_map_GNBDU_NRCellDU_2": {
-        "id": "NRCellDU_2",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_8"
-    },
-    "relation_map_GNBDU_NRCellDU_3": {
-        "id": "NRCellDU_3",
-        "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
-        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_9"
-    },
-    "relation_map_GNBDU_NRCellDU_REL_7": {
-        "id": "relation_7",
-        "gnbdufunction": "GNBDU_1",
-        "nrcelldu": "NRCellDU_1"
-    },
-    "relation_map_GNBDU_NRCellDU_REL_8": {
-        "id": "relation_8",
-        "gnbdufunction": "GNBDU_1",
-        "nrcelldu": "NRCellDU_2"
-    },
-    "relation_map_GNBDU_NRCellDU_REL_9": {
-        "id": "relation_9",
-        "gnbdufunction": "GNBDU_1",
-        "nrcelldu": "NRCellDU_3"
-    }
-}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-many-to-many.json
new file mode 100644 (file)
index 0000000..78dfb9a
--- /dev/null
@@ -0,0 +1,98 @@
+{
+    "e01fcb87ad2c34ce66c34420255e25aaca270e5e": [
+        {
+            "id": "CloudNativeApplication_1",
+            "name": "Test_CloudNativeApplication_1"
+        },
+        {
+            "id": "CloudNativeApplication_2",
+            "name": "Test_CloudNativeApplication_2"
+        },
+        {
+            "id": "CloudNativeApplication_3",
+            "name": "Test_CloudNativeApplication_3"
+        }
+    ],
+    "o-ran-smo-teiv-ran-logical_GNBDUFunction": [
+        {
+            "id": "GNBDU_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1",
+            "dUpLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "gNBDUId": 111,
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+            }
+        }
+    ],
+    "8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb": [
+        {
+            "id": "GNBCUUP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
+            }
+        }
+    ],
+    "c4a425179d3089b5288fdf059079d0ea26977f0f": [
+        {
+            "id": "GNBCUCP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
+            "gNBCUName": "Test_gNBCU",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "pLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+            }
+        }
+    ],
+    "10484f157f490eb5b27e40dbfaf4d5f2be17c57c": [
+        {
+            "id": "relation_1",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        },
+        {
+            "id": "relation_4",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        }
+    ],
+    "70a4a84bca01ea022ab24d8cb82422c572922675": [
+        {
+            "id": "relation_2",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        },
+        {
+            "id": "relation_5",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        }
+    ],
+    "7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7": [
+        {
+            "id": "relation_3",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        },
+        {
+            "id": "relation_6",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        }
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-one-to-one.json
new file mode 100644 (file)
index 0000000..dd9ccd1
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    "163276fa439cdfccabb80f7acacb6fa638e8d314": [
+        {
+            "id": "CloudNativeSystem_2"
+        },
+        {
+            "id": "CloudNativeSystem_3"
+        }
+    ],
+    "o-ran-smo-teiv-ran-oam_ManagedElement": [
+        {
+            "id": "ManagedElement_2",
+            "REL_FK_deployed-as-cloudNativeSystem": "CloudNativeSystem_2",
+            "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": "relation_11"
+        },
+        {
+            "id": "ManagedElement_3",
+            "REL_FK_deployed-as-cloudNativeSystem": "CloudNativeSystem_3",
+            "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": "relation_12"
+        }
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-second-case.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-create-second-case.json
new file mode 100644 (file)
index 0000000..23c9633
--- /dev/null
@@ -0,0 +1,185 @@
+{
+    "e01fcb87ad2c34ce66c34420255e25aaca270e5e": [
+        {
+            "id": "CloudNativeApplication_1",
+            "name": "Test_CloudNativeApplication_1"
+        },
+        {
+            "id": "CloudNativeApplication_2",
+            "name": "Test_CloudNativeApplication_2"
+        },
+        {
+            "id": "CloudNativeApplication_3",
+            "name": "Test_CloudNativeApplication_3"
+        },
+        {
+            "id": "CNA_SED_1",
+            "name": "CNA_1"
+        }
+    ],
+    "o-ran-smo-teiv-ran-logical_GNBDUFunction": [
+        {
+            "id": "GNBDU_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
+            "dUpLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "gNBDUId": 12,
+            "gNBId": 1234,
+            "gNBIdLength": 4,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+            }
+        },
+        {
+            "id": "GNBDU_SED_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
+            "dUpLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "gNBDUId": 111,
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1929103B15999999",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+            }
+        }
+    ],
+    "8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb": [
+        {
+            "id": "GNBCUUP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
+            }
+        }
+    ],
+    "c4a425179d3089b5288fdf059079d0ea26977f0f": [
+        {
+            "id": "GNBCUCP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
+            "gNBCUName": "Test_gNBCU",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "pLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+            }
+        },
+        {
+            "id": "GNBCUCP_SED_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
+            "gNBCUName": "Test_sed_gNBCU",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "pLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1929103B15999999",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+            }
+        }
+    ],
+    "o-ran-smo-teiv-ran-logical_NRCellDU": [
+        {
+            "id": "NRCellDU_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
+            "cellLocalId": 4589,
+            "nCI": 1,
+            "nRPCI": 12,
+            "nRTAC": 310,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
+            }
+        },
+        {
+            "id": "NRCellDU_2",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
+            "cellLocalId": 45891,
+            "nCI": 2,
+            "nRPCI": 121,
+            "nRTAC": 3101,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
+            }
+        },
+        {
+            "id": "NRCellDU_3",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
+            "cellLocalId": 469,
+            "nCI": 3,
+            "nRPCI": 15,
+            "nRTAC": 301,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
+            }
+        },
+        {
+            "id": "NRCellDU_1",
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_7"
+        },
+        {
+            "id": "NRCellDU_2",
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_8"
+        },
+        {
+            "id": "NRCellDU_3",
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_9"
+        }
+    ],
+    "10484f157f490eb5b27e40dbfaf4d5f2be17c57c": [
+        {
+            "id": "relation_1",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        },
+        {
+            "id": "relation_4",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        }
+    ],
+    "70a4a84bca01ea022ab24d8cb82422c572922675": [
+        {
+            "id": "relation_2",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        },
+        {
+            "id": "relation_5",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        }
+    ],
+    "7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7": [
+        {
+            "id": "relation_3",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        },
+        {
+            "id": "relation_6",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        }
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-delete-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-delete-one-to-one.json
new file mode 100644 (file)
index 0000000..ea66a96
--- /dev/null
@@ -0,0 +1,19 @@
+{
+    "163276fa439cdfccabb80f7acacb6fa638e8d314": [
+        {
+            "id": "CloudNativeSystem_2",
+            "REL_FK_deployed-managedElement": null
+        },
+        {
+            "id": "CloudNativeSystem_3",
+            "REL_FK_deployed-managedElement": null
+        }
+    ],
+    "o-ran-smo-teiv-ran-oam_ManagedElement": [
+        {
+            "id": "ManagedElement_3",
+            "REL_FK_deployed-as-cloudNativeSystem": null,
+            "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": null
+        }
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-merge-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/exp-merge-one-to-many.json
new file mode 100644 (file)
index 0000000..ef104e4
--- /dev/null
@@ -0,0 +1,142 @@
+{
+    "e01fcb87ad2c34ce66c34420255e25aaca270e5e": [
+        {
+            "id": "CloudNativeApplication_1",
+            "name": "Test_CloudNativeApplication_1"
+        },
+        {
+            "id": "CloudNativeApplication_2",
+            "name": "Test_CloudNativeApplication_2"
+        },
+        {
+            "id": "CloudNativeApplication_3",
+            "name": "Test_CloudNativeApplication_3"
+        }
+    ],
+    "o-ran-smo-teiv-ran-logical_GNBDUFunction": [
+        {
+            "id": "GNBDU_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
+            "dUpLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "gNBDUId": 12,
+            "gNBId": 1234,
+            "gNBIdLength": 4,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+            }
+        }
+    ],
+    "8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb": [
+        {
+            "id": "GNBCUUP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
+            }
+        }
+    ],
+    "c4a425179d3089b5288fdf059079d0ea26977f0f": [
+        {
+            "id": "GNBCUCP_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
+            "gNBCUName": "Test_gNBCU",
+            "gNBId": 123,
+            "gNBIdLength": 3,
+            "pLMNId": {
+                "mcc": "110",
+                "mnc": "210"
+            },
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+            }
+        }
+    ],
+    "o-ran-smo-teiv-ran-logical_NRCellDU": [
+        {
+            "id": "NRCellDU_1",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
+            "cellLocalId": 4589,
+            "nCI": 1,
+            "nRPCI": 12,
+            "nRTAC": 310,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
+            },
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_7"
+        },
+        {
+            "id": "NRCellDU_2",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
+            "cellLocalId": 45891,
+            "nCI": 2,
+            "nRPCI": 121,
+            "nRTAC": 3101,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
+            },
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_8"
+        },
+        {
+            "id": "NRCellDU_3",
+            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
+            "cellLocalId": 469,
+            "nCI": 3,
+            "nRPCI": 15,
+            "nRTAC": 301,
+            "cmId": {
+                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
+            },
+            "REL_FK_provided-by-gnbduFunction": "GNBDU_1",
+            "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU": "relation_9"
+        }
+    ],
+    "10484f157f490eb5b27e40dbfaf4d5f2be17c57c": [
+        {
+            "id": "relation_1",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        },
+        {
+            "id": "relation_4",
+            "aSide_GNBDUFunction": "GNBDU_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        }
+    ],
+    "70a4a84bca01ea022ab24d8cb82422c572922675": [
+        {
+            "id": "relation_2",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_2"
+        },
+        {
+            "id": "relation_5",
+            "aSide_GNBCUUPFunction": "GNBCUUP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        }
+    ],
+    "7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7": [
+        {
+            "id": "relation_3",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_3"
+        },
+        {
+            "id": "relation_6",
+            "aSide_GNBCUCPFunction": "GNBCUCP_1",
+            "bSide_CloudNativeApplication": "CloudNativeApplication_1"
+        }
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-many-to-many.json
new file mode 100644 (file)
index 0000000..731edaf
--- /dev/null
@@ -0,0 +1,18 @@
+{
+    "e01fcb87ad2c34ce66c34420255e25aaca270e5e": [
+        "CloudNativeApplication_3"
+    ],
+    "c4a425179d3089b5288fdf059079d0ea26977f0f": [
+        "GNBCUCP_1"
+    ],
+    "10484f157f490eb5b27e40dbfaf4d5f2be17c57c": [
+        "relation_1"
+    ],
+    "70a4a84bca01ea022ab24d8cb82422c572922675": [
+        "relation_5"
+    ],
+    "7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7": [
+        "relation_3",
+        "relation_6"
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-delete-one-to-one.json
new file mode 100644 (file)
index 0000000..b1d9a08
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "163276fa439cdfccabb80f7acacb6fa638e8d314": [
+        "relation_11",
+        "relation_12"
+    ],
+    "o-ran-smo-teiv-ran-oam_ManagedElement": [
+        "ManagedElement_2",
+        "relation_11",
+        "relation_12"
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-source-entity-delete-cm-handle.json b/teiv/src/test/resources/cloudeventdata/end-to-end/expected-results/not-exp-source-entity-delete-cm-handle.json
new file mode 100644 (file)
index 0000000..b6d5349
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "o-ran-smo-teiv-ran-logical_GNBDUFunction": [
+        "GNBDU_SED_1"
+    ],
+    "c4a425179d3089b5288fdf059079d0ea26977f0f": [
+        "GNBCUCP_SED_1",
+        "GNBCUCP_SED_2"
+    ],
+    "7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7": [
+        "relation_sed_1"
+    ],
+    "10484f157f490eb5b27e40dbfaf4d5f2be17c57c": [
+        "relation_sed_2"
+    ]
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-geo-location.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-geo-location.json
new file mode 100644 (file)
index 0000000..656b5d4
--- /dev/null
@@ -0,0 +1,31 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f1113",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": {
+            "o-ran-smo-teiv-cloud:CloudSite": [
+                {
+                    "id": "CloudSite1",
+                    "sourceIds": [
+                        "urn:3gpp:dn:fdn1",
+                        "urn:cmHandle:1234"
+                    ],
+                    "attributes": {
+                        "name": "geo-location1",
+                        "geo-location": {
+                            "location": {
+                                "latitude": 12.78232,
+                                "longitude": 56.7455
+                            }
+                        }
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-many.json
new file mode 100644 (file)
index 0000000..99507d6
--- /dev/null
@@ -0,0 +1,137 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0001",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-cloud:CloudNativeApplication": [
+                    {
+                        "id": "CloudNativeApplication_1",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_1"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeApplication_2",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_2"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeApplication_3",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_3"
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                    {
+                        "id": "GNBDU_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1",
+                            "dUpLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "gNBDUId": 111,
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                    {
+                        "id": "GNBCUUP_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUUPFunction=1",
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUUPFunction]/o-ran-smo-GNBCUUP:GNBCUUPFunction[@id=1]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCP_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,GNBCUCPFunction=1",
+                            "gNBCUName": "Test_gNBCU",
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "pLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=GNBCUCPFunction]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+                            }
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_1",
+                        "aSide": "GNBDU_1",
+                        "bSide": "CloudNativeApplication_1"
+                    },
+                    {
+                        "id": "relation_4",
+                        "aSide": "GNBDU_1",
+                        "bSide": "CloudNativeApplication_2"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_2",
+                        "aSide": "GNBCUUP_1",
+                        "bSide": "CloudNativeApplication_2"
+                    },
+                    {
+                        "id": "relation_5",
+                        "aSide": "GNBCUUP_1",
+                        "bSide": "CloudNativeApplication_3"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_3",
+                        "aSide": "GNBCUCP_1",
+                        "bSide": "CloudNativeApplication_3"
+                    },
+                    {
+                        "id": "relation_6",
+                        "aSide": "GNBCUCP_1",
+                        "bSide": "CloudNativeApplication_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-many-to-one.json
new file mode 100644 (file)
index 0000000..2729d70
--- /dev/null
@@ -0,0 +1,76 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-cloud:NodeCluster": [
+                    {
+                        "id": "NodeCluster_1",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:AntennaCapability": [
+                    {
+                        "id": "AntennaCapability_1",
+                        "attributes": {
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873820",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:NRSectorCarrier": [
+                    {
+                        "id": "NRSectorCarrier_1",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudSite": [
+                    {
+                        "id": "CloudSite_1",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
+                    {
+                        "id": "relation_1",
+                        "aSide": "NodeCluster_1",
+                        "bSide": "CloudSite_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "relation_10",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-many.json
new file mode 100644 (file)
index 0000000..45e422b
--- /dev/null
@@ -0,0 +1,56 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1",
+                        "attributes": {
+
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:ENodeBFunction": [
+                    {
+                        "id": "ENodeBFunction_1",
+                        "attributes": {
+
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
+                    {
+                        "id": "relation_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "ENodeBFunction_1",
+                        "sourceIds": [
+                            "fdn_1",
+                            "cmHandleId_1"
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-one-to-one.json
new file mode 100644 (file)
index 0000000..4c4cdb1
--- /dev/null
@@ -0,0 +1,61 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_2",
+                        "attributes": {
+
+                        }
+                    },
+                    {
+                        "id": "ManagedElement_3",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                    {
+                        "id": "CloudNativeSystem_2",
+                        "attributes": {
+
+                        }
+                    },
+                    {
+                        "id": "CloudNativeSystem_3",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "relation_11",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "CloudNativeSystem_2"
+                    },
+                    {
+                        "id": "relation_12",
+                        "aSide": "ManagedElement_3",
+                        "bSide": "CloudNativeSystem_3"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-relationship-connecting-same-entity.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-relationship-connecting-same-entity.json
new file mode 100644 (file)
index 0000000..a411b47
--- /dev/null
@@ -0,0 +1,86 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0100",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-equipment-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-equipment:AntennaModule": [
+                    {
+                        "id": "AntennaModule_1",
+                        "attributes": {
+
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_2",
+                        "attributes": {
+
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                    {
+                        "id": "AntennaModule_3",
+                        "attributes": {
+                            "fdn": "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=21"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_4",
+                        "attributes": {
+                            "fdn": "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=22"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_5",
+                        "attributes": {
+                            "fdn": "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=31"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_6",
+                        "attributes": {
+                            "fdn": "AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=32"
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULE_REALISED_BY_ANTENNAMODULE": [
+                    {
+                        "id": "many_to_many_relation_1",
+                        "aSide": "AntennaModule_1",
+                        "bSide": "AntennaModule_2"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "one_to_many_relation_1",
+                        "aSide": "AntennaModule_3",
+                        "bSide": "AntennaModule_4"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "one_to_one_relation_1",
+                        "aSide": "AntennaModule_5",
+                        "bSide": "AntennaModule_6"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-second-case.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-create-second-case.json
new file mode 100644 (file)
index 0000000..0abdcfa
--- /dev/null
@@ -0,0 +1,114 @@
+{
+    "specversion": "1.0",
+    "id": "26504e8e-838e-11ee-b962-0242ac120002",
+    "source": "dmi-plugin:nm-3",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:CloudNativeApplication": [
+                    {
+                        "id": "CNA_SED_1",
+                        "attributes": {
+                            "name": "CNA_1"
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                    {
+                        "id": "GNBDU_SED_1",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBDUFunction=1",
+                            "dUpLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "gNBDUId": 111,
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1929103B15999999",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCP_SED_1",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=1",
+                            "gNBCUName": "Test_sed_gNBCU",
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "pLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1929103B15999999",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=1]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "GNBCUCP_SED_2",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=2",
+                            "urn:cmHandle:395221E080CCF0FD1929103B15999999"
+                        ],
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00009,ManagedElement=NR01gNodeBRadio00009,GNBCUCPFunction=2",
+                            "gNBCUName": "Test_sed_gNBCU2",
+                            "gNBId": 123,
+                            "gNBIdLength": 3,
+                            "pLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1929103B15999999",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00009]/o-ran-smo-GNBCUCP:GNBCUCPFunction[@id=2]"
+                            }
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_sed_1",
+                        "aSide": "GNBDU_SED_1",
+                        "bSide": "CNA_SED_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_sed_2",
+                        "aSide": "GNBCUCP_SED_1",
+                        "bSide": "CNA_SED_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-managed-element.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-managed-element.json
new file mode 100644 (file)
index 0000000..6083b31
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-many.json
new file mode 100644 (file)
index 0000000..8b5797b
--- /dev/null
@@ -0,0 +1,36 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran:CloudNativeApplication": [
+                    {
+                        "id": "CloudNativeApplication_3"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCP_1"
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION": [
+                    {
+                        "id": "relation_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-many-to-one.json
new file mode 100644 (file)
index 0000000..6ba8fc8
--- /dev/null
@@ -0,0 +1,36 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-cloud:NodeCluster": [
+                    {
+                        "id": "NodeCluster_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudSite": [
+                    {
+                        "id": "CloudSite_1"
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-cloud:NODECLUSTER_LOCATED_AT_CLOUDSITE": [
+                    {
+                        "id": "relation_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-many.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-many.json
new file mode 100644 (file)
index 0000000..b3d93ee
--- /dev/null
@@ -0,0 +1,36 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:ENodeBFunction": [
+                    {
+                        "id": "ENodeBFunction_1"
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-oam-to-logical:MANAGEDELEMENT_MANAGES_ENODEBFUNCTION": [
+                    {
+                        "id": "relation_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-one.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-one-to-one.json
new file mode 100644 (file)
index 0000000..ccd5081
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_2"
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "relation_12"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-relationship-connecting-same-entity.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-delete-relationship-connecting-same-entity.json
new file mode 100644 (file)
index 0000000..e4844a0
--- /dev/null
@@ -0,0 +1,39 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0103",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-equipment-topology.delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-equipment:AntennaModule": [
+                    {
+                        "id": "AntennaModule_1"
+                    },
+                    {
+                        "id": "AntennaModule_2"
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "one_to_many_relation_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "one_to_one_relation_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-long-names.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-long-names.json
new file mode 100644 (file)
index 0000000..ee90fb1
--- /dev/null
@@ -0,0 +1,364 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0002",
+    "source": "dmi-plugin:nm-1",
+    "type": "ties.merge",
+    "time": "2023-10-25T13:30:12Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology-yang",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-cloud:Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                    {
+                        "id": "Namespace_1",
+                        "attributes": {
+                            "name": "Namespace_1"
+                        }
+                    },
+                    {
+                        "id": "Namespace_2",
+                        "attributes": {
+                            "name": "Namespace_2"
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-oam:ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt": [
+                    {
+                        "id": "ManagedElement_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001",
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "ManagedElement_2",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00002,ManagedElement=NR01gNodeBRadio00002",
+                            "cmId": {
+                                "cmHandle": "F0FD1924103B15873814395221E080CC",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00002]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "ManagedElement_3",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00003,ManagedElement=NR01gNodeBRadio00003",
+                            "cmId": {
+                                "cmHandle": "B15873F0FD192410381439E080CC5221",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00003]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm": [
+                    {
+                        "id": "CloudNativeSystem_1",
+                        "attributes": {
+                            "name": "Test_CloudNativeSystem_1"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeSystem_2",
+                        "attributes": {
+                            "name": "Test_CloudNativeSystem_2"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeSystem_3",
+                        "attributes": {
+                            "name": "Test_CloudNativeSystem_3"
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
+                    {
+                        "id": "CloudNativeApplication_1",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_1"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeApplication_2",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_2"
+                        }
+                    },
+                    {
+                        "id": "CloudNativeApplication_3",
+                        "attributes": {
+                            "name": "Test_CloudNativeApplication_3"
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": [
+                    {
+                        "id": "GNBDUFunction_1",
+                        "attributes": {
+                            "fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1",
+                            "dUpLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "gNBDUId": 12,
+                            "gNBId": 1234,
+                            "gNBIdLength": 4,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "GNBDUFunction_2",
+                        "attributes": {
+                            "fdnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=2",
+                            "dUpLMNId": {
+                                "mcc": "110",
+                                "mnc": "210"
+                            },
+                            "gNBDUId": 12,
+                            "gNBId": 1234,
+                            "gNBIdLength": 4,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=2]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU": [
+                    {
+                        "id": "NRCellDU_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1,NRCellDU=1",
+                            "cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd": 4589,
+                            "nCI": 1,
+                            "nRPCI": 12,
+                            "nRTAC": 310,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "NRCellDU_2",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1,NRCellDU=2",
+                            "cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd": 45891,
+                            "nCI": 2,
+                            "nRPCI": 121,
+                            "nRTAC": 3101,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "NRCellDU_3",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=1,NRCellDU=3",
+                            "cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd": 469,
+                            "nCI": 3,
+                            "nRPCI": 15,
+                            "nRTAC": 301,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
+                            }
+                        }
+                    },
+                    {
+                        "id": "NRCellDU_4",
+                        "attributes": {
+                            "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction=2,NRCellDU=4",
+                            "cellLocalIdddddddddddddddddddddddddddddddddddddddddddddddddddddd": 469,
+                            "nCI": 4,
+                            "nRPCI": 15,
+                            "nRTAC": 301,
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873814",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=2]/o-ran-smo-NRCellDU:NRCellDU[@id=4]"
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": [
+                    {
+                        "id": "AntennaModule_1",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=11"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_2",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=12"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_3",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=21"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_4",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=22"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_5",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=31"
+                        }
+                    },
+                    {
+                        "id": "AntennaModule_6",
+                        "attributes": {
+                            "fdn": "SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=32"
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-cloud:CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE": [
+                    {
+                        "id": "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE_relation_1",
+                        "aSide": "CloudNativeApplication_1",
+                        "bSide": "Namespace_1"
+                    },
+                    {
+                        "id": "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE_relation_2",
+                        "aSide": "CloudNativeApplication_2",
+                        "bSide": "Namespace_1"
+                    },
+                    {
+                        "id": "CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE_relation_3",
+                        "aSide": "CloudNativeApplication_3",
+                        "bSide": "Namespace_2"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM": [
+                    {
+                        "id": "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_relation_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "CloudNativeSystem_1"
+                    },
+                    {
+                        "id": "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_relation_2",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "CloudNativeSystem_2"
+                    },
+                    {
+                        "id": "MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM_relation_3",
+                        "aSide": "ManagedElement_3",
+                        "bSide": "CloudNativeSystem_3"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN": [
+                    {
+                        "id": "MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "CloudNativeApplication_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-to-cloud:GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN": [
+                    {
+                        "id": "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_1",
+                        "aSide": "GNBDUFunction_1",
+                        "bSide": "CloudNativeApplication_1"
+                    },
+                    {
+                        "id": "GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_relation_2",
+                        "aSide": "GNBDUFunction_1",
+                        "bSide": "CloudNativeApplication_2"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN": [
+                    {
+                        "id": "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION_relation_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "GNBDUFunction_1"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU": [
+                    {
+                        "id": "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_1",
+                        "aSide": "GNBDUFunction_1",
+                        "bSide": "NRCellDU_1"
+                    },
+                    {
+                        "id": "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_2",
+                        "aSide": "GNBDUFunction_1",
+                        "bSide": "NRCellDU_2"
+                    },
+                    {
+                        "id": "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_3",
+                        "aSide": "GNBDUFunction_1",
+                        "bSide": "NRCellDU_3"
+                    },
+                    {
+                        "id": "GNBDUFUNCTION_PROVIDES_NRCELLDU_relation_4",
+                        "aSide": "GNBDUFunction_2",
+                        "bSide": "NRCellDU_4"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_relation_1",
+                        "aSide": "AntennaModule_1",
+                        "bSide": "AntennaModule_2"
+                    },
+                    {
+                        "id": "ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_relation_2",
+                        "aSide": "AntennaModule_3",
+                        "bSide": "AntennaModule_4"
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-equipment:ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE": [
+                    {
+                        "id": "ANTENNAMODULE_DEPLOYED_ON_ANTENNAMODULE_relation_1",
+                        "aSide": "AntennaModule_5",
+                        "bSide": "AntennaModule_6"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many-deprecated-structure.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many-deprecated-structure.json
new file mode 100644 (file)
index 0000000..b4d75c5
--- /dev/null
@@ -0,0 +1,95 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0002",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.merge",
+    "time": "2023-10-25T13:30:12Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": {
+            "o-ran-smo-teiv-ran:GNBDUFunction": [
+                {
+                    "id": "GNBDU_1",
+                    "attributes": {
+                        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,MeContext=NR01gNodeBRadio00001,ManagedElement=NR01gNodeBRadio00001,GNBDUFunction[@id=1]",
+                        "dUpLMNId": {
+                            "mcc": "110",
+                            "mnc": "210"
+                        },
+                        "gNBDUId": 12,
+                        "gNBId": 1234,
+                        "gNBIdLength": 4,
+                        "cmId": {
+                            "cmHandle": "395221E080CCF0FD1924103B15873814",
+                            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NR01gNodeBRadio00001]/o-ran-smo-GNBDU:GNBDUFunction[@id=1]"
+                        }
+                    }
+                }
+            ],
+            "o-ran-smo-teiv-ran:NRCellDU": [
+                {
+                    "id": "NRCellDU_1",
+                    "attributes": {
+                        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=1",
+                        "cellLocalId": 4589,
+                        "nCI": 1,
+                        "nRPCI": 12,
+                        "nRTAC": 310,
+                        "cmId": {
+                            "cmHandle": "395221E080CCF0FD1924103B15873814",
+                            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_1]/o-ran-smo-NRCellDU:NRCellDU[@id=1]"
+                        }
+                    }
+                },
+                {
+                    "id": "NRCellDU_2",
+                    "attributes": {
+                        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=2",
+                        "cellLocalId": 45891,
+                        "nCI": 2,
+                        "nRPCI": 121,
+                        "nRTAC": 3101,
+                        "cmId": {
+                            "cmHandle": "395221E080CCF0FD1924103B15873814",
+                            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_2]/o-ran-smo-NRCellDU:NRCellDU[@id=2]"
+                        }
+                    }
+                },
+                {
+                    "id": "NRCellDU_3",
+                    "attributes": {
+                        "fdn": "SubNetwork=Europe,SubNetwork=Ireland,NRCellDU=3",
+                        "cellLocalId": 469,
+                        "nCI": 3,
+                        "nRPCI": 15,
+                        "nRTAC": 301,
+                        "cmId": {
+                            "cmHandle": "395221E080CCF0FD1924103B15873814",
+                            "resourceIdentifier": "/o-ran-smo-ComTop:ManagedElement[@id=NRCellDU_3]/o-ran-smo-NRCellDU:NRCellDU[@id=3]"
+                        }
+                    }
+                }
+            ]
+        },
+        "relationships": {
+            "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                {
+                    "id": "relation_7",
+                    "aSide": "GNBDU_1",
+                    "bSide": "NRCellDU_1"
+                },
+                {
+                    "id": "relation_8",
+                    "aSide": "GNBDU_1",
+                    "bSide": "NRCellDU_2"
+                },
+                {
+                    "id": "relation_9",
+                    "aSide": "GNBDU_1",
+                    "bSide": "NRCellDU_3"
+                }
+            ]
+        }
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many2.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-merge-one-to-many2.json
new file mode 100644 (file)
index 0000000..9ab1302
--- /dev/null
@@ -0,0 +1,86 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f1113",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.merge",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1",
+                        "attributes": {
+
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
+                    },
+                    {
+                        "id": "ManagedElement_2",
+                        "attributes": {
+
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                    {
+                        "id": "CloudNativeSystem_1",
+                        "attributes": {
+
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:fdn1",
+                            "urn:cmHandle:1234"
+                        ]
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                    {
+                        "id": "GNBDU_1",
+                        "attributes": {
+                            "dUpLMNId": {
+                                "mcc": 110,
+                                "mnc": 210
+                            },
+                            "gNBDUId": 111,
+                            "gNBId": 123,
+                            "gNBIdLength": 3
+                        },
+                        "sourceIds": [
+                            "urn:3gpp:dn:/SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR01gNodeBRadio00001/ManagedElement=NR01gNodeBRadio00001/GNBDUFunction=1",
+                            "urn:cmHandle:/395221E080CCF0FD1924103B15873814"
+                        ]
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "relation_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "CloudNativeSystem_1",
+                        "sourceIds": [
+                            "fdn_1",
+                            "cmHandleId_1"
+                        ]
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle.json
new file mode 100644 (file)
index 0000000..6f5ce38
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "specversion": "1.0",
+    "id": "063b0da2-8396-11ee-b962-0242ac120002",
+    "source": "dmi-plugin:nm-3",
+    "type": "ran-logical-topology.source-entity-delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/source-entity-delete",
+    "data": {
+        "type": "cmHandle",
+        "value": "395221E080CCF0FD1929103B15999999"
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle2.json b/teiv/src/test/resources/cloudeventdata/end-to-end/olde2e/ce-source-entity-delete-cm-handle2.json
new file mode 100644 (file)
index 0000000..81dd6e0
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "specversion": "1.0",
+    "id": "063b0da2-8396-11ee-b962-0242ac120002",
+    "source": "dmi-plugin:nm-3",
+    "type": "ran-logical-topology.source-entity-delete",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/source-entity-delete",
+    "data": {
+        "type": "cmHandle",
+        "value": "395221E080CCF0FD1924103B15873820"
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation.json b/teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation.json
new file mode 100644 (file)
index 0000000..b3e8e85
--- /dev/null
@@ -0,0 +1,54 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-equipment:AntennaModule": [
+                    {
+                        "id": "AntennaModule_1",
+                        "attributes": {
+                            "geo-location": {
+                                "location": {
+                                    "latitude": 12.78232,
+                                    "longitude": 56.7455
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-equipment:Site": [
+                    {
+                        "id": "Site_1",
+                        "attributes": {
+                            "geo-location": {
+                                "location": {
+                                    "latitude": 12.78232,
+                                    "longitude": 56.7455
+                                }
+                            }
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULE_INSTALLED_AT_SITE": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "AntennaModule_1",
+                        "bSide": "Site_1"
+                    }
+                ]
+            }
+        ]
+    }
+}
diff --git a/teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation2.json b/teiv/src/test/resources/cloudeventdata/validation/many-to-one/ce-create-many-to-one-geolocation2.json
new file mode 100644 (file)
index 0000000..48d6056
--- /dev/null
@@ -0,0 +1,39 @@
+{
+    "specversion": "1.0",
+    "id": "a30e63c9-d29e-46ff-b99a-b63ed83f0003",
+    "source": "dmi-plugin:nm-1",
+    "type": "ran-logical-topology.create",
+    "time": "2023-10-25T13:30:01Z",
+    "datacontenttype": "application/json",
+    "dataschema": "https://ties:8080/schemas/v1/r1-topology",
+    "data": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-equipment:Site": [
+                    {
+                        "id": "Site_2",
+                        "attributes": {
+                            "geo-location": {
+                                "location": {
+                                    "latitude": 12.78232,
+                                    "longitude": 56.7455
+                                }
+                            }
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-equipment:ANTENNAMODULE_INSTALLED_AT_SITE": [
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "AntennaModule_1",
+                        "bSide": "Site_2"
+                    }
+                ]
+            }
+        ]
+    }
+}
index df95133..5491c10 100644 (file)
@@ -7,35 +7,41 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:AntennaCapability": [
-                {
-                    "id": "AntennaCapability_1",
-                    "attributes": {
-                        "cmId": {
-                            "cmHandle": "395221E080CCF0FD1924103B15873820",
-                            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:AntennaCapability": [
+                    {
+                        "id": "AntennaCapability_1",
+                        "attributes": {
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873820",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+                            }
                         }
                     }
-                }
-            ],
-            "o-ran-smo-teiv-ran:NRSectorCarrier": [
-                {
-                    "id": "NRSectorCarrier_1",
-                    "attributes": {
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-logical:NRSectorCarrier": [
+                    {
+                        "id": "NRSectorCarrier_1",
+                        "attributes": {
 
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_1"
-                }
-            ]
-        }
+                ]
+            }
+        ]
     }
 }
index 524818d..51805ba 100644 (file)
@@ -7,35 +7,41 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:AntennaCapability": [
-                {
-                    "id": "AntennaCapability_2",
-                    "attributes": {
-                        "cmId": {
-                            "cmHandle": "395221E080CCF0FD1924103B15873820",
-                            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:AntennaCapability": [
+                    {
+                        "id": "AntennaCapability_2",
+                        "attributes": {
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873820",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+                            }
                         }
                     }
-                }
-            ],
-            "o-ran-smo-teiv-ran:NRSectorCarrier": [
-                {
-                    "id": "NRSectorCarrier_2",
-                    "attributes": {
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-logical:NRSectorCarrier": [
+                    {
+                        "id": "NRSectorCarrier_2",
+                        "attributes": {
 
+                        }
+                    }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_2"
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_2",
-                    "bSide": "AntennaCapability_2"
-                }
-            ]
-        }
+                ]
+            }
+        ]
     }
 }
index 1e82283..c7086e3 100644 (file)
@@ -7,27 +7,31 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:AntennaCapability": [
-                {
-                    "id": "AntennaCapability_2",
-                    "attributes": {
-                        "cmId": {
-                            "cmHandle": "395221E080CCF0FD1924103B15873820",
-                            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:AntennaCapability": [
+                    {
+                        "id": "AntennaCapability_2",
+                        "attributes": {
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873820",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+                            }
                         }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_2",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_2"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_2",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_2"
+                    }
+                ]
+            }
+        ]
     }
 }
index 402a2ae..97f2f56 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_2"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_2"
+                    }
+                ]
+            }
+        ]
     }
 }
index c3e131e..8c0e59d 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:NRSectorCarrier": [
-                {
-                    "id": "NRSectorCarrier_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSectorCarrier": [
+                    {
+                        "id": "NRSectorCarrier_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 4404948..7cdb75b 100644 (file)
@@ -7,27 +7,31 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:AntennaCapability": [
-                {
-                    "id": "AntennaCapability_1",
-                    "attributes": {
-                        "cmId": {
-                            "cmHandle": "395221E080CCF0FD1924103B15873820",
-                            "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:AntennaCapability": [
+                    {
+                        "id": "AntennaCapability_1",
+                        "attributes": {
+                            "cmId": {
+                                "cmHandle": "395221E080CCF0FD1924103B15873820",
+                                "resourceIdentifier": "/o-ran-smo-ComTop:NodeCluster[@id=2]"
+                            }
                         }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 35328aa..120c210 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_1",
-                    "bSide": "AntennaCapability_1"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_1",
+                        "bSide": "AntennaCapability_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 7536b5e..6e8f736 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-ran:NRSectorCarrier": [
-                {
-                    "id": "NRSectorCarrier_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSectorCarrier": [
+                    {
+                        "id": "NRSectorCarrier_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
-                {
-                    "id": "Relation_ManyToOne_1",
-                    "aSide": "NRSectorCarrier_2",
-                    "bSide": "AntennaCapability_2"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-logical:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                    {
+                        "id": "Relation_ManyToOne_1",
+                        "aSide": "NRSectorCarrier_2",
+                        "bSide": "AntennaCapability_2"
+                    }
+                ]
+            }
+        ]
     }
 }
index 81d6d14..382accd 100644 (file)
@@ -7,32 +7,38 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ],
-            "o-ran-smo-teiv-cloud-to-logical:GNBCUCPFunction": [
-                {
-                    "id": "GNBCUCPFunction_1",
-                    "attributes": {
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCPFunction_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_1",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 836faff..aeea79d 100644 (file)
@@ -7,32 +7,38 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ],
-            "o-ran-smo-teiv-ran:GNBCUCPFunction": [
-                {
-                    "id": "GNBCUCPFunction_2",
-                    "attributes": {
+                ]
+            },
+            {
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCPFunction_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_2",
-                    "bSide": "GNBCUCPFunction_2"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "GNBCUCPFunction_2"
+                    }
+                ]
+            }
+        ]
     }
 }
index f966e80..1466991 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_2",
-                    "aSide": "ManagedElement_2",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_2",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index fec6466..e2d8b5c 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_2",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index c174ad9..9355350 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-cloud-to-ran:GNBCUCPFunction": [
-                {
-                    "id": "GNBCUCPFunction_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCPFunction_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_1",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 5929e58..e78cdc7 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_1",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 36c989d..f7aa901 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_1",
-                    "bSide": "GNBCUCPFunction_1"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "GNBCUCPFunction_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index c7625d1..cc1cb2b 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-cloud-to-ran:GNBCUCPFunction": [
-                {
-                    "id": "GNBCUCPFunction_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-logical-to-cloud:GNBCUCPFunction": [
+                    {
+                        "id": "GNBCUCPFunction_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
-                {
-                    "id": "Relation_OneToMany_1",
-                    "aSide": "ManagedElement_2",
-                    "bSide": "GNBCUCPFunction_2"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-logical:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": [
+                    {
+                        "id": "Relation_OneToMany_1",
+                        "aSide": "ManagedElement_2",
+                        "bSide": "GNBCUCPFunction_2"
+                    }
+                ]
+            }
+        ]
     }
 }
index d8433c3..941dc32 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_O2O_1",
                         "attributes": {
@@ -19,7 +19,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
                     {
                         "id": "CloudNativeSystem_1",
                         "attributes": {
@@ -31,7 +31,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
                     {
                         "id": "Relation_OneToOne_1",
                         "aSide": "ManagedElement_O2O_1",
index 3e12fed..6939d96 100644 (file)
@@ -9,7 +9,7 @@
     "data": {
         "entities": [
             {
-                "o-ran-smo-teiv-oam:ManagedElement": [
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
                     {
                         "id": "ManagedElement_O2O_2",
                         "attributes": {
@@ -19,7 +19,7 @@
                 ]
             },
             {
-                "o-ran-smo-teiv-cloud:CloudNativeSystem": [
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
                     {
                         "id": "CloudNativeSystem_2",
                         "attributes": {
@@ -31,7 +31,7 @@
         ],
         "relationships": [
             {
-                "o-ran-smo-teiv-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
                     {
                         "id": "Relation_OneToOne_1",
                         "aSide": "ManagedElement_O2O_2",
index 495a9e6..59467dc 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_O2O_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_O2O_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_2",
-                    "aSide": "ManagedElement_O2O_2",
-                    "bSide": "CloudNativeSystem_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_2",
+                        "aSide": "ManagedElement_O2O_2",
+                        "bSide": "CloudNativeSystem_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 7504f91..b3e9240 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_1",
-                    "aSide": "ManagedElement_O2O_2",
-                    "bSide": "CloudNativeSystem_1"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_1",
+                        "aSide": "ManagedElement_O2O_2",
+                        "bSide": "CloudNativeSystem_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index e87aaaa..ec056f0 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-cloud:CloudNativeSystem": [
-                {
-                    "id": "CloudNativeSystem_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
+                    {
+                        "id": "CloudNativeSystem_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_1",
-                    "aSide": "ManagedElement_O2O_1",
-                    "bSide": "CloudNativeSystem_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_1",
+                        "aSide": "ManagedElement_O2O_1",
+                        "bSide": "CloudNativeSystem_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 2151339..e39deda 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-oam:ManagedElement": [
-                {
-                    "id": "ManagedElement_O2O_1",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-oam:ManagedElement": [
+                    {
+                        "id": "ManagedElement_O2O_1",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-ran-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_1",
-                    "aSide": "ManagedElement_1",
-                    "bSide": "CloudNativeSystem_1"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_1",
+                        "aSide": "ManagedElement_1",
+                        "bSide": "CloudNativeSystem_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index 552e334..4d65e2b 100644 (file)
@@ -7,14 +7,16 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "relationships": {
-            "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_1",
-                    "aSide": "ManagedElement_O2O_1",
-                    "bSide": "CloudNativeSystem_1"
-                }
-            ]
-        }
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_1",
+                        "aSide": "ManagedElement_O2O_1",
+                        "bSide": "CloudNativeSystem_1"
+                    }
+                ]
+            }
+        ]
     }
 }
index e4f46f6..202c60d 100644 (file)
@@ -7,24 +7,28 @@
     "datacontenttype": "application/json",
     "dataschema": "https://ties:8080/schemas/v1/r1-topology",
     "data": {
-        "entities": {
-            "o-ran-smo-teiv-cloud:CloudNativeSystem": [
-                {
-                    "id": "CloudNativeSystem_2",
-                    "attributes": {
+        "entities": [
+            {
+                "o-ran-smo-teiv-ran-cloud:CloudNativeSystem": [
+                    {
+                        "id": "CloudNativeSystem_2",
+                        "attributes": {
 
+                        }
                     }
-                }
-            ]
-        },
-        "relationships": {
-            "o-ran-smo-teiv-oam-to-ran:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
-                {
-                    "id": "Relation_OneToOne_1",
-                    "aSide": "ManagedElement_O2O_2",
-                    "bSide": "CloudNativeSystem_2"
-                }
-            ]
-        }
+                ]
+            }
+        ],
+        "relationships": [
+            {
+                "o-ran-smo-teiv-ran-oam-to-cloud:MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM": [
+                    {
+                        "id": "Relation_OneToOne_1",
+                        "aSide": "ManagedElement_O2O_2",
+                        "bSide": "CloudNativeSystem_2"
+                    }
+                ]
+            }
+        ]
     }
 }
diff --git a/teiv/src/test/resources/contracts/classifiers/00_getClassifiers_getTopologyByEntityTypeName.groovy b/teiv/src/test/resources/contracts/classifiers/00_getClassifiers_getTopologyByEntityTypeName.groovy
new file mode 100644 (file)
index 0000000..1ceed6e
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ *  ============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.classifiers
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with classifiers in scopeFilter."
+        request {
+            method GET()
+            url "topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[2]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with classifiers in scopeFilter(OR)"
+        request {
+            method GET()
+            url "topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural'] | /classifiers[@item='test-app-module:Indoor']"
+                },
+                "totalCount": 4
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(4)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[2]', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with classifiers in scopeFilter.(AND)"
+        request {
+            method GET()
+            url "topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                {
+                    "o-ran-smo-teiv-ran:GNBDUFunction": [
+                        {
+                            "classifiers": [
+                                "test-app-module:Rural",
+                                "test-app-module:Weekend"
+                            ],
+                            "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                        }
+                    ]
+                },
+                {
+                    "o-ran-smo-teiv-ran:GNBDUFunction": [
+                        {
+                            "classifiers": [
+                                "test-app-module:Indoor",
+                                "test-app-module:Rural",
+                                "test-app-module:Weekend"
+                            ],
+                            "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                        }
+                    ]
+                }
+            ],
+            "self": {
+                "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+            },
+            "first": {
+                "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+            },
+            "prev": {
+                "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+            },
+            "next": {
+                "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+            },
+            "last": {
+                "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+            },
+            "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[2]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with classifiers in scopeFilter.(Contains)"
+        request {
+            method GET()
+            url "topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'app-module:Rural')]"
+                },
+                "totalCount": 2
+                }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].classifiers[2]', byEquality())
+            }
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/classifiers/01_getClassifiers_getRelationshipsByType.groovy b/teiv/src/test/resources/contracts/classifiers/01_getClassifiers_getRelationshipsByType.groovy
new file mode 100644 (file)
index 0000000..583196d
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  ============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.classifier
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getRelationshipsByType - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+               "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10",
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16",
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural']&targetFilter=/classifiers"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural']&targetFilter=/classifiers"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural']&targetFilter=/classifiers"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural']&targetFilter=/classifiers"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural']&targetFilter=/classifiers"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getRelationshipsByType - EQUALS(AND)"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10",
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16",
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']&targetFilter=/classifiers"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']&targetFilter=/classifiers"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']&targetFilter=/classifiers"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']&targetFilter=/classifiers"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[@item='test-app-module:Rural' and @item='test-app-module:Weekend']&targetFilter=/classifiers"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getRelationshipsByType - CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'ural')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10",
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16",
+                                "classifiers": [
+                                    "module-x:Indoor",
+                                    "module-y:Rural",
+                                    "module-z:Weekend"
+                                ],
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[contains(@item,'ural')]&targetFilter=/classifiers"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[contains(@item,'ural')]&targetFilter=/classifiers"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[contains(@item,'ural')]&targetFilter=/classifiers"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[contains(@item,'ural')]&targetFilter=/classifiers"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/classifiers[contains(@item,'ural')]&targetFilter=/classifiers"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getRelationshipsByType - CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[contains(@item,'NOT_EXISTING')]"
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                    "status": "NOT_FOUND",
+                    "message": "Invalid classifiers",
+                    "details": "The provided classifiers are invalid [NOT_EXISTING]"
+                }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+]
diff --git a/teiv/src/test/resources/contracts/classifiers/02_getClassifiers_getEntitiesByDomain.groovy b/teiv/src/test/resources/contracts/classifiers/02_getClassifiers_getEntitiesByDomain.groovy
new file mode 100644 (file)
index 0000000..2006eb7
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  ============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.classifier
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getEntitiesByDomain - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/GNBDUFunction/classifiers&scopeFilter=/GNBDUFunction/classifiers[@item='test-app-module:Rural']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get classifiers using getEntitiesByDomain - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Indoor",
+                                    "test-app-module:Rural",
+                                    "test-app-module:Weekend"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "classifiers": [
+                                    "test-app-module:Rural"
+                                ],
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=93"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Rural']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+]
diff --git a/teiv/src/test/resources/contracts/classifiers/03_postClassifiers_merge.groovy b/teiv/src/test/resources/contracts/classifiers/03_postClassifiers_merge.groovy
new file mode 100644 (file)
index 0000000..bf9bb1a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ *  ============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.classifier
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "NOT FOUND - 404: Merge classifiers with wrong entity ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                    "status": "NOT_FOUND",
+                    "message": "Resource Not Found",
+                    "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: []"
+                }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Merge classifiers with wrong relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                    "test-app-module:Rural",
+                    "test-app-module:Weekend"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                    "status": "NOT_FOUND",
+                    "message": "Resource Not Found",
+                    "details": "The requested resource with the following ids cannot be found. Entities: [] Relationships: [WRONG_RELATIONSHIP_ID]"
+                }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid classifiers to entities and relationships (add)."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                    "test-app-module:Weekday"
+                ],
+                "entityIds": [
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/classifiers/04_postClassifiers_delete.groovy b/teiv/src/test/resources/contracts/classifiers/04_postClassifiers_delete.groovy
new file mode 100644 (file)
index 0000000..a0a3edd
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ *  ============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.classifier
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "NOT FOUND - 404: Delete classifiers with wrong entity ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers":[
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+            "status": "NOT_FOUND",
+            "message": "Resource Not Found",
+            "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: []"}''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Delete classifiers with wrong relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+            "status": "NOT_FOUND",
+            "message": "Resource Not Found",
+            "details": "The requested resource with the following ids cannot be found. Entities: [] Relationships: [WRONG_RELATIONSHIP_ID]"}''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "BAD REQUEST - 400: Delete classifiers from non-existing schema."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module-wrong:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+            "status": "BAD_REQUEST",
+            "message": "Invalid schema name",
+            "details": "Invalid schema name: test-app-module-wrong"}''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid classifiers, no topology object given."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid classifiers on entities."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid classifiers on relationships."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA",
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid classifiers on entities and relationships."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/classifiers"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "classifiers": [
+                        "test-app-module:Rural",
+                        "test-app-module:Weekend"
+                 ],
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA",
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/00_getAllDomains.groovy b/teiv/src/test/resources/contracts/data/00_getAllDomains.groovy
new file mode 100644 (file)
index 0000000..10e40f3
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology domains."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "EQUIPMENT",
+                        "entityTypes": {
+                            "href": "/domains/EQUIPMENT/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/EQUIPMENT/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "OAM",
+                        "entityTypes": {
+                            "href": "/domains/OAM/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/OAM/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "RAN",
+                        "entityTypes": {
+                            "href": "/domains/RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/RAN/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "REL_EQUIPMENT_RAN",
+                        "entityTypes": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "REL_OAM_RAN",
+                        "entityTypes": {
+                            "href": "/domains/REL_OAM_RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "TEIV",
+                        "entityTypes": {
+                            "href": "/domains/TEIV/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/TEIV/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "TEST",
+                        "entityTypes": {
+                            "href": "/domains/TEST/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/TEST/relationship-types"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains?offset=0&limit=500"
+                },
+                "totalCount": 7
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(7)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entityTypes.href', byEquality())
+                jsonPath('$.items[0].relationshipTypes.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].entityTypes.href', byEquality())
+                jsonPath('$.items[1].relationshipTypes.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].entityTypes.href', byEquality())
+                jsonPath('$.items[2].relationshipTypes.href', byEquality())
+                jsonPath('$.items[3].name', byEquality())
+                jsonPath('$.items[3].entityTypes.href', byEquality())
+                jsonPath('$.items[3].relationshipTypes.href', byEquality())
+                jsonPath('$.items[4].name', byEquality())
+                jsonPath('$.items[4].entityTypes.href', byEquality())
+                jsonPath('$.items[4].relationshipTypes.href', byEquality())
+                jsonPath('$.items[5].name', byEquality())
+                jsonPath('$.items[5].entityTypes.href', byEquality())
+                jsonPath('$.items[5].relationshipTypes.href', byEquality())
+                jsonPath('$.items[6].name', byEquality())
+                jsonPath('$.items[6].entityTypes.href', byEquality())
+                jsonPath('$.items[6].relationshipTypes.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology domains with offset as 2 and limit as 3."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains?offset=2&limit=3"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "RAN",
+                        "entityTypes": {
+                            "href": "/domains/RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/RAN/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "REL_EQUIPMENT_RAN",
+                        "entityTypes": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types"
+                        }
+                    },
+                    {
+                        "name": "REL_OAM_RAN",
+                        "entityTypes": {
+                            "href": "/domains/REL_OAM_RAN/entity-types"
+                        },
+                        "relationshipTypes": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains?offset=2&limit=3"
+                },
+                "first": {
+                    "href": "/domains?offset=0&limit=3"
+                },
+                "prev": {
+                    "href": "/domains?offset=0&limit=3"
+                },
+                "next": {
+                    "href": "/domains?offset=5&limit=3"
+                },
+                "last": {
+                    "href": "/domains?offset=5&limit=3"
+                },
+                "totalCount": 7
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entityTypes.href', byEquality())
+                jsonPath('$.items[0].relationshipTypes.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].entityTypes.href', byEquality())
+                jsonPath('$.items[1].relationshipTypes.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].entityTypes.href', byEquality())
+                jsonPath('$.items[2].relationshipTypes.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all the available topology domains with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains?offset=100"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid Value",
+                "details": "Offset cannot be larger than 6"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/01_getTopologyEntityTypes.groovy b/teiv/src/test/resources/contracts/data/01_getTopologyEntityTypes.groovy
new file mode 100644 (file)
index 0000000..d6a89a8
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology entity types in OAM domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/OAM/entity-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "ManagedElement",
+                        "entities": {
+                            "href": "/domains/OAM/entity-types/ManagedElement/entities"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/OAM/entity-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/OAM/entity-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/OAM/entity-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/OAM/entity-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/OAM/entity-types?offset=0&limit=500"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entities.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology entity types in REL_OAM_RAN domain (includes OAM and RAN domains)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/entity-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "AntennaCapability",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/AntennaCapability/entities"
+                        }
+                    },
+                    {
+                        "name": "ENodeBFunction",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/ENodeBFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "EUtranCell",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/EUtranCell/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFunction",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/GNBCUCPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUUPFunction",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/GNBCUUPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFunction",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/GNBDUFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "LTESectorCarrier",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/LTESectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "ManagedElement",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/ManagedElement/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellCU",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/NRCellCU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellDU",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/NRCellDU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRSectorCarrier",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/NRSectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "Sector",
+                        "entities": {
+                            "href": "/domains/REL_OAM_RAN/entity-types/Sector/entities"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/entity-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/entity-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/entity-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/entity-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/entity-types?offset=0&limit=500"
+                },
+                "totalCount": 12
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(12)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entities.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].entities.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].entities.href', byEquality())
+                jsonPath('$.items[3].name', byEquality())
+                jsonPath('$.items[3].entities.href', byEquality())
+                jsonPath('$.items[4].name', byEquality())
+                jsonPath('$.items[4].entities.href', byEquality())
+                jsonPath('$.items[5].name', byEquality())
+                jsonPath('$.items[5].entities.href', byEquality())
+                jsonPath('$.items[6].name', byEquality())
+                jsonPath('$.items[6].entities.href', byEquality())
+                jsonPath('$.items[7].name', byEquality())
+                jsonPath('$.items[7].entities.href', byEquality())
+                jsonPath('$.items[8].name', byEquality())
+                jsonPath('$.items[8].entities.href', byEquality())
+                jsonPath('$.items[9].name', byEquality())
+                jsonPath('$.items[9].entities.href', byEquality())
+                jsonPath('$.items[10].name', byEquality())
+                jsonPath('$.items[10].entities.href', byEquality())
+                jsonPath('$.items[11].name', byEquality())
+                jsonPath('$.items[11].entities.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology entity types in RAN domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "AntennaCapability",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/AntennaCapability/entities"
+                        }
+                    },
+                    {
+                        "name": "ENodeBFunction",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/ENodeBFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "EUtranCell",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/EUtranCell/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFunction",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/GNBCUCPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUUPFunction",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFunction",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/GNBDUFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "LTESectorCarrier",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/LTESectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellCU",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/NRCellCU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellDU",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/NRCellDU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRSectorCarrier",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/NRSectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "Sector",
+                        "entities": {
+                            "href": "/domains/RAN/entity-types/Sector/entities"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types?offset=0&limit=500"
+                },
+                "totalCount": 11
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(11)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entities.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].entities.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].entities.href', byEquality())
+                jsonPath('$.items[3].name', byEquality())
+                jsonPath('$.items[3].entities.href', byEquality())
+                jsonPath('$.items[4].name', byEquality())
+                jsonPath('$.items[4].entities.href', byEquality())
+                jsonPath('$.items[5].name', byEquality())
+                jsonPath('$.items[5].entities.href', byEquality())
+                jsonPath('$.items[6].name', byEquality())
+                jsonPath('$.items[6].entities.href', byEquality())
+                jsonPath('$.items[7].name', byEquality())
+                jsonPath('$.items[7].entities.href', byEquality())
+                jsonPath('$.items[8].name', byEquality())
+                jsonPath('$.items[8].entities.href', byEquality())
+                jsonPath('$.items[9].name', byEquality())
+                jsonPath('$.items[9].entities.href', byEquality())
+                jsonPath('$.items[10].name', byEquality())
+                jsonPath('$.items[10].entities.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology entity types in TEIV domain (includes all the supported topology domains)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEIV/entity-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "AntennaCapability",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/AntennaCapability/entities"
+                        }
+                    },
+                    {
+                        "name": "AntennaModule",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/AntennaModule/entities"
+                        }
+                    },
+                    {
+                        "name": "ENodeBFunction",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/ENodeBFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "EUtranCell",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/EUtranCell/entities"
+                        }
+                    },
+                    {
+                        "name": "EntityTypeA",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/EntityTypeA/entities"
+                        }
+                    },
+                    {
+                        "name": "EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFunction",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/GNBCUCPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBCUUPFunction",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/GNBCUUPFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFunction",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/GNBDUFunction/entities"
+                        }
+                    },
+                    {
+                        "name": "LTESectorCarrier",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/LTESectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "ManagedElement",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/ManagedElement/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellCU",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/NRCellCU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRCellDU",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/NRCellDU/entities"
+                        }
+                    },
+                    {
+                        "name": "NRSectorCarrier",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/NRSectorCarrier/entities"
+                        }
+                    },
+                    {
+                        "name": "Sector",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/Sector/entities"
+                        }
+                    },
+                    {
+                        "name": "Site",
+                        "entities": {
+                            "href": "/domains/TEIV/entity-types/Site/entities"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEIV/entity-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/TEIV/entity-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/TEIV/entity-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/TEIV/entity-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/TEIV/entity-types?offset=0&limit=500"
+                },
+                "totalCount": 16
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(16)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].entities.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].entities.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].entities.href', byEquality())
+                jsonPath('$.items[3].name', byEquality())
+                jsonPath('$.items[3].entities.href', byEquality())
+                jsonPath('$.items[4].name', byEquality())
+                jsonPath('$.items[4].entities.href', byEquality())
+                jsonPath('$.items[5].name', byEquality())
+                jsonPath('$.items[5].entities.href', byEquality())
+                jsonPath('$.items[6].name', byEquality())
+                jsonPath('$.items[6].entities.href', byEquality())
+                jsonPath('$.items[7].name', byEquality())
+                jsonPath('$.items[7].entities.href', byEquality())
+                jsonPath('$.items[8].name', byEquality())
+                jsonPath('$.items[8].entities.href', byEquality())
+                jsonPath('$.items[9].name', byEquality())
+                jsonPath('$.items[9].entities.href', byEquality())
+                jsonPath('$.items[10].name', byEquality())
+                jsonPath('$.items[10].entities.href', byEquality())
+                jsonPath('$.items[11].name', byEquality())
+                jsonPath('$.items[11].entities.href', byEquality())
+                jsonPath('$.items[12].name', byEquality())
+                jsonPath('$.items[12].entities.href', byEquality())
+                jsonPath('$.items[13].name', byEquality())
+                jsonPath('$.items[13].entities.href', byEquality())
+                jsonPath('$.items[14].name', byEquality())
+                jsonPath('$.items[14].entities.href', byEquality())
+                jsonPath('$.items[15].name', byEquality())
+                jsonPath('$.items[15].entities.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all the available topology entity types with invalid domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/INVALID/entity-types"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Unknown domain",
+                "details": "Unknown domain: INVALID, known domains: [EQUIPMENT, OAM, RAN, REL_EQUIPMENT_RAN, REL_OAM_RAN, TEIV, TEST]"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all the available topology entity types in TEIV domain with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEIV/entity-types?offset=100"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid Value",
+                "details": "Offset cannot be larger than 15"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/02_getTopologyByEntityTypeName.groovy b/teiv/src/test/resources/contracts/data/02_getTopologyByEntityTypeName.groovy
new file mode 100644 (file)
index 0000000..0b100f9
--- /dev/null
@@ -0,0 +1,1488 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type NRCellDU."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=92"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=93"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500"
+                },
+                "totalCount": 6
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(6)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with offset as 1 and limit as 4."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=1&limit=4"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=1&limit=4"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=4"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=4"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=5&limit=4"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=5&limit=4"
+                },
+                "totalCount": 7
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(4)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type NRCellDU with scopeFilter."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type NRCellDU which matches given ID (exact ID match). Alternate to GET entity by ID."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type NRCellDU which contain 'ManagedElement=9,GNBDUFunction=9' in ID (partial ID match)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=500&scopeFilter=/NRCellDU[contains(@id, 'ManagedElement=9,GNBDUFunction=9')]"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaCapability which has serving-antennaModule association with ID that contains 'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A'"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEIV/entity-types/AntennaCapability/entities?scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                  {
+                    "o-ran-smo-teiv-ran:AntennaCapability": [
+                      {
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1"
+                      }
+                    ]
+                  }
+                ],
+                "self": {
+                    "href": "/domains/TEIV/entity-types/AntennaCapability/entities?offset=0&limit=500&scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+                },
+                "first": {
+                    "href": "/domains/TEIV/entity-types/AntennaCapability/entities?offset=0&limit=500&scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+                },
+                "prev": {
+                    "href": "/domains/TEIV/entity-types/AntennaCapability/entities?offset=0&limit=500&scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+                },
+                "next": {
+                    "href": "/domains/TEIV/entity-types/AntennaCapability/entities?offset=0&limit=500&scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+                },
+                "last": {
+                    "href": "/domains/TEIV/entity-types/AntennaCapability/entities?offset=0&limit=500&scopeFilter=/serving-antennaModule[contains(@id,'AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A')]"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:AntennaCapability[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction which has provided-nrCellDu association with ID that contains 'NRCellDU=1'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/provided-nrCellDu[contains(@id,'NRCellDU=1')]"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaModule with targetFilter=/sourceIds"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?targetFilter=/sourceIds"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A",
+                                "sourceIds": [
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaNearUnit=1,RetSubUnit=1",
+                                    "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                                ]
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                                "sourceIds": [
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaNearUnit=1,RetSubUnit=1",
+                                    "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"
+                                ]
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds"
+                },
+                "first": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds"
+                },
+                "prev": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds"
+                },
+                "next": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds"
+                },
+                "last": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[1]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[2]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[3]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-equipment:AntennaModule[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[2]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[3]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaModule with scopeFilter on sourceIds"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']&targetFilter=/sourceIds"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A",
+                                "sourceIds": [
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1",
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaNearUnit=1,RetSubUnit=1",
+                                    "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                                ]
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']"
+                },
+                "first": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']"
+                },
+                "prev": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']"
+                },
+                "next": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']"
+                },
+                "last": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1']"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[1]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[2]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-equipment:AntennaModule[0].sourceIds[3]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get empty items array when no entity exists of given filter criteria."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=898989]"
+                },
+                "totalCount": 0
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(0)
+                })
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities by a long named entity type."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=0&limit=1&targetFilter=/attributes"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters": [
+                            {
+                                "attributes": {
+                                    "attributeA2WithAttributeNameLengthLongerThanSixtyThreeCharacters": 9223372036854775807,
+                                    "attributeA6WithAttributeNameLengthLongerThanSixtyThreeCharacters": [
+                                        "1000",
+                                        "2000"
+                                    ],
+                                    "attributeA5WithAttributeNameLengthLongerThanSixtyThreeCharacters": 1.1,
+                                    "attributeA4WithAttributeNameLengthLongerThanSixtyThreeCharacters": -9223372036854775807,
+                                    "attributeA3WithAttributeNameLengthLongerThanSixtyThreeCharacters": 2147483647,
+                                    "attributeA7WithAttributeNameLengthLongerThanSixtyThreeCharacters": {
+                                        "mcc": "01",
+                                        "mnc": "234"
+                                    },
+                                    "attributeA1WithAttributeNameLengthLongerThanSixtyThreeCharacters": "someStringValue"
+                                },
+                                "id": "LongEntityType1"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=0&limit=1&targetFilter=/attributes"
+                },
+                "first": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=0&limit=1&targetFilter=/attributes"
+                },
+                "prev": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=0&limit=1&targetFilter=/attributes"
+                },
+                "next": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=1&limit=1&targetFilter=/attributes"
+                },
+                "last": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities?offset=2&limit=1&targetFilter=/attributes"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].id', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA1WithAttributeNameLengthLongerThanSixtyThreeCharacters', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA2WithAttributeNameLengthLongerThanSixtyThreeCharacters', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA3WithAttributeNameLengthLongerThanSixtyThreeCharacters', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA4WithAttributeNameLengthLongerThanSixtyThreeCharacters', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA5WithAttributeNameLengthLongerThanSixtyThreeCharacters', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA6WithAttributeNameLengthLongerThanSixtyThreeCharacters[0]', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA6WithAttributeNameLengthLongerThanSixtyThreeCharacters[1]', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA7WithAttributeNameLengthLongerThanSixtyThreeCharacters.mcc', byEquality())
+                jsonPath('$.items[0].test-built-in-module:EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[0].attributes.attributeA7WithAttributeNameLengthLongerThanSixtyThreeCharacters.mnc', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type NRCellDU with scopeFilter on association."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']&targetFilter=/attributes(nCI)"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                  {
+                    "o-ran-smo-teiv-ran:NRCellDU": [
+                      {
+                        "attributes": {
+                          "nCI": 1
+                        },
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                      }
+                    ]
+                  },
+                  {
+                    "o-ran-smo-teiv-ran:NRCellDU": [
+                      {
+                        "attributes": {
+                          "nCI": 2
+                        },
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2"
+                      }
+                    ]
+                  },
+                  {
+                    "o-ran-smo-teiv-ran:NRCellDU": [
+                      {
+                        "attributes": {
+                          "nCI": 3
+                        },
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3"
+                      }
+                    ]
+                  }
+                ],
+                "self": {
+                  "href": "/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&targetFilter=/attributes(nCI)&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']"
+                },
+                "first": {
+                  "href": "/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&targetFilter=/attributes(nCI)&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']"
+                },
+                "prev": {
+                  "href": "/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&targetFilter=/attributes(nCI)&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']"
+                },
+                "next": {
+                  "href": "/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&targetFilter=/attributes(nCI)&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']"
+                },
+                "last": {
+                  "href": "/domains/RAN/entity-types/NRCellDU/entities?offset=0&limit=100&targetFilter=/attributes(nCI)&scopeFilter=/provided-by-gnbduFunction[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].attributes.nCI', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].attributes.nCI', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].attributes.nCI', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter on sourceIds and gNBId with AND condition."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']&targetFilter=/attributes;/sourceIds"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "82"
+                                    },
+                                    "gNBId": 10,
+                                    "gNBDUId": null,
+                                    "gNBIdLength": 2
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "sourceIds": [
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                    "urn:cmHandle:72FDA73D085F138FECC974CB91F1450E"
+                                ]
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes;/sourceIds&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes;/sourceIds&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes;/sourceIds&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes;/sourceIds&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes;/sourceIds&scopeFilter=/attributes[@gNBId=10]; /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter with AND an OR conditions."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]&targetFilter=/GNBDUFunction"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+            "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/GNBDUFunction&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/GNBDUFunction&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/GNBDUFunction&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/GNBDUFunction&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/GNBDUFunction&scopeFilter=/attributes[@gNBId=10 or @gNBId=13]; /attributes[@gNBIdLength = 2]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter with AND an OR conditions."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']&targetFilter=/id"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/id&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/id&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/id&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/id&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/id&scopeFilter=/attributes[@gNBId = 9 and @gNBIdLength = 1] | /sourceIds[@item = 'urn:cmHandle:72FDA73D085F138FECC974CB91F1450E']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter on complex attribute STRING value - EQUALS - KEY AND VALUE EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "83"
+                                    }
+                                }
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "86"
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter on complex attribute STRING value - EQUALS - KEY AND VALUE EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "83"
+                                    }
+                                }
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "86"
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[@mcc='456']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type GNBDUFunction with scopeFilter on complex attribute STRING value - CONTAINS - KEY AND VALUE EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "789",
+                                        "mnc": "84"
+                                    }
+                                }
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19",
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "789",
+                                        "mnc": "87"
+                                    }
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/attributes(dUpLMNId)&scopeFilter=/attributes/dUpLMNId[contains(@mcc,'78')]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaCapability with scopeFilter on complex attribute STRING array - EXACT MATCH - VALUE EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:AntennaCapability": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1",
+                                "attributes": {
+                                    "eUtranFqBands": [
+                                        "123",
+                                        "456",
+                                        "789"
+                                    ]
+                                }
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:AntennaCapability": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "attributes": {
+                                    "eUtranFqBands": [
+                                        "123",
+                                        "456",
+                                        "789"
+                                    ]
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item='456']"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:AntennaCapability[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:AntennaCapability[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaCapability with scopeFilter on complex attribute INTEGER array - EXACT MATCH - VALUE NOT EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[@item=456]"
+                },
+                "totalCount": 0
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(0)
+                })
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaCapability with scopeFilter on complex attribute STRING array - PARTIAL MATCH - VALUE EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:AntennaCapability": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1",
+                                "attributes": {
+                                    "eUtranFqBands": [
+                                        "123",
+                                        "456",
+                                        "789"
+                                    ]
+                                }
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:AntennaCapability": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "attributes": {
+                                    "eUtranFqBands": [
+                                        "123",
+                                        "456",
+                                        "789"
+                                    ]
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'45')]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:AntennaCapability[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:AntennaCapability[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all topology entities of type AntennaCapability with scopeFilter on complex attribute STRING array - PARTIAL MATCH - VALUE NOT EXISTS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/AntennaCapability/entities?offset=0&limit=500&targetFilter=/attributes(eUtranFqBands)&scopeFilter=/attributes/eUtranFqBands[contains(@item,'999')]"
+                },
+                "totalCount": 0
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(0)
+                })
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities of type AntennaModule with scopeFilter on geographic attribute"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A",
+                                "attributes": {
+                                    "geo-location": "POINT(39.4019881 67.9419888)"
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+                },
+                "first": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+                },
+                "prev": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+                },
+                "next": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+                },
+                "last": {
+                    "href": "/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 67.9419888)']"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+            }
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get entities of type AntennaModule with scopeFilter on geographic attribute - invalid format"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = '(39.4019881 67.9419888)']"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid query condition",
+                "details": "Invalid geographic format."
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get entities of type AntennaModule with scopeFilter on geographic attribute - 1 coordinate"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881)']"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid query condition",
+                "details": "A point should have 2 coordinates (longitude and latitude)."
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get entities of type AntennaModule with scopeFilter on geographic attribute - invalid coordinate"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/AntennaModule/entities?offset=0&limit=500&targetFilter=/attributes(geo-location)&scopeFilter=/attributes[@geo-location = 'POINT(39.4019881 ABC)']"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid query condition",
+                "details": "Invalid coordinate: ABC"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all topology entities for an entity type that is not in the domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/EQUIPMENT/entity-types/NRCellDU/entities"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Unknown entity type",
+                "details": "Entity type NRCellDU is not part of the domain EQUIPMENT, known entity types: [AntennaModule, Site]"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all topology entities for wrong entity type name."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU1/entities"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Unknown entity type",
+                "details": "Entity type NRCellDU1 is not part of the model, known entity types: [AntennaCapability, AntennaModule, ENodeBFunction, EUtranCell, EntityTypeA, EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters, GNBCUCPFunction, GNBCUUPFunction, GNBDUFunction, LTESectorCarrier, ManagedElement, NRCellCU, NRCellDU, NRSectorCarrier, Sector, Site]"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all topology entities with invalid scopeFilter (attribute not prefixed with @)"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBCUCPFunction/entities?scopeFilter=/attributes[contains(gNBCUName,'Cucp-1')]"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Grammar error",
+                "details": "no viable alternative at input '[contains(gNBCUName' at line 1:21"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all topology entities of type GNBCUUPFunction with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "topology-inventory/v1alpha11/domains/RAN/entity-types/GNBCUUPFunction/entities?offset=10000"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid Value",
+                "details": "Offset cannot be larger than 6"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/03_getTopologyById.groovy b/teiv/src/test/resources/contracts/data/03_getTopologyById.groovy
new file mode 100644 (file)
index 0000000..2ff0980
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get topology for ManagedElement entity with id 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9' in OAM domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/yang.data+json')
+            }
+            body('''{
+                "o-ran-smo-teiv-oam:ManagedElement": [
+                    {
+                        "decorators": {},
+                        "classifiers": [],
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9",
+                            "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                        ]
+                    }
+                ]
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology for GNBDUFunction entity with id 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9' with REL_EQUIPMENT_RAN (domain including other domains)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/yang.data+json')
+            }
+            body('''{
+                "o-ran-smo-teiv-ran:GNBDUFunction": [
+                    {
+                        "decorators": {
+                            "test-app-module:textdata": "ORAN"
+                        },
+                        "classifiers": [
+                            "test-app-module:Indoor",
+                            "test-app-module:Weekend"
+                        ],
+                        "attributes": {
+                            "dUpLMNId": {
+                                "mcc": "123",
+                                "mnc": "82"
+                            },
+                            "gNBDUId": null,
+                            "gNBId": 9,
+                            "gNBIdLength": 1
+                        },
+                        "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                        "sourceIds": [
+                            "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                            "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                        ]
+                    }
+                ]
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get topology for GNBDUFunction entity with non existing id 'non-existing-id'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/entity-types/GNBDUFunction/entities/non-existing-id"
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource is not found"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/04_getAllRelationshipsForEntityId.groovy b/teiv/src/test/resources/contracts/data/04_getAllRelationshipsForEntityId.groovy
new file mode 100644 (file)
index 0000000..0ed0aa7
--- /dev/null
@@ -0,0 +1,693 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for entity type NRCellDU with ID urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+              "items": [
+                {
+                  "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                      "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                      "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                      "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+                    }
+                  ]
+                },
+                {
+                  "o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER": [
+                    {
+                      "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=1",
+                      "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                      "id": "urn:o-ran:smo:teiv:sha512:NRCELLDU_USES_NRSECTORCARRIER=7B9425BBD6977FEA6C180F6078CFBAEBE65400223B29E0EFA4F38424FAD66C690806778909177ECF1457CAC18E5BCF6FA4F24E3ECE524C89DE68108708D6D876"
+                    }
+                  ]
+                },
+                {
+                  "o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU": [
+                    {
+                      "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                      "aSide": "Sector=2",
+                      "id": "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463"
+                    }
+                  ]
+                }
+              ],
+              "self": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+              },
+              "first": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+              },
+              "prev": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+              },
+              "next": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+              },
+              "last": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100"
+              },
+              "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].aSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].bSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].bSide', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for entity type NRCellDU  with ID urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1 & targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU"
+                },
+                "totalCount": 1
+}''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for entity type NRCellDU  with ID urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1 & targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "aSide": "Sector=2",
+                                "id": "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1/relationships?offset=0&limit=100&targetFilter=/GNBDUFUNCTION_PROVIDES_NRCELLDU;/SECTOR_GROUPS_NRCELLDU"
+                },
+                "totalCount": 2
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for entity type GNBDUFunction with ID urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1. & scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9/relationships?offset=0&limit=100&scopeFilter=/provided-nrCellDu[@id = 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "totalCount": 1
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for entity type NRCellDU with ID urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3 with limit as 2."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?limit=2"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=714C1B73945C298CAA03FE0D800053CDD1C571BBF375DC647B9F23FDA861CEB369832A3593BB1AA4B8A7245AD187ED24ADDF6FB147130827CDC17BA8370C4838"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=3",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3",
+                                "id": "urn:o-ran:smo:teiv:sha512:NRCELLDU_USES_NRSECTORCARRIER=950ED4540349F9859CEA9E47884A28CD567BDD2505A3C5335C8851A7AADF2AF65542157BB42D607EE3847E4223D76DE88B90762D0590E48693822FD6DCAE60CD"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=0&limit=2"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=0&limit=2"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=0&limit=2"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=2&limit=2"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=2&limit=2"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].aSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCELLDU_USES_NRSECTORCARRIER[0].bSide', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for long entity type name with id as LongEntityType1 (OneToOne, ManyToOne, ManyToMany and Same Entity with aSide of relationship)"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType1",
+                                "aSide": "EntityType1",
+                                "id": "RelId_OneToOne_EntityType1_LongEntityType1"
+                            }
+                        ]
+                    },
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    },
+                    {
+                        "test-built-in-module:ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType1",
+                                "aSide": "EntityType2",
+                                "id": "Rel_ManyToOne_EntityType2_LongEntityType1"
+                            }
+                        ]
+                    },
+                    {
+                        "test-built-in-module:ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType1",
+                                "aSide": "EntityType1",
+                                "id": "Rel_ManyToMany_EntityType1_LongEntityType1"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500"
+                },
+                "totalCount": 4
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for long entity type name with id as LongEntityType2  (OneToMany and Same Entity with bSide of relationship)"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+            "items": [
+                {
+                    "test-built-in-module:ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                        {
+                            "bSide": "LongEntityType2",
+                            "aSide": "EntityType2",
+                            "id": "Rel_OneToMany_EntityType2_LongEntityType2"
+                        }
+                    ]
+                },
+                {
+                    "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                        {
+                            "bSide": "LongEntityType2",
+                            "aSide": "LongEntityType1",
+                            "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                        }
+                    ]
+                },
+                {
+                    "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                        {
+                            "bSide": "LongEntityType3",
+                            "aSide": "LongEntityType2",
+                            "id": "Rel_OneToOne_SameEntity_LongEntityType2_LongEntityType3"
+                        }
+                    ]
+                }
+            ],
+            "self": {
+                "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500"
+            },
+            "first": {
+                "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500"
+            },
+            "prev": {
+                "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500"
+            },
+            "next": {
+                "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500"
+            },
+            "last": {
+                "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500"
+            },
+            "totalCount": 3
+        }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for long entity type name with id as LongEntityType1 and with scope filter on sourceIds"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']&targetFilter=/sourceIds"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']"
+                },
+                "first": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']"
+                },
+                "prev": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']"
+                },
+                "next": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']"
+                },
+                "last": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType1/relationships?offset=0&limit=500&targetFilter=/sourceIds&scopeFilter=/sourceIds[@item = 'urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616']"
+                },
+                "totalCount": 1
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for long entity type name with id as LongEntityType3 and with scope filter on classifiers"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?scopeFilter=/classifiers[@item='test-app-module:Weekend']&targetFilter=/classifiers"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType3",
+                                "aSide": "LongEntityType2",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType2_LongEntityType3"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Weekend']"
+                },
+                "first": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Weekend']"
+                },
+                "prev": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Weekend']"
+                },
+                "next": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Weekend']"
+                },
+                "last": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType3/relationships?offset=0&limit=500&targetFilter=/classifiers&scopeFilter=/classifiers[@item='test-app-module:Weekend']"
+                },
+                "totalCount": 1
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for long entity type name with id as LongEntityType2 and with scope filter on decorators"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]&targetFilter=/decorators"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    },
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType3",
+                                "aSide": "LongEntityType2",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType2_LongEntityType3"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]"
+                },
+                "first": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]"
+                },
+                "prev": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]"
+                },
+                "next": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]"
+                },
+                "last": {
+                    "href": "/domains/TEST/entity-types/EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters/entities/LongEntityType2/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'ORAN')]"
+                },
+                "totalCount": 2
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Return items as empty for a entity with no relationship"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+            "items": [],
+            "self": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships?offset=0&limit=500"
+            },
+            "first": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships?offset=0&limit=500"
+            },
+            "prev": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships?offset=0&limit=500"
+            },
+            "next": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships?offset=0&limit=500"
+            },
+            "last": {
+                "href": "/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91/relationships?offset=0&limit=500"
+            },
+            "totalCount": 0
+        }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for an entity id where there exists no relationships for the entity type in the given domain"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBCUUPFunction/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9/relationships?offset=0&limit=500"
+                },
+                "totalCount": 0
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all relationships for an entity id where there exists no relationships in the given domain"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+                },
+                "first": {
+                    "href": "/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+                },
+                "prev": {
+                    "href": "/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+                },
+                "next": {
+                    "href": "/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+                },
+                "last": {
+                    "href": "/domains/OAM/entity-types/ManagedElement/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9/relationships?offset=0&limit=100"
+                },
+                "totalCount": 0
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all relationships for NRCellDU entity with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3/relationships?offset=1000"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+            "status": "BAD_REQUEST",
+            "message": "Invalid Value",
+            "details": "Offset cannot be larger than 2"
+        }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 404: Get all relationships for non existing NRCellDU id."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/non-existent/relationships"
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+            "status": "NOT_FOUND",
+            "message": "Resource Not Found",
+            "details": "The requested resource is not found"
+        }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/05_getRelationshipTypes.groovy b/teiv/src/test/resources/contracts/data/05_getRelationshipTypes.groovy
new file mode 100644 (file)
index 0000000..fd50f6e
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology relationships types in REL_OAM_RAN domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/ENODEBFUNCTION_PROVIDES_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "EUTRANCELL_USES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/EUTRANCELL_USES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/GNBCUCPFUNCTION_PROVIDES_NRCELLCU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "LTESECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/LTESECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRCELLDU_USES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRSECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/SECTOR_GROUPS_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/REL_OAM_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types?offset=0&limit=500"
+                },
+                "totalCount": 15
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(15)
+                })
+                jsonPath('$.items[0].name', byEquality())
+                jsonPath('$.items[0].relationships.href', byEquality())
+                jsonPath('$.items[1].name', byEquality())
+                jsonPath('$.items[1].relationships.href', byEquality())
+                jsonPath('$.items[2].name', byEquality())
+                jsonPath('$.items[2].relationships.href', byEquality())
+                jsonPath('$.items[3].name', byEquality())
+                jsonPath('$.items[3].relationships.href', byEquality())
+                jsonPath('$.items[4].name', byEquality())
+                jsonPath('$.items[4].relationships.href', byEquality())
+                jsonPath('$.items[5].name', byEquality())
+                jsonPath('$.items[5].relationships.href', byEquality())
+                jsonPath('$.items[6].name', byEquality())
+                jsonPath('$.items[6].relationships.href', byEquality())
+                jsonPath('$.items[7].name', byEquality())
+                jsonPath('$.items[7].relationships.href', byEquality())
+                jsonPath('$.items[8].name', byEquality())
+                jsonPath('$.items[8].relationships.href', byEquality())
+                jsonPath('$.items[9].name', byEquality())
+                jsonPath('$.items[9].relationships.href', byEquality())
+                jsonPath('$.items[10].name', byEquality())
+                jsonPath('$.items[10].relationships.href', byEquality())
+                jsonPath('$.items[11].name', byEquality())
+                jsonPath('$.items[11].relationships.href', byEquality())
+                jsonPath('$.items[12].name', byEquality())
+                jsonPath('$.items[12].relationships.href', byEquality())
+                jsonPath('$.items[13].name', byEquality())
+                jsonPath('$.items[13].relationships.href', byEquality())
+                jsonPath('$.items[14].name', byEquality())
+                jsonPath('$.items[14].relationships.href', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology relationship types in REL_EQUIPMENT_RAN domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/relationship-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "ANTENNAMODULE_INSTALLED_AT_SITE",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_INSTALLED_AT_SITE/relationships"
+                        }
+                    },
+                    {
+                        "name": "ANTENNAMODULE_SERVES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ENODEBFUNCTION_PROVIDES_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "EUTRANCELL_USES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/EUTRANCELL_USES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/GNBCUCPFUNCTION_PROVIDES_NRCELLCU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "LTESECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/LTESECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRCELLDU_USES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRSECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_ANTENNAMODULE",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_ANTENNAMODULE/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types?offset=0&limit=500"
+                },
+                "totalCount": 14
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology relationship types in RAN domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/relationship-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/ENODEBFUNCTION_PROVIDES_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "EUTRANCELL_USES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/EUTRANCELL_USES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/GNBCUCPFUNCTION_PROVIDES_NRCELLCU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "LTESECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/LTESECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRCELLDU_USES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRSECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/SECTOR_GROUPS_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/relationship-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/RAN/relationship-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/RAN/relationship-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/RAN/relationship-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/RAN/relationship-types?offset=0&limit=500"
+                },
+                "totalCount": 11
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get all the available topology relationship types in TEIV."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEIV/relationship-types"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "name": "ANTENNAMODULE_INSTALLED_AT_SITE",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ANTENNAMODULE_INSTALLED_AT_SITE/relationships"
+                        }
+                    },
+                    {
+                        "name": "ANTENNAMODULE_SERVES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENODEBFUNCTION_PROVIDES_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+                        }
+                    },
+                    {
+                        "name": "ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+                        }
+                    },
+                    {
+                        "name": "EUTRANCELL_USES_LTESECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/EUTRANCELL_USES_LTESECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBCUCPFUNCTION_PROVIDES_NRCELLCU",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/GNBCUCPFUNCTION_PROVIDES_NRCELLCU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships"
+                        }
+                    },
+                    {
+                        "name": "GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "LTESECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/LTESECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_ENODEBFUNCTION",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "MANAGEDELEMENT_MANAGES_GNBDUFUNCTION",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRCELLDU_USES_NRSECTORCARRIER",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/NRCELLDU_USES_NRSECTORCARRIER/relationships"
+                        }
+                    },
+                    {
+                        "name": "NRSECTORCARRIER_USES_ANTENNACAPABILITY",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_ANTENNAMODULE",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/SECTOR_GROUPS_ANTENNAMODULE/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_EUTRANCELL",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/SECTOR_GROUPS_EUTRANCELL/relationships"
+                        }
+                    },
+                    {
+                        "name": "SECTOR_GROUPS_NRCELLDU",
+                        "relationships": {
+                            "href": "/domains/TEIV/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships"
+                        }
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEIV/relationship-types?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/TEIV/relationship-types?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/TEIV/relationship-types?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/TEIV/relationship-types?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/TEIV/relationship-types?offset=0&limit=500"
+                },
+                "totalCount": 23
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get all the available topology relationship types in invalid domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/INVALID/relationship-types"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Unknown domain",
+                "details": "Unknown domain: INVALID, known domains: [EQUIPMENT, OAM, RAN, REL_EQUIPMENT_RAN, REL_OAM_RAN, TEIV, TEST]"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/06_getRelationshipsByType.groovy b/teiv/src/test/resources/contracts/data/06_getRelationshipsByType.groovy
new file mode 100644 (file)
index 0000000..ac68e26
--- /dev/null
@@ -0,0 +1,707 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type MANAGEDELEMENT_MANAGES_GNBDUFUNCTION(OneToMany)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6BD25E5C8FB7842F69010736253CC47F43535D7238E9E9A03E8092E8C019C83270DE47C96EF1049C40B83A130F9F129AE93B9C8538B6B004AE89BD0A098E48DD"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=9243B48F7D6A6CF471226915C74CF5FE4BDA6FA3CF7D897473007B46DF7FC50230BD6B8B4256116A6AFBF4D822CF9379EB56DE9490C1C0B54238263F2574B426"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBDUFunction=28",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=ADD4A82DFBAF0409FA9D3C929A09314088627B447C733429D4EE7AAE2FFAEE4894F90826B6814B63431EC07140783C7861E463C5AF8330E29469D704675EAB43"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500"
+                },
+                "totalCount": 7
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(7)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+                jsonPath('$.items[6].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[6].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].aSide', byEquality())
+                jsonPath('$.items[6].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].bSide', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type NRSECTORCARRIER_USES_ANTENNACAPABILITY(ManyToOne)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=1",
+                                "id": "urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=11EDFC31E2BE240D3CB15DB1A3FA3B78C828524BC8FCA3365A615129A61A627C21DA8EBF6DD788CDBDEC668344D1F79A371749083D6AE04DDDD57CB4FA8C3ECB"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=3",
+                                "id": "urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=1B891FCC4F5479BC71127ED2EB43EA26AC3452F8C47792786373442C10BBC408FE5B779BF1CF732C81220803342F4FB969E348F9C5CEEDEC78F9764E186C633F"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRSECTORCARRIER_USES_ANTENNACAPABILITY": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=2",
+                                "id": "urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=27DF07D016FE349EC565DE2FB09303EE7D8700346624046F79D8DAC176E7FA221E918E3030758B51931C430919E14FD7D16720460F6E1585000C72874A1641DA"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/RAN/relationship-types/NRSECTORCARRIER_USES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "totalCount": 3
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type ANTENNAMODULE_SERVES_ANTENNACAPABILITY(ManyToMany)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1",
+                                "aSide": "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                                "id": "urn:o-ran:smo:teiv:sha512:ANTENNAMODULE_SERVES_ANTENNACAPABILITY=8940999E2069725B463052BC35572FDB888C7B734459EE78A01B9F91E2607D87356425BC8EFF0B1C9057D852A4D3F9E1B09479D32FEE68C65EF2821B65F7BD80"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-equipment-ran:ANTENNAMODULE_SERVES_ANTENNACAPABILITY": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1",
+                                "aSide": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A",
+                                "id": "urn:o-ran:smo:teiv:sha512:ANTENNAMODULE_SERVES_ANTENNACAPABILITY=ABD52B030DF1169F9F41C898913EF30F7BB5741F53352F482310B280C90AC569B7D31D52A2BB41F1F0099AE1EDD56CACF0B285D145A5584D376DD45DED1E2D65"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/ANTENNAMODULE_SERVES_ANTENNACAPABILITY/relationships?offset=0&limit=500"
+                },
+                "totalCount": 2
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type MANAGEDELEMENT_MANAGES_GNBDUFUNCTION with offset=1 and limit=1."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=1&limit=1"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19",
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6BD25E5C8FB7842F69010736253CC47F43535D7238E9E9A03E8092E8C019C83270DE47C96EF1049C40B83A130F9F129AE93B9C8538B6B004AE89BD0A098E48DD"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=1&limit=1"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=1"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=1"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=2&limit=1"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=6&limit=1"
+                },
+                "totalCount": 7
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS where used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters id is 'Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+                },
+                "first": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+                },
+                "prev": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+                },
+                "next": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+                },
+                "last": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType1']"
+                },
+                "totalCount": 1
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS where used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters id is 'Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+                },
+                "first": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+                },
+                "prev": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+                },
+                "next": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+                },
+                "last": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=100&scopeFilter=/used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters[@id='LongEntityType2']"
+                },
+                "totalCount": 1
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type SECTOR_GROUPS_NRCELLDU where grouped-nrCellDu id is 'urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                  {
+                    "o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU": [
+                      {
+                        "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                        "aSide": "Sector=2",
+                        "id": "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463"
+                      }
+                    ]
+                  }
+                ],
+                "self": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "first": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "prev": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "next": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "last": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/grouped-nrCellDu[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1']"
+                },
+                "totalCount": 1
+                }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].bSide', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships of type SECTOR_GROUPS_NRCELLDU where relation id is 'urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463'."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                  {
+                    "o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU": [
+                      {
+                        "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                        "aSide": "Sector=2",
+                        "id": "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463"
+                      }
+                    ]
+                  }
+                ],
+                "self": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+                },
+                "first": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+                },
+                "prev": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+                },
+                "next": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+                },
+                "last": {
+                  "href": "/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships?offset=0&limit=100&scopeFilter=/SECTOR_GROUPS_NRCELLDU[@id='urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463']"
+                },
+                "totalCount": 1
+                }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:SECTOR_GROUPS_NRCELLDU[0].bSide', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology relationships for same entity long relationship name of type ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType2",
+                                "aSide": "LongEntityType1",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2"
+                            }
+                        ]
+                    },
+                    {
+                        "test-built-in-module:ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS": [
+                            {
+                                "bSide": "LongEntityType3",
+                                "aSide": "LongEntityType2",
+                                "id": "Rel_OneToOne_SameEntity_LongEntityType2_LongEntityType3"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/TEST/relationship-types/ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS/relationships?offset=0&limit=500"
+                },
+                "totalCount": 2
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get empty items array when no relationship exists of given type."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION": []
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_ENODEBFUNCTION/relationships?offset=0&limit=500"
+                },
+                "totalCount": 0
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get relationship by type checking total count"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                           {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                           {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=714C1B73945C298CAA03FE0D800053CDD1C571BBF375DC647B9F23FDA861CEB369832A3593BB1AA4B8A7245AD187ED24ADDF6FB147130827CDC17BA8370C4838"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                           {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=93",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=7723E5D5B3332E0890EAA620C77A6A47065E15A2EA28AD83F3B3CFEA5A7E3BB5965AE78890F1BF000EAA89BF8DE209E506192BF5EA6871426603ED76CBFAF088"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                           {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=78ECC09D4832328976EF0F9C19699EE05D98E3837368D386AE39AD027543494AC620086BD2A7403DACFAA7B474B3DEBD313E0906F1EDE7FA2B584E16542A706A"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                           {
+                                "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=92",
+                                "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19",
+                                "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=DDECCEFB8831FA4EB21B121BA35EAB07ED8D841B5A38580C5F3AD11E66FE73D2FC42E823C6C73288860C7562B610C3D07B6C39FD386171A3BE622096F4B3D006"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=500"
+                },
+                "first": {
+                    "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=500"
+                },
+                "prev": {
+                    "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=500"
+                },
+                "next": {
+                    "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=500"
+                },
+                "last": {
+                    "href": "/domains/RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships?offset=0&limit=500"
+                },
+                "totalCount": 5
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(5)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].id', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].aSide', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU[0].bSide', byEquality())
+                jsonPath('$.totalCount', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get topology relationships of type MANAGEDELEMENT_MANAGES_GNBDUFUNCTION with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=1000"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid Value",
+                "details": "Offset cannot be larger than 6"
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get topology relationships of type SECTOR_GROUPS_NRCELLDU with wrong domain."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/OAM/relationship-types/SECTOR_GROUPS_NRCELLDU/relationships"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Unknown relationship type",
+                "details": "Relationship type SECTOR_GROUPS_NRCELLDU is not part of the domain OAM, known relationship types: []"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/07_getRelationshipById.groovy b/teiv/src/test/resources/contracts/data/07_getRelationshipById.groovy
new file mode 100644 (file)
index 0000000..d5f731b
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get relationship with specified id"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_EQUIPMENT_RAN/relationship-types/SECTOR_GROUPS_ANTENNAMODULE/relationships/urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/yang.data+json')
+            }
+            body('''{
+                "o-ran-smo-teiv-rel-equipment-ran:SECTOR_GROUPS_ANTENNAMODULE": [
+                    {
+                        "bSide": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A",
+                        "aSide": "Sector=2",
+                        "id": "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                        "sourceIds": []
+                    }
+                ]
+            }''')
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get relationship with specified id"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/GNBDUFUNCTION_PROVIDES_NRCELLDU/relationships/urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/yang.data+json')
+            }
+            body('''{
+                "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
+                    {
+                        "bSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                        "aSide": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9",
+                        "id": "urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C",
+                        "sourceIds": []
+                    }
+                ]
+            }''')
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get relationship with non existing id 'non-existing-id'"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships/non-existing-id"
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource is not found"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/data/08_getEntitiesByDomain.groovy b/teiv/src/test/resources/contracts/data/08_getEntitiesByDomain.groovy
new file mode 100644 (file)
index 0000000..1f4026b
--- /dev/null
@@ -0,0 +1,784 @@
+/*
+ *  ============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.data
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with targetFilter=/GNBDUFunction/attributes(gNBDUId)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": 16
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBDUFunction=28"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "gNBDUId": null
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/attributes(gNBDUId)"
+                },
+                "totalCount": 7
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(7)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byRegex(anInteger()).asInteger())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+                jsonPath('$.items[5].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+                jsonPath('$.items[6].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[6].o-ran-smo-teiv-ran:GNBDUFunction[0].attributes.gNBDUId', byNull())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in TEIV domain with targetFilter=/AntennaModule;/GNBCUUPFunction."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUUPFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBCUUPFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBCUUPFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBCUUPFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBCUUPFunction=19"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBCUUPFunction=28"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-equipment:AntennaModule": [
+                            {
+                                "id": "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+                },
+                "first": {
+                    "href": "/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+                },
+                "prev": {
+                    "href": "/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+                },
+                "next": {
+                    "href": "/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+                },
+                "last": {
+                    "href": "/domains/TEIV/entities?offset=0&limit=100&targetFilter=/AntennaModule;/GNBCUUPFunction"
+                },
+                "totalCount": 9
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(9)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[3].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[4].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[5].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[6].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[7].o-ran-smo-teiv-equipment:AntennaModule[0].id', byEquality())
+                jsonPath('$.items[8].o-ran-smo-teiv-equipment:AntennaModule[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')] or /NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')] and targetFilter=/NRCellDU/sourceIds."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]&targetFilter=/NRCellDU/sourceIds"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "sourceIds": [
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                    "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                                    ]
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU":[
+                            {
+                                "id":"urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2",
+                                "sourceIds":[
+                                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2",
+                                    "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"
+                                ]
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/sourceIds&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/sourceIds&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/sourceIds&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/sourceIds&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/sourceIds&scopeFilter=/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]|/NRCellDU/sourceIds[contains(@item,'ManagedElement=9,GNBDUFunction=9,NRCellDU=2')]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].sourceIds[0]', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].sourceIds[1]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].sourceIds[0]', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].sourceIds[1]', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter=/NRCellDU/attributes[@cellLocalId=1] and targetFilter=/NRCellDU/attributes(nCI)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]&targetFilter=/NRCellDU/attributes(nCI)"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1",
+                                "attributes": {
+                                    "nCI": 1
+                                }
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/attributes(nCI)&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/attributes(nCI)&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/attributes(nCI)&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/attributes(nCI)&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU/attributes(nCI)&scopeFilter=/NRCellDU/attributes[@cellLocalId=1]"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].attributes.nCI', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get topology for an entity with given ID (exact ID match) without knowing entity type."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/id[text()='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2']"
+                },
+                "totalCount": 1
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(1)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get empty items array when no entity exists of given filter criteria."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]&targetFilter=/NRCellDU"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/NRCellDU&scopeFilter=/NRCellDU/attributes[@cellLocalId=8989439]"
+                },
+                "totalCount": 0
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(0)
+                })
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10'] and targetFilter=/attributes."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=500&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']&targetFilter=/attributes"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "attributes": {
+                                    "gNBId": 10,
+                                    "gNBIdLength": 2
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUUPFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "82"
+                                    },
+                                    "gNBId": 10,
+                                    "gNBDUId": null,
+                                    "gNBIdLength": 2
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                            {
+                                "attributes": {
+                                    "gNBId": 10,
+                                    "pLMNId": {
+                                        "mcc": "01",
+                                        "mnc": "234"
+                                    },
+                                    "gNBIdLength": 2,
+                                    "gNBCUName": "gnbcucp-10"
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUCPFunction=10"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBCUCPFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter=/managed-by-managedElement; /attributes[@gNBId=10] and targetFilter=/attributes."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=500&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']&targetFilter=/attributes"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                            "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUUPFunction": [
+                            {
+                                "attributes": {
+                                    "gNBId": 10,
+                                    "gNBIdLength": 2
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUUPFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "82"
+                                    },
+                                    "gNBId": 10,
+                                    "gNBDUId": null,
+                                    "gNBIdLength": 2
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBCUCPFunction": [
+                            {
+                                "attributes": {
+                                    "gNBId": 10,
+                                    "pLMNId": {
+                                        "mcc": "01",
+                                        "mnc": "234"
+                                    },
+                                    "gNBIdLength": 2,
+                                    "gNBCUName": "gnbcucp-10"
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUCPFunction=10"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes&scopeFilter=/managed-by-managedElement[@id='urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBCUUPFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBCUCPFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1] and targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=500&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                                        "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "attributes": {
+                                    "dUpLMNId": {
+                                        "mcc": "456",
+                                        "mnc": "82"
+                                    },
+                                    "gNBId": 9
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&targetFilter=/attributes(gNBId, dUpLMNId); /NRCellDU&scopeFilter=/attributes[@gNBIdLength=1]; /NRCellDU/attributes[@nCI=1]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get entities in RAN domain with scopeFilter on 2 different entity types and combining the condition on complex attributes"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:NRCellDU": [
+                            {
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=500&scopeFilter=/NRCellDU/attributes[@nCI=1];/GNBDUFunction/attributes/dUpLMNId[@mcc='456' or @mnc='83']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:NRCellDU[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "ERROR - 400: Get entities in RAN domain with invalid offset (greater than total count)."
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?&targetFilter=/NRCellDU;&offset=1000"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid Value",
+                "details": "Offset cannot be larger than 5"
+            }''')
+        }
+    },
+    Contract.make {
+        description "Error - 400: Get entities with wrong syntax items instead of item with scopeFilter=/NRCellDU/sourceIds[contains(@items,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&scopeFilter=/NRCellDU/sourceIds[contains(@items,'ManagedElement=9,GNBDUFunction=9,NRCellDU=1')]"
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "status": "BAD_REQUEST",
+                "message": "Invalid parameter error",
+                "details": "Invalid source id parameter provided for NRCellDU"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/decorators/00_getDecorators_getTopologyByEntityTypeName.groovy b/teiv/src/test/resources/contracts/decorators/00_getDecorators_getTopologyByEntityTypeName.groovy
new file mode 100644 (file)
index 0000000..171bce6
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  ============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.decorators
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getTopologyByEntityTypeName - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 456
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getTopologyByEntityTypeName - CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 456
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getTopologyByEntityTypeName - CONTAINS and EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entity-types/GNBDUFunction/entities?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/decorators/01_getDecorators_getRelationshipsByType.groovy b/teiv/src/test/resources/contracts/decorators/01_getDecorators_getRelationshipsByType.groovy
new file mode 100644 (file)
index 0000000..8fa81d9
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  ============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.decorators
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getRelationshipsByType - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 456
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']&targetFilter=/decorators"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']&targetFilter=/decorators"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']&targetFilter=/decorators"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']&targetFilter=/decorators"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[@test-app-module:textdata = 'Stockholm']&targetFilter=/decorators"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getRelationshipsByType - CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 456
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]&targetFilter=/decorators"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]&targetFilter=/decorators"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]&targetFilter=/decorators"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]&targetFilter=/decorators"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')]&targetFilter=/decorators"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getRelationshipsByType - CONTAINS and EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&targetFilter=/decorators&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]&targetFilter=/decorators"
+                },
+                "first": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]&targetFilter=/decorators"
+                },
+                "prev": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]&targetFilter=/decorators"
+                },
+                "next": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]&targetFilter=/decorators"
+                },
+                "last": {
+                    "href": "/domains/REL_OAM_RAN/relationship-types/MANAGEDELEMENT_MANAGES_GNBDUFUNCTION/relationships?offset=0&limit=500&scopeFilter=/decorators[contains(@test-app-module:textdata, 'Stock')] ; /decorators[@test-app-module:intdata = 123]&targetFilter=/decorators"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-rel-oam-ran:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION[0].id', byEquality())
+            }
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/decorators/02_getDecorators_getEntitiesByDomain.groovy b/teiv/src/test/resources/contracts/decorators/02_getDecorators_getEntitiesByDomain.groovy
new file mode 100644 (file)
index 0000000..08ff2a6
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  ============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.decorators
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getEntitiesByDomain - EQUALS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Budapest",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123]"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getEntitiesByDomain - CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 456
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "totalCount": 3
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(3)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[2].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 200: Get decorators using getEntitiesByDomain - EQUALS and CONTAINS"
+        request {
+            method GET()
+            url "/topology-inventory/v1alpha11/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+        }
+        response {
+            status OK()
+            headers {
+                contentType('application/json')
+            }
+            body('''{
+                "items": [
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                            }
+                        ]
+                    },
+                    {
+                        "o-ran-smo-teiv-ran:GNBDUFunction": [
+                            {
+                                "decorators": {
+                                    "test-app-module:textdata": "Stockholm",
+                                    "test-app-module:intdata": 123
+                                },
+                                "id": "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16"
+                            }
+                        ]
+                    }
+                ],
+                "self": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "first": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "prev": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "next": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "last": {
+                    "href": "/domains/RAN/entities?offset=0&limit=100&targetFilter=/GNBDUFunction/decorators&scopeFilter=/GNBDUFunction/decorators[@test-app-module:intdata=123];/GNBDUFunction/decorators[contains(@test-app-module:textdata,'Stock')]"
+                },
+                "totalCount": 2
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(2)
+                })
+                jsonPath('$.items[0].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+                jsonPath('$.items[1].o-ran-smo-teiv-ran:GNBDUFunction[0].id', byEquality())
+            }
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/decorators/03_postDecoratorsMerge.groovy b/teiv/src/test/resources/contracts/decorators/03_postDecoratorsMerge.groovy
new file mode 100644 (file)
index 0000000..77a72b3
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ *  ============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.decorators
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "NOT FOUND - 404: Merge decorators with wrong entity ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: []"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Merge decorators with wrong relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [] Relationships: [WRONG_RELATIONSHIP_ID]"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Merge decorators with wrong entity and relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "relationshipIds": [
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: [WRONG_RELATIONSHIP_ID]"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Merge invalid decorators."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:te": "Budapest",
+                    "test-app-module:intdata": "123"
+                },
+                "entityIds": [
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Invalid decorators",
+                "details": "The provided decorators are invalid {test-app-module:intdata=is_not_compatible, test-app-module:te=is_not_available}"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid decorators, no topology object given."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid decorators to entities (add)."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid decorators to relationships (add)."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=CEEC51BE136D671D2101C09FEDD8A1D95E1E177A4818E9FC0D6E63E610BC8FE26FC9C729A1E58AD43D70472F4CD54403E25CB1E5D2BBA66966625C21435C4A78"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid decorators to entities and relationships (add)."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Budapest",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Merge valid decorators to entities and relationships (update)."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Athlone",
+                    "test-app-module:intdata": 456
+                },
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328"
+                ],
+                "operation": "merge"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/decorators/04_postDecoratorsDelete.groovy b/teiv/src/test/resources/contracts/decorators/04_postDecoratorsDelete.groovy
new file mode 100644 (file)
index 0000000..16143f9
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ *  ============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.decorators
+
+import org.springframework.cloud.contract.spec.Contract
+
+[
+    Contract.make {
+        description "NOT FOUND - 404: Delete decorators with wrong entity ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 1
+                },
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: []"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Delete decorators with wrong relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 2
+                },
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512",
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [] Relationships: [WRONG_RELATIONSHIP_ID]"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "NOT FOUND - 404: Delete decorators with wrong entity and relationship ids."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 3
+                },
+                "entityIds": [
+                    "WRONG_ENTITY_ID",
+                    "urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A"
+                ],
+                "relationshipIds": [
+                    "WRONG_RELATIONSHIP_ID"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NOT_FOUND()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+                "status": "NOT_FOUND",
+                "message": "Resource Not Found",
+                "details": "The requested resource with the following ids cannot be found. Entities: [WRONG_ENTITY_ID] Relationships: [WRONG_RELATIONSHIP_ID]"
+            }''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "BAD REQUEST - 400: Delete decorators from non-existing schema."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module-wrong:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status BAD_REQUEST()
+            headers {
+                contentType('application/problem+json')
+            }
+            body('''{
+            "status": "BAD_REQUEST",
+            "message": "Invalid schema name",
+            "details": "Invalid schema name: test-app-module-wrong"}''')
+            bodyMatchers {
+                jsonPath('$.status', byEquality())
+                jsonPath('$.message', byEquality())
+                jsonPath('$.details', byEquality())
+            }
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete invalid decorators, no topology object given."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid decorators, no topology object given."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid decorators on entities."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid decorators on relationships."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA",
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    },
+    Contract.make {
+        description "SUCCESS - 204: Delete valid decorators on entities and relationships."
+        request {
+            method POST()
+            url "/topology-inventory/v1alpha11/decorators"
+            headers {
+                contentType("application/json")
+                accept('application/problem+json')
+            }
+            body('''{
+                "decorators": {
+                    "test-app-module:textdata": "Stockholm",
+                    "test-app-module:intdata": 123
+                },
+                "entityIds": [
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13",
+                    "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14"
+                ],
+                "relationshipIds": [
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA",
+                    "urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7"
+                ],
+                "operation": "delete"
+            }''')
+        }
+        response {
+            status NO_CONTENT()
+        }
+    }
+]
diff --git a/teiv/src/test/resources/contracts/ran/GNBDUFunction/getAllRelationships.groovy b/teiv/src/test/resources/contracts/ran/GNBDUFunction/getAllRelationships.groovy
deleted file mode 100644 (file)
index 2b78695..0000000
+++ /dev/null
@@ -1,87 +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.ran.GNBDUFunction
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all relationships for GNBDUFunction 1"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [
-        {
-            "o-ran-smo-teiv-ran:GNBDUFUNCTION_PROVIDES_NRCELLDU": [
-                {
-                    "id": "urn:sha512:R05CRFVGdW5jdGlvbjpTdWJOZXR3b3JrPUV1cm9wZSxTdWJOZXR3",
-                    "aSide": "urn:3gpp:dn:ManagedElement=1,GNBDUFunction=1",
-                    "bSide": "urn:3gpp:dn:ManagedElement=1,GNBDUFunction=1,NRCellDU=1",
-                    "decorators": {
-                        "location": "Stockholm"
-                    },
-                    "classifiers": [
-                        "Rural"
-                    ],
-                    "sourceIds": [],
-                    "metadata": {
-                        "trustLevel": "RELIABLE"
-                    }
-                }
-            ]
-        }
-    ],
-    "self": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-    },
-    "first": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-    },
-    "prev": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-    },
-    "next": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-    },
-    "last": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FManagedElement%3D1%2FGNBDUFunction%3D1/relationships?offset=0&limit=100"
-    }
-}''')
-        }
-    },
-    Contract.make {
-        description "BAD_REQUEST - 400: Get a list of all relationships for an unknown objectType"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/5GCell/entities/R05CRFVGdW5jdGlvbg/relationships?offset=1&limit=100"
-        }
-        response {
-            status BAD_REQUEST()
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyById.groovy b/teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyById.groovy
deleted file mode 100644 (file)
index 07f37dc..0000000
+++ /dev/null
@@ -1,128 +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.ran.GNBDUFunction
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get topology for object type by GNBDUFunction 1"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/yang.data+json')
-            }
-            body('''{
-    "o-ran-smo-teiv-ran:GNBDUFunction": [
-        {
-            "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1",
-            "attributes": {
-                "gNBId": 1,
-                "gNBDUId": 1,
-                "gNBIdLength": 2,
-                "dUpLMNId": {
-                    "mcc": "110",
-                    "mnc": "210"
-                }
-            },
-            "decorators": {
-                "location": "Stockholm"
-            },
-            "classifiers": [
-                "Rural"
-            ],
-            "sourceIds": [
-                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1"
-            ],
-            "metadata": {
-                "trustLevel": "RELIABLE"
-            }
-        }
-    ]
-}''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get topology for object type by GNBDUFunction 2"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D2")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/yang.data+json')
-            }
-            body('''{
-    "o-ran-smo-teiv-ran:GNBDUFunction": [
-        {
-            "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=2",
-            "attributes": {
-                "gNBId": 2,
-                "gNBDUId": 2,
-                "gNBIdLength": 2,
-                "dUpLMNId": {
-                    "mcc": "110",
-                    "mnc": "210"
-                }
-            },
-            "decorators": {
-                "location": "Stockholm"
-            },
-            "classifiers": [
-                "Rural"
-            ],
-            "sourceIds": [
-                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=2"
-            ],
-            "metadata": {
-                "trustLevel": "RELIABLE"
-            }
-        }
-    ]
-}''')
-        }
-    },
-    Contract.make {
-        description "NOT_FOUND - 404: Get unknown for object type by GNBDUFunction 1"
-        request {
-            method GET()
-            url "/ties/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1"
-        }
-        response {
-            status NOT_FOUND()
-        }
-    },
-    Contract.make {
-        description "BAD_REQUEST - 400: Get topology for unknown object type by GNBDUFunction 1"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GBFunction/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio00001%2FGNBDUFunction%3D1"
-        }
-        response {
-            status BAD_REQUEST()
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyByType.groovy b/teiv/src/test/resources/contracts/ran/GNBDUFunction/getTopologyByType.groovy
deleted file mode 100644 (file)
index e8426b5..0000000
+++ /dev/null
@@ -1,162 +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.ran.GNBDUFunction
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    /**************************
-     * 'targetFilter' query parameter
-     ***************************/
-    Contract.make {
-        description "SUCCESS - 200: Get topology for GNBDUFunction using 'targetFilter' query parameter"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [
-        {
-            "o-ran-smo-teiv-ran:GNBDUFunction": [
-                {
-                    "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1",
-                    "attributes": {
-                        "gNBDUId": 1
-                    },
-                    "metadata": {
-                        "trustLevel": "RELIABLE"
-                    }
-                }
-            ]
-        }
-    ],
-    "self": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50"
-    },
-    "first": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50"
-    },
-    "prev": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50"
-    },
-    "next": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50"
-    },
-    "last": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&offset=0&limit=50"
-    }
-}''')
-        }
-    },
-    Contract.make {
-        description "NOT_FOUND - 404: Get topology for GNBDUFunction using unknown 'targetFilter' query parameter"
-        request {
-            method GET()
-            url "/ties/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2F%2FGNBDUFunction&offset=1&limit=100"
-        }
-        response {
-            status NOT_FOUND()
-        }
-    },
-    Contract.make {
-        description "BAD_REQUEST - 400: The provided request is not valid"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBBUFunction/entities?targetFilter=%2F%2FGNBBUFunction&offset=1&limit=100"
-        }
-        response {
-            status BAD_REQUEST()
-        }
-    },
-    /***************************************
-     * 'targetFilter' and 'scopeFilter' query parameter
-     ****************************************/
-    Contract.make {
-        description "SUCCESS - 200: Get topology for GNBDUFunction using 'targetFilter' and 'scopeFilter' query parameter"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [
-        {
-            "o-ran-smo-teiv-ran:GNBDUFunction": [
-                {
-                    "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1",
-                    "attributes": {
-                        "gNBDUId": 1
-                    },
-                    "metadata": {
-                        "trustLevel": "RELIABLE"
-                    }
-                }
-            ]
-        }
-    ],
-    "self": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100"
-    },
-    "first": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100"
-    },
-    "prev": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100"
-    },
-    "next": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100"
-    },
-    "last": {
-        "href": "/domains/RAN/entity-types/GNBDUFunction/entities?targetFilter=%2Fattributes(gNBDUId)&scopeFilter=%2Fattributes[@gNBDUId=1]&offset=0&limit=100"
-    }
-}''')
-        }
-    },
-    Contract.make {
-        description "NOT_FOUND - 404: Get unknown for GNBCUCPFunction using 'targetFilter' and 'scopeFilter' query parameter"
-        request {
-            method GET()
-            url "/ties/v1alpha11/domains/RAN/entity-type/GNBDUFunction/entities?targetFilter=%2F%2FGNBDUFunction&scopeFilter=%2F%2FNRCellDU%2FnRTAC%3D50&offset=1&limit=100"
-        }
-        response {
-            status NOT_FOUND()
-        }
-    },
-    Contract.make {
-        description "BAD_REQUEST - 400: The provided request is not valid"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/GNBBUFunction/entities?targetFilter=%2F%2FGNBDUFunction&scopeFilter=%2F%2FNRCellDU%2FnRTAC%3D50&offset=1&limit=100"
-        }
-        response {
-            status BAD_REQUEST()
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/ran/NRCellDU/getTopologyById.groovy b/teiv/src/test/resources/contracts/ran/NRCellDU/getTopologyById.groovy
deleted file mode 100644 (file)
index 20f1580..0000000
+++ /dev/null
@@ -1,122 +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.ran.NRCellDU
-
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get topology for object type by NRCellDU 1"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D1")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/yang.data+json')
-            }
-            body('''{
-    "o-ran-smo-teiv-ran:NRCellDU": [
-        {
-            "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=1",
-            "attributes": {
-                "cellLocalId": 91,
-                "nCI": 1,
-                "nRPCI": 35,
-                "nRTAC": 50
-            },
-            "decorators": {
-                "location": "Stockholm"
-            },
-            "classifiers": [
-                "Rural"
-            ],
-            "sourceIds": [
-                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=1"
-            ],
-            "metadata": {
-                "trustLevel": "RELIABLE"
-            }
-        }
-    ]
-}''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - 200: Get topology for object type by NRCellDU 2"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D2")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/yang.data+json')
-            }
-            body('''{
-    "o-ran-smo-teiv-ran:NRCellDU": [
-        {
-            "id": "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=2",
-            "attributes": {
-                "cellLocalId": 95,
-                "nCI": 5,
-                "nRPCI": 35,
-                "nRTAC": 50
-            },
-            "decorators": {
-                "location": "Stockholm"
-            },
-            "classifiers": [
-                "Rural"
-            ],
-            "sourceIds": [
-                "urn:3gpp:dn:MeContext=NR01,ManagedElement=NR01gNodeBRadio,GNBDUFunction=1,NRCellDU=2"
-            ],
-            "metadata": {
-                "trustLevel": "RELIABLE"
-            }
-        }
-    ]
-}''')
-        }
-    },
-    Contract.make {
-        description "NOT_FOUND - 404: Get unknown for object type by NRCellDU 1"
-        request {
-            method GET()
-            url "/ties/v1alpha11/domains/RAN/entity-types/NRCellDU/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D1"
-        }
-        response {
-            status NOT_FOUND()
-        }
-    },
-    Contract.make {
-        description "BAD_REQUEST - 400: Get topology for unknown object type by NRCellDU 1"
-        request {
-            method GET()
-            url "/topology-inventory/v1alpha11/domains/RAN/entity-types/NRDU/entities/urn%3A3gpp%3Adn%3A%2FMeContext%3DNR01%2FManagedElement%3DNR01gNodeBRadio%2FGNBDUFunction%3D1%2FNRCellDU%3D1"
-        }
-        response {
-            status BAD_REQUEST()
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/ran/schemas/getAllSchemas.groovy b/teiv/src/test/resources/contracts/ran/schemas/getAllSchemas.groovy
deleted file mode 100644 (file)
index 0135d2d..0000000
+++ /dev/null
@@ -1,65 +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.ran.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?offset=0&limit=100")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [
-        {
-            "name": "o-ran-smo-teiv-cloud-to-ran",
-            "domain": "CLOUD_TO_RAN",
-            "revision": "2023-06-26",
-            "content": {
-                "href": "/schemas/o-ran-smo-teiv-cloud-to-ran/content"
-            }
-        }
-    ],
-    "self": {
-        "href": "/schemas?offset=0&limit=100"
-    },
-    "first": {
-        "href": "/schemas?offset=0&limit=100"
-    },
-    "prev": {
-        "href": "/schemas?offset=0&limit=100"
-    },
-    "next": {
-        "href": "/schemas?offset=0&limit=100"
-    },
-    "last": {
-        "href": "/schemas?offset=0&limit=100"
-    }
-}''')
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/ran/schemas/getSchemasInDomain.groovy b/teiv/src/test/resources/contracts/ran/schemas/getSchemasInDomain.groovy
deleted file mode 100644 (file)
index f754260..0000000
+++ /dev/null
@@ -1,96 +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.ran.schemas
-import org.springframework.cloud.contract.spec.Contract
-
-[
-    Contract.make {
-        description "SUCCESS - 200: Get a list of all schemas in RAN domain"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=RAN&offset=0&limit=8")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [
-        {
-            "name": "o-ran-smo-teiv-cloud-to-ran",
-            "domain": "CLOUD_TO_RAN",
-            "revision": "2023-06-26",
-            "content": {
-                "href": "/schemas/o-ran-smo-teiv-cloud-to-ran/content"
-            }
-        }
-    ],
-    "self": {
-        "href": "/schemas?domain=RAN&offset=0&limit=8"
-    },
-    "first": {
-        "href": "/schemas?domain=RAN&offset=0&limit=8"
-    },
-    "prev": {
-        "href": "/schemas?domain=RAN&offset=0&limit=8"
-    },
-    "next": {
-        "href": "/schemas?domain=RAN&offset=0&limit=8"
-    },
-    "last": {
-        "href": "/schemas?domain=RAN&offset=0&limit=8"
-    }
-}''')
-        }
-    },
-    Contract.make {
-        description "SUCCESS - Get list of all schemas in unknown domain"
-        request {
-            method GET()
-            url("/topology-inventory/v1alpha11/schemas?domain=LOGICAL")
-        }
-        response {
-            status OK()
-            headers {
-                contentType('application/json')
-            }
-            body('''{
-    "items": [],
-    "self": {
-        "href": "/schemas?domain=LOGICAL&offset=0&limit=500"
-    },
-    "first": {
-        "href": "/schemas?domain=LOGICAL&offset=0&limit=500"
-    },
-    "prev": {
-        "href": "/schemas?domain=LOGICAL&offset=0&limit=500"
-    },
-    "next": {
-        "href": "/schemas?domain=LOGICAL&offset=0&limit=500"
-    },
-    "last": {
-        "href": "/schemas?domain=LOGICAL&offset=0&limit=500"
-    }
-}''')
-        }
-    }
-]
diff --git a/teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy b/teiv/src/test/resources/contracts/schemas/00_getAllSchemas.groovy
new file mode 100644 (file)
index 0000000..3294d3d
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ *  ============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": "2023-11-06",
+                        "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-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-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-common-yang-types/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-equipment",
+                        "domain": "EQUIPMENT",
+                        "revision": "2024-05-24",
+                        "content": {
+                        "href": "/schemas/o-ran-smo-teiv-equipment/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-oam",
+                        "domain": "OAM",
+                        "revision": "2024-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-oam/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-ran",
+                        "domain": "RAN",
+                        "revision": "2024-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-ran/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-rel-equipment-ran",
+                        "domain": "REL_EQUIPMENT_RAN",
+                        "revision": "2024-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-rel-equipment-ran/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-rel-oam-ran",
+                        "domain": "REL_OAM_RAN",
+                        "revision": "2024-05-24",
+                        "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": 19
+            }''')
+            bodyMatchers {
+                jsonPath('$.items', byType {
+                    occurrence(19)
+                })
+                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())
+            }
+        }
+    },
+    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=18&limit=1"
+                },
+                "totalCount": 19
+            }''')
+        }
+    },
+    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-common-yang-extensions",
+                        "domain": "",
+                        "revision": "2024-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-common-yang-extensions/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=18&limit=3"
+                },
+                "totalCount": 19
+            }''')
+        }
+    },
+    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-05-24",
+                        "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-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-rel-oam-ran/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-ran",
+                        "domain": "RAN",
+                        "revision": "2024-05-24",
+                        "content": {
+                            "href": "/schemas/o-ran-smo-teiv-ran/content"
+                        }
+                    },
+                    {
+                        "name": "o-ran-smo-teiv-rel-equipment-ran",
+                        "domain": "REL_EQUIPMENT_RAN",
+                        "revision": "2024-05-24",
+                        "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": 3
+            }''')
+        }
+    },
+    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
new file mode 100644 (file)
index 0000000..994402d
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  ============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-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_ENODEBFUNCTION {   // 1 to 0..n\n" +
+                    "\n" +
+                    "        uses or-teiv-types:Top_Grp_Type;\n" +
+                    "        key id;\n" +
+                    "\n" +
+                    "        leaf-list managed-enodebFunction {\n" +
+                    "            description \"Managed Element manages eNodeB Function.\";\n" +
+                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
+                    "            type instance-identifier;\n" +
+                    "        }\n" +
+                    "\n" +
+                    "        leaf managed-by-managedElement {\n" +
+                    "            description \"eNodeB Function managed by Managed Element.\";\n" +
+                    "            or-teiv-yext:bSide or-teiv-ran:ENodeBFunction;\n" +
+                    "            type instance-identifier;\n" +
+                    "            mandatory true;\n" +
+                    "        }\n" +
+                    "    }\n" +
+                    "\n" +
+                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_GNBDUFUNCTION {    // 1 to 0..n\n" +
+                    "\n" +
+                    "        uses or-teiv-types:Top_Grp_Type;\n" +
+                    "        key id;\n" +
+                    "\n" +
+                    "        leaf-list managed-gnbduFunction {\n" +
+                    "            description \"Managed Element manages gNodeB-DU Function.\";\n" +
+                    "            or-teiv-yext:aSide or-teiv-oam:ManagedElement;\n" +
+                    "            type instance-identifier;\n" +
+                    "        }\n" +
+                    "\n" +
+                    "        leaf managed-by-managedElement {\n" +
+                    "            description \"gNodeB-DU Function managed by Managed Element.\";\n" +
+                    "            or-teiv-yext:bSide or-teiv-ran:GNBDUFunction;\n" +
+                    "            type instance-identifier;\n" +
+                    "            mandatory true;\n" +
+                    "        }\n" +
+                    "    }\n" +
+                    "\n" +
+                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION {    // 1 to 0..n\n" +
+                    "\n" +
+                    "        uses or-teiv-types:Top_Grp_Type;\n" +
+                    "        key id;\n" +
+                    "\n" +
+                    "        leaf-list managed-gnbcucpFunction {\n" +
+                    "            description \"Managed Element manages gNodeB-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 \"gNodeB-CU-CP Function managed by Managed Element.\";\n" +
+                    "            or-teiv-yext:bSide or-teiv-ran:GNBCUCPFunction;\n" +
+                    "            type instance-identifier;\n" +
+                    "            mandatory true;\n" +
+                    "        }\n" +
+                    "    }\n" +
+                    "\n" +
+                    "    or-teiv-yext:biDirectionalTopologyRelationship MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION {    // 1 to 0..n\n" +
+                    "\n" +
+                    "        uses or-teiv-types:Top_Grp_Type;\n" +
+                    "        key id;\n" +
+                    "\n" +
+                    "        leaf-list managed-gnbcuupFunction {\n" +
+                    "            description \"Managed Element manages gNodeB-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 \"gNodeB-CU-UP Function managed by Managed Element.\";\n" +
+                    "            or-teiv-yext:bSide or-teiv-ran:GNBCUUPFunction;\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
new file mode 100644 (file)
index 0000000..36018d9
--- /dev/null
@@ -0,0 +1,1037 @@
+/*
+ *  ============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*fromgnbcucpfunction { ' +
+                    '            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*fromgnbcucpfunction' 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_referenceSETstatusDELETINGWHEREnamegnbdu-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
new file mode 100644 (file)
index 0000000..5c486fa
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  ============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"
+            }''')
+        }
+    }
+]
diff --git a/teiv/src/test/resources/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql b/teiv/src/test/resources/pgsqlschema/00_init-oran-smo-teiv-data-v1.sql
new file mode 100644 (file)
index 0000000..fe8d597
--- /dev/null
@@ -0,0 +1,1024 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+CREATE EXTENSION IF NOT EXISTS postgis;
+CREATE EXTENSION IF NOT EXISTS postgis_topology;
+CREATE EXTENSION IF NOT EXISTS pg_trgm;
+
+CREATE SCHEMA IF NOT EXISTS ties_data;
+
+-- Function to create CONSTRAINT only if it does not exists
+CREATE OR REPLACE FUNCTION ties_data.create_constraint_if_not_exists (
+       t_name TEXT, c_name TEXT, constraint_sql TEXT
+)
+RETURNS void AS
+$$
+BEGIN
+       IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = t_name AND constraint_name = c_name) THEN
+               EXECUTE constraint_sql;
+       END IF;
+END;
+$$ language 'plpgsql';
+
+-- Update data schema exec status
+INSERT INTO ties_model.execution_status("schema", "status") VALUES ('ties_data', 'success');
+
+CREATE TABLE IF NOT EXISTS ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" (
+       "id"                    TEXT,
+       "aSide_AntennaModule"                   TEXT,
+       "bSide_AntennaCapability"                       TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-equipment_AntennaModule" (
+       "id"                    TEXT,
+       "antennaBeamWidth"                      jsonb,
+       "antennaModelNumber"                    TEXT,
+       "electricalAntennaTilt"                 INTEGER,
+       "geo-location"                  geography,
+       "mechanicalAntennaBearing"                      INTEGER,
+       "mechanicalAntennaTilt"                 INTEGER,
+       "positionWithinSector"                  TEXT,
+       "totalTilt"                     INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_installed-at-site"                      TEXT,
+       "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE"                        TEXT,
+       "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE"                      jsonb,
+       "REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE"                    jsonb,
+       "REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE"                     jsonb,
+       "REL_FK_grouped-by-sector"                      TEXT,
+       "REL_ID_SECTOR_GROUPS_ANTENNAMODULE"                    TEXT,
+       "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE"                  jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE"                        jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-equipment_Site" (
+       "id"                    TEXT,
+       "geo-location"                  geography,
+       "name"                  TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_Site" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_Site" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-equipment_Site" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-oam_ManagedElement" (
+       "id"                    TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-oam_ManagedElement" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-oam_ManagedElement" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-oam_ManagedElement" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_AntennaCapability" (
+       "id"                    TEXT,
+       "eUtranFqBands"                 jsonb,
+       "geranFqBands"                  jsonb,
+       "nRFqBands"                     jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_AntennaCapability" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_AntennaCapability" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_AntennaCapability" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_ENodeBFunction" (
+       "id"                    TEXT,
+       "eNBId"                 INTEGER,
+       "eNodeBPlmnId"                  jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_managed-by-managedElement"                      TEXT,
+       "REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                  TEXT,
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                        jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                      jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                       jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_EUtranCell" (
+       "id"                    TEXT,
+       "cellId"                        INTEGER,
+       "channelBandwidth"                      INTEGER,
+       "dlChannelBandwidth"                    INTEGER,
+       "duplexType"                    TEXT,
+       "earfcn"                        INTEGER,
+       "earfcndl"                      INTEGER,
+       "earfcnul"                      INTEGER,
+       "tac"                   INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-enodebFunction"                     TEXT,
+       "REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                     TEXT,
+       "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                   jsonb,
+       "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                 jsonb,
+       "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                  jsonb,
+       "REL_FK_grouped-by-sector"                      TEXT,
+       "REL_ID_SECTOR_GROUPS_EUTRANCELL"                       TEXT,
+       "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL"                     jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL"                   jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL"                    jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_EUtranCell" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" (
+       "id"                    TEXT,
+       "gNBCUName"                     TEXT,
+       "gNBId"                 BIGINT,
+       "gNBIdLength"                   INTEGER,
+       "pLMNId"                        jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_managed-by-managedElement"                      TEXT,
+       "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                 TEXT,
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                       jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                     jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                      jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" (
+       "id"                    TEXT,
+       "gNBId"                 BIGINT,
+       "gNBIdLength"                   INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_managed-by-managedElement"                      TEXT,
+       "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                 TEXT,
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                       jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                     jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                      jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_GNBDUFunction" (
+       "id"                    TEXT,
+       "dUpLMNId"                      jsonb,
+       "gNBDUId"                       BIGINT,
+       "gNBId"                 BIGINT,
+       "gNBIdLength"                   INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_managed-by-managedElement"                      TEXT,
+       "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"                   TEXT,
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"                 jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"                       jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"                        jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" (
+       "id"                    TEXT,
+       "sectorCarrierType"                     TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-enodebFunction"                     TEXT,
+       "REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                       TEXT,
+       "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                     jsonb,
+       "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                   jsonb,
+       "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                    jsonb,
+       "REL_FK_used-by-euTranCell"                     TEXT,
+       "REL_ID_EUTRANCELL_USES_LTESECTORCARRIER"                       TEXT,
+       "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER"                     jsonb,
+       "REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER"                   jsonb,
+       "REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER"                    jsonb,
+       "REL_FK_used-antennaCapability"                 TEXT,
+       "REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                        TEXT,
+       "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                      jsonb,
+       "REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                    jsonb,
+       "REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                     jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ALTER COLUMN "REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_NRCellCU" (
+       "id"                    TEXT,
+       "cellLocalId"                   INTEGER,
+       "nCI"                   BIGINT,
+       "nRTAC"                 INTEGER,
+       "plmnId"                        jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-gnbcucpFunction"                    TEXT,
+       "REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                      TEXT,
+       "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                    jsonb,
+       "REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                  jsonb,
+       "REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                   jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellCU" ALTER COLUMN "REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_NRCellDU" (
+       "id"                    TEXT,
+       "cellLocalId"                   INTEGER,
+       "nCI"                   BIGINT,
+       "nRPCI"                 INTEGER,
+       "nRTAC"                 INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-gnbduFunction"                      TEXT,
+       "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU"                        TEXT,
+       "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU"                      jsonb,
+       "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU"                    jsonb,
+       "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU"                     jsonb,
+       "REL_FK_grouped-by-sector"                      TEXT,
+       "REL_ID_SECTOR_GROUPS_NRCELLDU"                 TEXT,
+       "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU"                       jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU"                     jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_NRCELLDU"                      jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRCellDU" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" (
+       "id"                    TEXT,
+       "arfcnDL"                       INTEGER,
+       "arfcnUL"                       INTEGER,
+       "bSChannelBwDL"                 INTEGER,
+       "frequencyDL"                   INTEGER,
+       "frequencyUL"                   INTEGER,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-gnbduFunction"                      TEXT,
+       "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                 TEXT,
+       "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                       jsonb,
+       "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                     jsonb,
+       "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                      jsonb,
+       "REL_FK_used-by-nrCellDu"                       TEXT,
+       "REL_ID_NRCELLDU_USES_NRSECTORCARRIER"                  TEXT,
+       "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER"                        jsonb,
+       "REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER"                      jsonb,
+       "REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER"                       jsonb,
+       "REL_FK_used-antennaCapability"                 TEXT,
+       "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                 TEXT,
+       "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                       jsonb,
+       "REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                     jsonb,
+       "REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                      jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ALTER COLUMN "REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran_Sector" (
+       "id"                    TEXT,
+       "azimuth"                       DECIMAL,
+       "geo-location"                  geography,
+       "sectorId"                      BIGINT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_Sector" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_Sector" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran_Sector" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'CFC235E0404703D1E4454647DF8AAE2C193DB402',
+ 'PK_63E61CB6802F21FE7A04A80A095F6AF8ABF067CE',
+ 'ALTER TABLE ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ADD CONSTRAINT "PK_63E61CB6802F21FE7A04A80A095F6AF8ABF067CE" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_AntennaModule',
+ 'PK_o-ran-smo-teiv-equipment_AntennaModule_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_AntennaModule" ADD CONSTRAINT "PK_o-ran-smo-teiv-equipment_AntennaModule_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_Site',
+ 'PK_o-ran-smo-teiv-equipment_Site_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_Site" ADD CONSTRAINT "PK_o-ran-smo-teiv-equipment_Site_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-oam_ManagedElement',
+ 'PK_o-ran-smo-teiv-oam_ManagedElement_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-oam_ManagedElement" ADD CONSTRAINT "PK_o-ran-smo-teiv-oam_ManagedElement_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_AntennaCapability',
+ 'PK_o-ran-smo-teiv-ran_AntennaCapability_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_AntennaCapability" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_AntennaCapability_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_ENodeBFunction',
+ 'PK_o-ran-smo-teiv-ran_ENodeBFunction_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_ENodeBFunction_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_EUtranCell',
+ 'PK_o-ran-smo-teiv-ran_EUtranCell_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_EUtranCell" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_EUtranCell_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUCPFunction',
+ 'PK_o-ran-smo-teiv-ran_GNBCUCPFunction_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_GNBCUCPFunction_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUUPFunction',
+ 'PK_o-ran-smo-teiv-ran_GNBCUUPFunction_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_GNBCUUPFunction_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBDUFunction',
+ 'PK_o-ran-smo-teiv-ran_GNBDUFunction_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_GNBDUFunction_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'PK_o-ran-smo-teiv-ran_LTESectorCarrier_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_LTESectorCarrier_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellCU',
+ 'PK_o-ran-smo-teiv-ran_NRCellCU_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellCU" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_NRCellCU_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellDU',
+ 'PK_o-ran-smo-teiv-ran_NRCellDU_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellDU" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_NRCellDU_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'PK_o-ran-smo-teiv-ran_NRSectorCarrier_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_NRSectorCarrier_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_Sector',
+ 'PK_o-ran-smo-teiv-ran_Sector_id',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_Sector" ADD CONSTRAINT "PK_o-ran-smo-teiv-ran_Sector_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'CFC235E0404703D1E4454647DF8AAE2C193DB402',
+ 'FK_D80D1E6B26DF620B4DE659C600A3B7F709A41960',
+ 'ALTER TABLE ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ADD CONSTRAINT "FK_D80D1E6B26DF620B4DE659C600A3B7F709A41960" FOREIGN KEY ("aSide_AntennaModule") REFERENCES ties_data."o-ran-smo-teiv-equipment_AntennaModule" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'CFC235E0404703D1E4454647DF8AAE2C193DB402',
+ 'FK_7148BEED02C0617DE1DEEB6639F34A9FA9251B06',
+ 'ALTER TABLE ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ADD CONSTRAINT "FK_7148BEED02C0617DE1DEEB6639F34A9FA9251B06" FOREIGN KEY ("bSide_AntennaCapability") REFERENCES ties_data."o-ran-smo-teiv-ran_AntennaCapability" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_AntennaModule',
+ 'FK_E3BAEF04443354C0FC1837CF7964E05BEF9FD6CC',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_AntennaModule" ADD CONSTRAINT "FK_E3BAEF04443354C0FC1837CF7964E05BEF9FD6CC" FOREIGN KEY ("REL_FK_installed-at-site") REFERENCES ties_data."o-ran-smo-teiv-equipment_Site" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_AntennaModule',
+ 'UNIQUE_9DF414C2F0CD7FA8BFCB3E9BF851784AC4BC49B1',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_AntennaModule" ADD CONSTRAINT "UNIQUE_9DF414C2F0CD7FA8BFCB3E9BF851784AC4BC49B1" UNIQUE ("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_AntennaModule',
+ 'FK_078764B2F3D613D44CC6E3586F564C83164D2481',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_AntennaModule" ADD CONSTRAINT "FK_078764B2F3D613D44CC6E3586F564C83164D2481" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."o-ran-smo-teiv-ran_Sector" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-equipment_AntennaModule',
+ 'UNIQUE_78B1D3DCD903AFFB1965D440D87B2D194CA028A0',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-equipment_AntennaModule" ADD CONSTRAINT "UNIQUE_78B1D3DCD903AFFB1965D440D87B2D194CA028A0" UNIQUE ("REL_ID_SECTOR_GROUPS_ANTENNAMODULE");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_ENodeBFunction',
+ 'FK_6C99B14BF3C9BC6DE2D69AD55DF323ADCB174167',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ADD CONSTRAINT "FK_6C99B14BF3C9BC6DE2D69AD55DF323ADCB174167" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-oam_ManagedElement" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_ENodeBFunction',
+ 'UNIQUE_A30444B7D036FA579730F0D2853E52FD08DEDCF0',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ADD CONSTRAINT "UNIQUE_A30444B7D036FA579730F0D2853E52FD08DEDCF0" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_EUtranCell',
+ 'FK_2D1FA89480BF856AB865D58FAFB6AC0B476015EB',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_EUtranCell" ADD CONSTRAINT "FK_2D1FA89480BF856AB865D58FAFB6AC0B476015EB" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."o-ran-smo-teiv-ran_ENodeBFunction" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_EUtranCell',
+ 'UNIQUE_CA88C7E60C1A332FA7561FC965ED41DD4125CDED',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_EUtranCell" ADD CONSTRAINT "UNIQUE_CA88C7E60C1A332FA7561FC965ED41DD4125CDED" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_EUtranCell',
+ 'FK_o-ran-smo-teiv-ran_EUtranCell_REL_FK_grouped-by-sector',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_EUtranCell" ADD CONSTRAINT "FK_o-ran-smo-teiv-ran_EUtranCell_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."o-ran-smo-teiv-ran_Sector" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_EUtranCell',
+ 'UNIQUE_0513FE4A675A02C31E5EDD6BCB3728911FBDA2FA',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_EUtranCell" ADD CONSTRAINT "UNIQUE_0513FE4A675A02C31E5EDD6BCB3728911FBDA2FA" UNIQUE ("REL_ID_SECTOR_GROUPS_EUTRANCELL");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUCPFunction',
+ 'FK_F1FB8F88851067901B66D53EE1420D2ECCEC98A3',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ADD CONSTRAINT "FK_F1FB8F88851067901B66D53EE1420D2ECCEC98A3" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-oam_ManagedElement" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUCPFunction',
+ 'UNIQUE_50E9E4A87D93AC833B1D1AC05E3B58805909E20E',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ADD CONSTRAINT "UNIQUE_50E9E4A87D93AC833B1D1AC05E3B58805909E20E" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUUPFunction',
+ 'FK_34D6E2537E8EE1D395CAF5BF9B2182A4696A1EAA',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ADD CONSTRAINT "FK_34D6E2537E8EE1D395CAF5BF9B2182A4696A1EAA" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-oam_ManagedElement" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBCUUPFunction',
+ 'UNIQUE_0CA05800AC7D277BDCB5CF0097DC35978E9311F4',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ADD CONSTRAINT "UNIQUE_0CA05800AC7D277BDCB5CF0097DC35978E9311F4" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBDUFunction',
+ 'FK_F67FAF9D3E82B97104E2392DA0AC8A86DF2407CC',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ADD CONSTRAINT "FK_F67FAF9D3E82B97104E2392DA0AC8A86DF2407CC" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-oam_ManagedElement" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_GNBDUFunction',
+ 'UNIQUE_5BD09ED226520A0BE27904AEAF0557416808E7E2',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ADD CONSTRAINT "UNIQUE_5BD09ED226520A0BE27904AEAF0557416808E7E2" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'FK_D0868FBC0BBE2754F4B765C4898C1A1700E2BEFD',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "FK_D0868FBC0BBE2754F4B765C4898C1A1700E2BEFD" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."o-ran-smo-teiv-ran_ENodeBFunction" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'UNIQUE_FD943EE596337B11E0C640E1176CADF9CD69E19A',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "UNIQUE_FD943EE596337B11E0C640E1176CADF9CD69E19A" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'FK_96E6D4983CFFDF30FCA20423B5913DEE486E42D0',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "FK_96E6D4983CFFDF30FCA20423B5913DEE486E42D0" FOREIGN KEY ("REL_FK_used-by-euTranCell") REFERENCES ties_data."o-ran-smo-teiv-ran_EUtranCell" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'UNIQUE_0A76398FBBC8E01A2D3BA602AB47835794E997E5',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "UNIQUE_0A76398FBBC8E01A2D3BA602AB47835794E997E5" UNIQUE ("REL_ID_EUTRANCELL_USES_LTESECTORCARRIER");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'FK_3D8DF3FBD9C042A888CEB382688C1E8F39D85AFE',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "FK_3D8DF3FBD9C042A888CEB382688C1E8F39D85AFE" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."o-ran-smo-teiv-ran_AntennaCapability" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_LTESectorCarrier',
+ 'UNIQUE_EA18F1D278EAFE834B8A80BCF8A7D8355CD013DF',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ADD CONSTRAINT "UNIQUE_EA18F1D278EAFE834B8A80BCF8A7D8355CD013DF" UNIQUE ("REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellCU',
+ 'FK_F2CDD1E84C7F07BF8065F99A5F3488E91E3BB7B2',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellCU" ADD CONSTRAINT "FK_F2CDD1E84C7F07BF8065F99A5F3488E91E3BB7B2" FOREIGN KEY ("REL_FK_provided-by-gnbcucpFunction") REFERENCES ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellCU',
+ 'UNIQUE_EA2A6F5BA36ABB0DA357542E05AA2D07415E127A',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellCU" ADD CONSTRAINT "UNIQUE_EA2A6F5BA36ABB0DA357542E05AA2D07415E127A" UNIQUE ("REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellDU',
+ 'FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_provided-by-gnbduFunction',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellDU" ADD CONSTRAINT "FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_provided-by-gnbduFunction" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."o-ran-smo-teiv-ran_GNBDUFunction" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellDU',
+ 'UNIQUE_C3D8E5331EC71D46D4B8CED29FE5F6CEB1D8E67A',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellDU" ADD CONSTRAINT "UNIQUE_C3D8E5331EC71D46D4B8CED29FE5F6CEB1D8E67A" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellDU',
+ 'FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_grouped-by-sector',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellDU" ADD CONSTRAINT "FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."o-ran-smo-teiv-ran_Sector" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRCellDU',
+ 'UNIQUE_AC1C114ABED77D6DEC3F3AE3F9EBE8231924AEF4',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRCellDU" ADD CONSTRAINT "UNIQUE_AC1C114ABED77D6DEC3F3AE3F9EBE8231924AEF4" UNIQUE ("REL_ID_SECTOR_GROUPS_NRCELLDU");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'FK_F7978366174C82E41F0A6ABF29005FF01603858F',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "FK_F7978366174C82E41F0A6ABF29005FF01603858F" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."o-ran-smo-teiv-ran_GNBDUFunction" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'UNIQUE_0AC16A840F6ACDC50136E71EC6D4F3D4E04B8198',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "UNIQUE_0AC16A840F6ACDC50136E71EC6D4F3D4E04B8198" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_used-by-nrCellDu',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_used-by-nrCellDu" FOREIGN KEY ("REL_FK_used-by-nrCellDu") REFERENCES ties_data."o-ran-smo-teiv-ran_NRCellDU" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'UNIQUE_1AB577E5AC207ED4C99A9A96BA1C9C35544AFD25',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "UNIQUE_1AB577E5AC207ED4C99A9A96BA1C9C35544AFD25" UNIQUE ("REL_ID_NRCELLDU_USES_NRSECTORCARRIER");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'FK_65D538D54EB33081C808540235FEB28823428E64',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "FK_65D538D54EB33081C808540235FEB28823428E64" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."o-ran-smo-teiv-ran_AntennaCapability" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'o-ran-smo-teiv-ran_NRSectorCarrier',
+ 'UNIQUE_A799EC9DA6624651081E1DA21B5F0C2D38F6A192',
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ADD CONSTRAINT "UNIQUE_A799EC9DA6624651081E1DA21B5F0C2D38F6A192" UNIQUE ("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY");'
+);
+
+CREATE INDEX IF NOT EXISTS "IDX_E896A9EB22A3F9F96CE75A271475316A98B629C8" ON ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_DD0D676834B12CA2F7E8219310998376A08D7F5F" ON ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_7BF09D0227840279556AD27ACECB068705893D28" ON ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_21B0F1FE632B6CB185C49BA6F00224068F443215" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("antennaBeamWidth"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_905011128A2C218B5352C19ED1FE9851F43EB911" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_1C0CAFD80FDD6444044E3F76C7C0A7BDC35F9BC8" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-equipment_AntennaModule_CD_decorators" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_F497DEC01DA066CB09DA2AA7EDE3F4410078491B" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_17E417F7EF56809674BE1D5F5154DCCE01E00A96" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_2321BFA482AD2700F41E2BA359F6EB00F47601B9" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN ("REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE");
+
+CREATE INDEX IF NOT EXISTS "IDX_5ABDB19E55A6BDEF33855F14CB1B3B8CF457912C" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_83B6347C0C0A005D5E3D856D973D3322DFEDEA35" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN (("REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_6C6FBD69F47F41970595A8775DC99CA0F5E894A1" ON ties_data."o-ran-smo-teiv-equipment_AntennaModule" USING GIN ("REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE");
+
+CREATE INDEX IF NOT EXISTS "IDX_102A50584376DE25B6BBD7157594C607A5C957F2" ON ties_data."o-ran-smo-teiv-equipment_Site" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_EEBF1BC3344E97988232825777AB13FAB6C4F3F0" ON ties_data."o-ran-smo-teiv-equipment_Site" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-equipment_Site_CD_decorators" ON ties_data."o-ran-smo-teiv-equipment_Site" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_DDD73D6F4004BF3A96AA118281EE3E565A922B47" ON ties_data."o-ran-smo-teiv-oam_ManagedElement" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_98AC4232BC02323E03416954215889CEE874A1E9" ON ties_data."o-ran-smo-teiv-oam_ManagedElement" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-oam_ManagedElement_CD_decorators" ON ties_data."o-ran-smo-teiv-oam_ManagedElement" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_5FB80647AE3E5C0443A792618D65B9090EE2A3FC" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN (("eUtranFqBands"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_A94722FF7B95D8974B494793908B57B4E1A9743B" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN (("geranFqBands"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_441B5C05448D63552C6414BD59C13641D8A4408D" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN (("nRFqBands"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_CC3E208A4EE51D3B505416A599F36F3C99F466C8" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_E7FFE8F4A166AA9A382A0659762FFEC313A9EB5C" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_AntennaCapability_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_AntennaCapability" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_eNodeBPlmnId" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN ("eNodeBPlmnId");
+
+CREATE INDEX IF NOT EXISTS "IDX_3F7D14B4CF2CA74F28BA1600606E82C6E8C447C0" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_B598B74193845587BA03553CEDBA058D33956847" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_252AF4814C67384A7B05EA116316E83AFF9EB6AE" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN (("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_61CDCD3F69CF67EE740358D2C76FA796CFDA19BF" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN (("REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_35C17C8A9BA3EF3AEADA72C21F8090C38F575BAF" ON ties_data."o-ran-smo-teiv-ran_ENodeBFunction" USING GIN ("REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION");
+
+CREATE INDEX IF NOT EXISTS "IDX_84E36DC53519D3E334C60B5B02C1AB27130CFA24" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_C9C19F8F83F50C130F2EB6502ABB7B2833F1F783" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_EUtranCell_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_976F6A0F8991F64592B6F9E716EFEECBD5400FDA" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_4C77E3A51BFAB2FCD30425E4EB21CC7636438299" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_FC7D79187227E0BFA69149048CC10E39AE540B8A" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN ("REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL");
+
+CREATE INDEX IF NOT EXISTS "IDX_173887418DD4FD6FD592F6404EA784150B1822C0" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_8A15E61498725DA9D8C78FC4B99053C06E88DCEC" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN (("REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_E4EF3C904939ED4C0996EAB7CDFE1895CDF34BFB" ON ties_data."o-ran-smo-teiv-ran_EUtranCell" USING GIN ("REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL");
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_pLMNId" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN ("pLMNId");
+
+CREATE INDEX IF NOT EXISTS "IDX_BE4B476041D559760931630000D3F4A6DFF42707" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_588840BAE32C7FF8CF0553F631DAAF8BB6E8E7C1" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_E01081465B87F46E1CC7A22FE406C7B41C817E8C" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN (("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_1324070754C1EBF8EA78EF40743AFC1713733BA8" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN (("REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_13E734DE57346378DA4F21FC4EA030290A7E532F" ON ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" USING GIN ("REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");
+
+CREATE INDEX IF NOT EXISTS "IDX_C6D2419F8DC299FBC98342AA00BE92308C7566A7" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_4C2B68358221A7FF0E68012DEDD3CBA2C4ED669F" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_GNBCUUPFunction_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_883506CAA3E742D82EEFCEE8C8F29927983B73B1" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN (("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_EB07ADD66F6CF51B9330403DE4500D05CA067647" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN (("REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_C3141DD7D2695EF74B13981AB378A58390D203D6" ON ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" USING GIN ("REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION");
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_dUpLMNId" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN ("dUpLMNId");
+
+CREATE INDEX IF NOT EXISTS "IDX_2BEF269CED354C2454AC2B2EABB134AC267A0C62" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_601A4514FFACA8985471531013AFC8F760361F09" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_3065F7FB78C5AA9FF17972F825F89AED127A6324" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN (("REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_04C614FDE6A4AE2AA106A1233D1DF95803FC122D" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN (("REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_298FCD184347DEC995B06FED2B1AE61F12BF766A" ON ties_data."o-ran-smo-teiv-ran_GNBDUFunction" USING GIN ("REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");
+
+CREATE INDEX IF NOT EXISTS "IDX_6EC539C61EA7078DBA264C9877B87FC263605D42" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_E754EB8AD825DB3111B07B9E5DA3B30C38DB406B" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_1EBC7271CEA658156DE25286404CBC4593340F8E" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_846B7740E8AA756B8C1409CD909D2DF73A47ED4C" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_44075E1D464599B61924196C20F2B88332520CD8" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN ("REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER");
+
+CREATE INDEX IF NOT EXISTS "IDX_F2D46817C2D618D8C33945F282299BF9EB49465E" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_B291D7EFCAD3BF06A2C11F8C0429ABABEEF8308B" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_EAE482189F45D63CD1A88B0DD5F76EEE163D9E53" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN ("REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER");
+
+CREATE INDEX IF NOT EXISTS "IDX_7D01A5D21C990ACCBE65035C062C7D881A05F1EE" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_3D3EFECFB917DAC074F56334224B19F8FD6BF8A5" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN (("REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_4EE2AA643311DFCC13B6ED832EBE2FAB4CFDF494" ON ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" USING GIN ("REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY");
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_plmnId" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN ("plmnId");
+
+CREATE INDEX IF NOT EXISTS "IDX_0C443A16285D233F16966C2F0314CDC9D0F6D0B8" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_E5930226819982DC0CFC1FA64FB3600647222435" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_36A671754CD510FFBDC2713FD142303DCA75DD65" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN (("REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_04BE1EB39848069422B97C28EE3C8ED18BCC6D33" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN (("REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_229957181BBC9D7B4535807BB397E8AA1378ED85" ON ties_data."o-ran-smo-teiv-ran_NRCellCU" USING GIN ("REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU");
+
+CREATE INDEX IF NOT EXISTS "IDX_FFD60DD99D80C276F402E66546F5DACB2D81EE26" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_C437D39632DC79BAB6AC4F0880826A05425F9C32" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_NRCellDU_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_1F6708B1E34FC908473DD7A7E5641E650B359BEF" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_2F4C43ED084968FDAF9943DB96741885C145FE1D" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_0E63D6B76B229961CD45D998C63175B569DDECD1" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN ("REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU");
+
+CREATE INDEX IF NOT EXISTS "IDX_6325926B4D2FDD1FBBB34250DABEA5E7229FF9F5" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_7CB4A7724F68D1CB2D12E8DE779BA9103F7DBE0A" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN (("REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_0A03C47C13AD3B5C84D3D8081493D670E9CBDCD1" ON ties_data."o-ran-smo-teiv-ran_NRCellDU" USING GIN ("REL_CD_decorators_SECTOR_GROUPS_NRCELLDU");
+
+CREATE INDEX IF NOT EXISTS "IDX_8E34EC0B1DE7DDCE3B32ADD85B11E15F95C5644E" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_050A80BEEF775E4D3CE216F282F23DB99DA2D798" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN ("CD_decorators");
+
+CREATE INDEX IF NOT EXISTS "IDX_CD293AD1111E344D150340A13BD299924D29A9DA" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_273D43FDDD1C4643ECF8BBE51B6B369C657F0861" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_EDE8B88F488F9380DB49CB2C141318FB33C2CCEC" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN ("REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");
+
+CREATE INDEX IF NOT EXISTS "IDX_7BFD17A71AB1B7765FE6431DA4E66C2EDE88AC3B" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_ED50A5139F1449DBAD8DA10D45F5A5BF819EACBA" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_2ADB5C6DCAEE8811FB1CA8FD9EB53381F35FCB70" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN ("REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER");
+
+CREATE INDEX IF NOT EXISTS "IDX_1F27C515A028616FAC422A02ABBEC402D5DBB2E5" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_B975D24291849007D4AA6686C5D3983885D5C884" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN (("REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_902B73F741160B9D4FBF62406D3D9ABBECAD8BE7" ON ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" USING GIN ("REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY");
+
+CREATE INDEX IF NOT EXISTS "IDX_E234B43A7CD7843672F08F2197AB46A2A50BECB0" ON ties_data."o-ran-smo-teiv-ran_Sector" USING GIN (("CD_sourceIds"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_19C19556F9714850389595E0A16218FA229205FE" ON ties_data."o-ran-smo-teiv-ran_Sector" USING GIN (("CD_classifiers"::TEXT) gin_trgm_ops);
+
+CREATE INDEX IF NOT EXISTS "IDX_GIN_o-ran-smo-teiv-ran_Sector_CD_decorators" ON ties_data."o-ran-smo-teiv-ran_Sector" USING GIN ("CD_decorators");
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_GNBDUFunction";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction";
+
+ANALYZE ties_data."o-ran-smo-teiv-equipment_Site";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_AntennaCapability";
+
+ANALYZE ties_data."o-ran-smo-teiv-equipment_AntennaModule";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_EUtranCell";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_LTESectorCarrier";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_NRCellCU";
+
+ANALYZE ties_data."o-ran-smo-teiv-oam_ManagedElement";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_NRCellDU";
+
+ANALYZE ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_NRSectorCarrier";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_ENodeBFunction";
+
+ANALYZE ties_data."o-ran-smo-teiv-ran_Sector";
+
+COMMIT;
index 094be5e..4748549 100644 (file)
@@ -31,7 +31,7 @@ ALTER SCHEMA ties_data OWNER TO :pguser;
 SET default_tablespace = '';
 SET default_table_access_method = heap;
 
-SET ROLE :'pguser';
+SET ROLE :pguser;
 
 -- Function to create CONSTRAINT only if it does not exists
 CREATE OR REPLACE FUNCTION ties_data.create_constraint_if_not_exists (
@@ -46,50 +46,76 @@ BEGIN
 END;
 $$ language 'plpgsql';
 
-CREATE TABLE IF NOT EXISTS ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" (
+CREATE TABLE IF NOT EXISTS ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "REL_FK_C2F5EC33C0760F653CE7263A49C0B697FCA2D542"                       VARCHAR(511)
 );
 
-ALTER TABLE ONLY ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" (
+CREATE TABLE IF NOT EXISTS ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "fdn"                   TEXT,
        "cmId"                  jsonb,
        "REL_FK_26958E3A529C4C8B68A29FDA906F8CD290F66078"                       VARCHAR(511),
        "REL_ID_B7945BFD83380F3E12CF99F2B0F838F364027F92"                       VARCHAR(511),
-       "REL_CD_B7945BFD83380F3E12CF99F2B0F838F364027F92"                       jsonb
+       "REL_CD_B7945BFD83380F3E12CF99F2B0F838F364027F92"                       jsonb,
+       "REL_CD_BF4AAC1A1A910D1182505CABF55BAAE822B2BE59"                       jsonb,
+       "REL_CD_AE82DD80D666B52D79A314F8B4EE9B046830D009"                       jsonb
 );
 
-ALTER TABLE ONLY ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ALTER COLUMN "REL_CD_B7945BFD83380F3E12CF99F2B0F838F364027F92" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "REL_CD_B7945BFD83380F3E12CF99F2B0F838F364027F92" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "REL_CD_BF4AAC1A1A910D1182505CABF55BAAE822B2BE59" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ALTER COLUMN "REL_CD_AE82DD80D666B52D79A314F8B4EE9B046830D009" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" (
+CREATE TABLE IF NOT EXISTS ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "REL_FK_AB87B417CCD05C332DDD0C60F0C6AB41D38B05E5"                       VARCHAR(511),
        "REL_ID_FC2F6A5A12917357B548C83F4B0C1AD58FA61413"                       VARCHAR(511),
        "REL_CD_CEAD4CCE5250E7D3C64801C8FDDC21F1D87BEC0C"                       jsonb,
+       "REL_CD_744530EF4EB1D281D23ADB3DB4CC926DFBE7A60D"                       jsonb,
+       "REL_CD_4D1F8113C3096B383582A7A04E68974983B4259E"                       jsonb,
        "REL_FK_8C98B70070BBD11F90F192DDA3ECF6302390E956"                       VARCHAR(511),
        "REL_ID_AFBF10D23507AD3B6408947D2A9AF8465BA7B08C"                       VARCHAR(511),
-       "REL_CD_F7E43E0D0F76D6EFED9AB684B84A69E177F591D2"                       jsonb
+       "REL_CD_F7E43E0D0F76D6EFED9AB684B84A69E177F591D2"                       jsonb,
+       "REL_CD_C4349BB0F0292A3CE7E456E3A4C40C86DD6B15DF"                       jsonb,
+       "REL_CD_8AD499BB116F3213C079F643D4B3532035D092D2"                       jsonb
 );
 
-ALTER TABLE ONLY ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ALTER COLUMN "REL_CD_CEAD4CCE5250E7D3C64801C8FDDC21F1D87BEC0C" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_CEAD4CCE5250E7D3C64801C8FDDC21F1D87BEC0C" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_744530EF4EB1D281D23ADB3DB4CC926DFBE7A60D" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_4D1F8113C3096B383582A7A04E68974983B4259E" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ALTER COLUMN "REL_CD_F7E43E0D0F76D6EFED9AB684B84A69E177F591D2" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_F7E43E0D0F76D6EFED9AB684B84A69E177F591D2" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_C4349BB0F0292A3CE7E456E3A4C40C86DD6B15DF" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ALTER COLUMN "REL_CD_8AD499BB116F3213C079F643D4B3532035D092D2" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" (
+CREATE TABLE IF NOT EXISTS ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "020335B0F627C169E24167748C38FE756FB34AE2"                      BIGINT,
        "nRTAC"                 BIGINT,
        "nRPCI"                 BIGINT,
@@ -98,60 +124,88 @@ CREATE TABLE IF NOT EXISTS ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC"
        "nCI"                   BIGINT,
        "REL_FK_609963BFEE15FF824280FBE201313C3CDACDDDCE"                       VARCHAR(511),
        "REL_ID_040FC8B06B420BA5708AF4798102D1E65FB4DC61"                       VARCHAR(511),
-       "REL_CD_040FC8B06B420BA5708AF4798102D1E65FB4DC61"                       jsonb
+       "REL_CD_040FC8B06B420BA5708AF4798102D1E65FB4DC61"                       jsonb,
+       "REL_CD_66AEF506899F14F936A2F48F9444E2202F5D43F9"                       jsonb,
+       "REL_CD_022F8280C0739C614C5F3293E7D8D349A8A10E30"                       jsonb
 );
 
-ALTER TABLE ONLY ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ALTER COLUMN "REL_CD_040FC8B06B420BA5708AF4798102D1E65FB4DC61" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "REL_CD_040FC8B06B420BA5708AF4798102D1E65FB4DC61" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "REL_CD_66AEF506899F14F936A2F48F9444E2202F5D43F9" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ALTER COLUMN "REL_CD_022F8280C0739C614C5F3293E7D8D349A8A10E30" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."78682DB1FFA2533BA45F8E4FAA5596E1A98479FC" (
+CREATE TABLE IF NOT EXISTS ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" (
        "id"                    VARCHAR(511),
        "name"                  TEXT,
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."78682DB1FFA2533BA45F8E4FAA5596E1A98479FC" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" (
+CREATE TABLE IF NOT EXISTS ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "gNBDUId"                       BIGINT,
        "cmId"                  jsonb,
        "3786A6CA64C9422F9E7FC35B7B039F345BBDDA65"                      TEXT,
-       "gNBIdLength"                   BIGINT,
+       "gNBIdLength"                   INTEGER,
        "dUpLMNId"                      jsonb,
        "gNBId"                 BIGINT,
        "REL_FK_48B14FA5B787C6398AD1DE5EE670AD0D2A2CB36F"                       VARCHAR(511),
        "REL_ID_BDE0B6C74D14AC109D29A08D80E92D4D0DCAEB0B"                       VARCHAR(511),
-       "REL_CD_45E8E8693B1B8928376EAA8995D08AA7B1E483BD"                       jsonb
+       "REL_CD_45E8E8693B1B8928376EAA8995D08AA7B1E483BD"                       jsonb,
+       "REL_CD_7E9F11EFBF8974D7C7DAB02E181A0BE4148091C6"                       jsonb,
+       "REL_CD_FFF7E036187A7605BFC714483D2E60FD2FF6560B"                       jsonb
 );
 
-ALTER TABLE ONLY ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ALTER COLUMN "REL_CD_45E8E8693B1B8928376EAA8995D08AA7B1E483BD" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "REL_CD_45E8E8693B1B8928376EAA8995D08AA7B1E483BD" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "REL_CD_7E9F11EFBF8974D7C7DAB02E181A0BE4148091C6" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ALTER COLUMN "REL_CD_FFF7E036187A7605BFC714483D2E60FD2FF6560B" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" (
+CREATE TABLE IF NOT EXISTS ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" (
        "id"                    VARCHAR(511),
        "aSide_B0FD0521695A211BFF76F413A31F28CBA32E57ED"                        VARCHAR(511),
        "bSide_84EF1134719BB6FCF33A94FF770311FC722BCF41"                        VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" (
+CREATE TABLE IF NOT EXISTS ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" (
        "id"                    VARCHAR(511),
        "aSide_AntennaCapability"                       VARCHAR(511),
        "bSide_AntennaModule"                   VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."AntennaCapability" (
+CREATE TABLE IF NOT EXISTS ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "eUtranFqBands"                 jsonb,
        "fdn"                   TEXT,
        "geranFqBands"                  jsonb,
@@ -160,125 +214,191 @@ CREATE TABLE IF NOT EXISTS ties_data."AntennaCapability" (
        "REL_FK_used-by-lteSectorCarrier"                       VARCHAR(511)
 );
 
-ALTER TABLE ONLY ties_data."AntennaCapability" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."AntennaModule" (
+CREATE TABLE IF NOT EXISTS ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" (
        "id"                    VARCHAR(511),
-       "CD_sourceIds"                  jsonb,
        "totalTilt"                     BIGINT,
+       "cmId"                  jsonb,
+       "antennaBeamWidth"                      jsonb,
+       "positionWithinSector"                  TEXT,
+       "geo-location"                  geography,
        "mechanicalAntennaBearing"                      BIGINT,
        "fdn"                   TEXT,
-       "antennaModelNumber"                    TEXT,
-       "mechanicalAntennaTilt"                 BIGINT,
-       "positionWithinSector"                  TEXT,
-       "cmId"                  jsonb,
        "electricalAntennaTilt"                 BIGINT,
+       "mechanicalAntennaTilt"                 BIGINT,
+       "antennaModelNumber"                    TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "REL_FK_grouped-by-sector"                      VARCHAR(511),
        "REL_ID_SECTOR_GROUPS_ANTENNAMODULE"                    VARCHAR(511),
        "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE"                  jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE"                        jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE"                 jsonb,
        "REL_FK_installed-at-site"                      VARCHAR(511),
        "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE"                        VARCHAR(511),
-       "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE"                      jsonb
+       "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE"                      jsonb,
+       "REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE"                    jsonb,
+       "REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE"                     jsonb
 );
 
-ALTER TABLE ONLY ties_data."AntennaModule" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."AntennaModule" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."AntennaModule" ALTER COLUMN "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ALTER COLUMN "REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" (
+CREATE TABLE IF NOT EXISTS ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" (
        "id"                    VARCHAR(511),
        "aSide_AntennaModule"                   VARCHAR(511),
        "bSide_AntennaModule"                   VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" (
+CREATE TABLE IF NOT EXISTS ties_data."cd39d44beed963d50df42cd301e63d288f911c97" (
        "id"                    VARCHAR(511),
        "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C"                        VARCHAR(511),
        "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E"                        VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" (
+CREATE TABLE IF NOT EXISTS ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" (
        "id"                    VARCHAR(511),
        "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C"                        VARCHAR(511),
        "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E"                        VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."CloudNativeApplication" (
+CREATE TABLE IF NOT EXISTS ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" (
        "id"                    VARCHAR(511),
        "name"                  TEXT,
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "REL_FK_realised-managedElement"                        VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION"                      VARCHAR(511),
        "REL_CD_8F561B5FB3CF928F2C4046CE1A7C37A8FE06B9A7"                       jsonb,
+       "REL_CD_CCEBD4C63B90BD1764CB5A15C282D6CDBDF0B1F2"                       jsonb,
+       "REL_CD_21E2495C31F0DBF735976C90F4CD10D1215190E1"                       jsonb,
        "REL_FK_comprised-by-cloudNativeSystem"                 VARCHAR(511),
        "REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION"                     VARCHAR(511),
        "REL_CD_39262797D0119611B8459ECF46754A074711E485"                       jsonb,
+       "REL_CD_026A1F92A7D93728916AF3DCC2C013FB79E29D07"                       jsonb,
+       "REL_CD_D32E90288E1982363B2BD8DA9D2E90AA16F71575"                       jsonb,
        "REL_FK_deployed-on-namespace"                  VARCHAR(511),
        "REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE"                   VARCHAR(511),
-       "REL_CD_sourceIds_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE"                 jsonb
+       "REL_CD_sourceIds_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE"                 jsonb,
+       "REL_CD_classifiers_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE"                       jsonb,
+       "REL_CD_decorators_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE"                        jsonb
 );
 
-ALTER TABLE ONLY ties_data."CloudNativeApplication" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."CloudNativeApplication" ALTER COLUMN "REL_CD_8F561B5FB3CF928F2C4046CE1A7C37A8FE06B9A7" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_8F561B5FB3CF928F2C4046CE1A7C37A8FE06B9A7" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_CCEBD4C63B90BD1764CB5A15C282D6CDBDF0B1F2" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_21E2495C31F0DBF735976C90F4CD10D1215190E1" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."CloudNativeApplication" ALTER COLUMN "REL_CD_39262797D0119611B8459ECF46754A074711E485" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_39262797D0119611B8459ECF46754A074711E485" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_026A1F92A7D93728916AF3DCC2C013FB79E29D07" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_D32E90288E1982363B2BD8DA9D2E90AA16F71575" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."CloudNativeApplication" ALTER COLUMN "REL_CD_sourceIds_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_sourceIds_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_classifiers_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ALTER COLUMN "REL_CD_decorators_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."CloudNativeSystem" (
+CREATE TABLE IF NOT EXISTS ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" (
        "id"                    VARCHAR(511),
        "CD_sourceIds" jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "REL_FK_deployed-managedElement"                        VARCHAR(511)
 );
 
-ALTER TABLE ONLY ties_data."CloudNativeSystem" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."CloudSite" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" (
        "id"                    VARCHAR(511),
        "CD_sourceIds" jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "geo-location"                  geography
 );
 
-ALTER TABLE ONLY ties_data."CloudSite" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."ENodeBFunction" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" (
        "id"                    VARCHAR(511),
        "fdn"                   TEXT,
        "eNBId"                 BIGINT,
        "cmId"                  jsonb,
        "eNodeBPlmnId"                  jsonb,
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "REL_FK_managed-by-managedElement"                      VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                  VARCHAR(511),
        "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                        jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                      jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION"                       jsonb,
        "REL_FK_realised-by-physicalNetworkAppliance"                   VARCHAR(511),
        "REL_ID_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE"                    VARCHAR(511),
-       "REL_CD_556274C475BA56EE4DEFB691F9037C869223A124"                       jsonb
+       "REL_CD_556274C475BA56EE4DEFB691F9037C869223A124"                       jsonb,
+       "REL_CD_C6C6D295144A637110DA4E6121BE13F30EFDBEBF"                       jsonb,
+       "REL_CD_B369805A0EB24F7C841B0E541A015F85AE2A23B1"                       jsonb
 );
 
-ALTER TABLE ONLY ties_data."ENodeBFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."ENodeBFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."ENodeBFunction" ALTER COLUMN "REL_CD_556274C475BA56EE4DEFB691F9037C869223A124" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_556274C475BA56EE4DEFB691F9037C869223A124" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_C6C6D295144A637110DA4E6121BE13F30EFDBEBF" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ALTER COLUMN "REL_CD_B369805A0EB24F7C841B0E541A015F85AE2A23B1" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."EUtranCell" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "earfcn"                        BIGINT,
        "earfcndl"                      BIGINT,
        "duplexType"                    TEXT,
@@ -290,103 +410,151 @@ CREATE TABLE IF NOT EXISTS ties_data."EUtranCell" (
        "REL_FK_grouped-by-sector"                      VARCHAR(511),
        "REL_ID_SECTOR_GROUPS_EUTRANCELL"                       VARCHAR(511),
        "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL"                     jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL"                   jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL"                    jsonb,
        "REL_FK_provided-by-enodebFunction"                     VARCHAR(511),
        "REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                     VARCHAR(511),
-       "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                   jsonb
+       "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                   jsonb,
+       "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                 jsonb,
+       "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL"                  jsonb
 );
 
-ALTER TABLE ONLY ties_data."EUtranCell" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."EUtranCell" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."EUtranCell" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ALTER COLUMN "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" (
+CREATE TABLE IF NOT EXISTS ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" (
        "id"                    VARCHAR(511),
        "aSide_GNBCUCPFunction"                 VARCHAR(511),
        "bSide_CloudNativeApplication"                  VARCHAR(511),
-       "CD_sourceIds"         jsonb
+       "CD_sourceIds"         jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBCUCPFunction" (
+CREATE TABLE IF NOT EXISTS ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "fdn"                   TEXT,
        "pLMNId"                        jsonb,
        "gNBCUName"                     TEXT,
        "gNBId"                 BIGINT,
        "cmId"                  jsonb,
-       "gNBIdLength"                   BIGINT,
+       "gNBIdLength"                   INTEGER,
        "REL_FK_managed-by-managedElement"                      VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                 VARCHAR(511),
-       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                       jsonb
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                       jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                     jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION"                      jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBCUCPFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."GNBCUCPFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" (
+CREATE TABLE IF NOT EXISTS ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" (
        "id"                    VARCHAR(511),
        "aSide_GNBCUUPFunction"                 VARCHAR(511),
        "bSide_CloudNativeApplication"                  VARCHAR(511),
-       "CD_sourceIds"     jsonb
+       "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBCUUPFunction" (
+CREATE TABLE IF NOT EXISTS ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "gNBId"                 BIGINT,
        "fdn"                   TEXT,
        "cmId"                  jsonb,
-       "gNBIdLength"                   BIGINT,
+       "gNBIdLength"                   INTEGER,
        "REL_FK_managed-by-managedElement"                      VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                 VARCHAR(511),
-       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                       jsonb
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                       jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                     jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION"                      jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBCUUPFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."GNBCUUPFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" (
+CREATE TABLE IF NOT EXISTS ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" (
        "id"                    VARCHAR(511),
        "aSide_GNBDUFunction"                   VARCHAR(511),
        "bSide_CloudNativeApplication"                  VARCHAR(511),
-       "CD_sourceIds"     jsonb
+       "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."GNBDUFunction" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" (
        "id"                    VARCHAR(511),
        "CD_sourceIds" jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "fdn"                   TEXT,
        "gNBId"                 BIGINT,
        "dUpLMNId"                      jsonb,
        "gNBDUId"                       BIGINT,
        "cmId"                  jsonb,
-       "gNBIdLength"                   BIGINT,
+       "gNBIdLength"                   INTEGER,
        "REL_FK_managed-by-managedElement"                      VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"                   VARCHAR(511),
-       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"       jsonb
+       "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"       jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"       jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION"       jsonb
 );
 
-ALTER TABLE ONLY ties_data."GNBDUFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."GNBDUFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."LTESectorCarrier" (
+CREATE TABLE IF NOT EXISTS ties_data."c88307168935f02fdecc084ea5040bb9db16c701" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "sectorCarrierType"                     TEXT,
        "essScLocalId"                  BIGINT,
        "fdn"                   TEXT,
@@ -394,39 +562,63 @@ CREATE TABLE IF NOT EXISTS ties_data."LTESectorCarrier" (
        "REL_FK_provided-by-enodebFunction"                     VARCHAR(511),
        "REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                       VARCHAR(511),
        "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                     jsonb,
+       "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                   jsonb,
+       "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER"                    jsonb,
        "REL_FK_used-antennaCapability"                 VARCHAR(511),
        "REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                        VARCHAR(511),
        "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                      jsonb,
+       "REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                    jsonb,
+       "REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY"                     jsonb,
        "REL_FK_used-by-euTranCell"                     VARCHAR(511),
        "REL_ID_EUTRANCELL_USES_LTESECTORCARRIER"                       VARCHAR(511),
-       "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER"                     jsonb
+       "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER"                     jsonb,
+       "REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER"                   jsonb,
+       "REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER"                    jsonb
 );
 
-ALTER TABLE ONLY ties_data."LTESectorCarrier" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."LTESectorCarrier" ALTER COLUMN "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ALTER COLUMN "REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."ManagedElement" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"     jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "fdn"                   TEXT,
        "cmId"                  jsonb,
        "REL_FK_deployed-as-cloudNativeSystem"                  VARCHAR(511),
        "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"                   VARCHAR(511),
-       "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"                 jsonb
+       "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"                 jsonb,
+       "REL_CD_classifiers_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"                       jsonb,
+       "REL_CD_decorators_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM"                        jsonb
 );
 
-ALTER TABLE ONLY ties_data."ManagedElement" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."ManagedElement" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "REL_CD_sourceIds_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "REL_CD_classifiers_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ALTER COLUMN "REL_CD_decorators_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."NRCellCU" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "nCI"                   BIGINT,
        "plmnId"                        jsonb,
        "fdn"                   TEXT,
@@ -435,17 +627,25 @@ CREATE TABLE IF NOT EXISTS ties_data."NRCellCU" (
        "cmId"                  jsonb,
        "REL_FK_provided-by-gnbcucpFunction"                    VARCHAR(511),
        "REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                      VARCHAR(511),
-       "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                    jsonb
+       "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                    jsonb,
+       "REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                  jsonb,
+       "REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU"                   jsonb
 );
 
-ALTER TABLE ONLY ties_data."NRCellCU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRCellCU" ALTER COLUMN "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ALTER COLUMN "REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."NRCellDU" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "nRTAC"                 BIGINT,
        "fdn"                   TEXT,
        "nRPCI"                 BIGINT,
@@ -455,20 +655,32 @@ CREATE TABLE IF NOT EXISTS ties_data."NRCellDU" (
        "REL_FK_grouped-by-sector"                      VARCHAR(511),
        "REL_ID_SECTOR_GROUPS_NRCELLDU"                 VARCHAR(511),
        "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU"                       jsonb,
+       "REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU"                     jsonb,
+       "REL_CD_decorators_SECTOR_GROUPS_NRCELLDU"                      jsonb,
        "REL_FK_provided-by-gnbduFunction"                      VARCHAR(511),
        "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU"                        VARCHAR(511),
-       "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU"                      jsonb
+       "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU"                      jsonb,
+       "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU"                    jsonb,
+       "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU"                     jsonb
 );
 
-ALTER TABLE ONLY ties_data."NRCellDU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRCellDU" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_decorators_SECTOR_GROUPS_NRCELLDU" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRCellDU" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ALTER COLUMN "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."NRSectorCarrier" (
+CREATE TABLE IF NOT EXISTS ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "frequencyDL"                   BIGINT,
        "arfcnDL"                       BIGINT,
        "fdn"                   TEXT,
@@ -479,876 +691,948 @@ CREATE TABLE IF NOT EXISTS ties_data."NRSectorCarrier" (
        "REL_FK_used-by-nrCellDu"                       VARCHAR(511),
        "REL_ID_NRCELLDU_USES_NRSECTORCARRIER"                  VARCHAR(511),
        "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER"                        jsonb,
+       "REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER"                      jsonb,
+       "REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER"                       jsonb,
        "REL_FK_provided-by-gnbduFunction"                      VARCHAR(511),
        "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                 VARCHAR(511),
        "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                       jsonb,
+       "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                     jsonb,
+       "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER"                      jsonb,
        "REL_FK_used-antennaCapability"                 VARCHAR(511),
        "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                 VARCHAR(511),
-       "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                       jsonb
+       "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                       jsonb,
+       "REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                     jsonb,
+       "REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY"                      jsonb
 );
 
-ALTER TABLE ONLY ties_data."NRSectorCarrier" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NRSectorCarrier" ALTER COLUMN "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ALTER COLUMN "REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."Namespace" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-cloud_Namespace" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "REL_FK_deployed-on-nodeCluster"                        VARCHAR(511),
        "REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER"                      VARCHAR(511),
-       "REL_CD_sourceIds_NAMESPACE_DEPLOYED_ON_NODECLUSTER"                    jsonb
+       "REL_CD_sourceIds_NAMESPACE_DEPLOYED_ON_NODECLUSTER"                    jsonb,
+       "REL_CD_classifiers_NAMESPACE_DEPLOYED_ON_NODECLUSTER"                  jsonb,
+       "REL_CD_decorators_NAMESPACE_DEPLOYED_ON_NODECLUSTER"                   jsonb
 );
 
-ALTER TABLE ONLY ties_data."Namespace" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."Namespace" ALTER COLUMN "REL_CD_sourceIds_NAMESPACE_DEPLOYED_ON_NODECLUSTER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "REL_CD_sourceIds_NAMESPACE_DEPLOYED_ON_NODECLUSTER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "REL_CD_classifiers_NAMESPACE_DEPLOYED_ON_NODECLUSTER" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ALTER COLUMN "REL_CD_decorators_NAMESPACE_DEPLOYED_ON_NODECLUSTER" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."NodeCluster" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "REL_FK_located-at-cloudSite"                   VARCHAR(511),
        "REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE"                       VARCHAR(511),
-       "REL_CD_sourceIds_NODECLUSTER_LOCATED_AT_CLOUDSITE"                     jsonb
+       "REL_CD_sourceIds_NODECLUSTER_LOCATED_AT_CLOUDSITE"                     jsonb,
+       "REL_CD_classifiers_NODECLUSTER_LOCATED_AT_CLOUDSITE"                   jsonb,
+       "REL_CD_decorators_NODECLUSTER_LOCATED_AT_CLOUDSITE"                    jsonb
 );
 
-ALTER TABLE ONLY ties_data."NodeCluster" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."NodeCluster" ALTER COLUMN "REL_CD_sourceIds_NODECLUSTER_LOCATED_AT_CLOUDSITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "REL_CD_sourceIds_NODECLUSTER_LOCATED_AT_CLOUDSITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "REL_CD_classifiers_NODECLUSTER_LOCATED_AT_CLOUDSITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ALTER COLUMN "REL_CD_decorators_NODECLUSTER_LOCATED_AT_CLOUDSITE" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."PhysicalNetworkAppliance" (
+CREATE TABLE IF NOT EXISTS ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "geo-location"                  geography,
        "name"                  TEXT,
        "cmId"                  jsonb,
        "type"                  TEXT,
        "REL_FK_installed-at-site"                      VARCHAR(511),
        "REL_ID_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE"                     VARCHAR(511),
-       "REL_CD_sourceIds_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE"                   jsonb
+       "REL_CD_sourceIds_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE"                   jsonb,
+       "REL_CD_classifiers_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE"                 jsonb,
+       "REL_CD_decorators_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE"                  jsonb
 );
 
-ALTER TABLE ONLY ties_data."PhysicalNetworkAppliance" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."PhysicalNetworkAppliance" ALTER COLUMN "REL_CD_sourceIds_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "REL_CD_sourceIds_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "REL_CD_classifiers_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ALTER COLUMN "REL_CD_decorators_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" SET DEFAULT '{}';
 
 
-CREATE TABLE IF NOT EXISTS ties_data."Sector" (
+CREATE TABLE IF NOT EXISTS ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "azimuth"                       DECIMAL,
        "geo-location"                  geography,
        "sectorId"                      BIGINT
 );
 
-ALTER TABLE ONLY ties_data."Sector" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."Site" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-equipment_Site" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "name"                  TEXT,
        "geo-location"                  geography,
        "cmId"                  jsonb
 );
 
-ALTER TABLE ONLY ties_data."Site" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."TESTENTITYA_GROUPS_TESTENTITYB" (
+CREATE TABLE IF NOT EXISTS ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" (
        "id"                    VARCHAR(511),
        "aSide_TestEntityA"                     VARCHAR(511),
        "bSide_TestEntityB"                     VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."TESTENTITYA_GROUPS_TESTENTITYB" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."TESTENTITYA_PROVIDES_TESTENTITYB" (
+CREATE TABLE IF NOT EXISTS ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" (
        "id"                    VARCHAR(511),
        "aSide_TestEntityA"                     VARCHAR(511),
        "bSide_TestEntityB"                     VARCHAR(511),
-       "CD_sourceIds"                  jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."TESTENTITYA_PROVIDES_TESTENTITYB" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."TestEntityA" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" (
        "id"                    VARCHAR(511),
        "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "attribute1"                    TEXT
 );
 
-ALTER TABLE ONLY ties_data."TestEntityA" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."TestEntityB" (
+CREATE TABLE IF NOT EXISTS ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" (
        "id"                    VARCHAR(511),
-    "CD_sourceIds"                     jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
        "attribute1"                    TEXT,
        "REL_FK_used-by-testEntityA"                    VARCHAR(511),
        "REL_ID_TESTENTITYA_USES_TESTENTITYB"                   VARCHAR(511),
-       "REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB"                 jsonb
+       "REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB"                 jsonb,
+       "REL_CD_classifiers_TESTENTITYA_USES_TESTENTITYB"                       jsonb,
+       "REL_CD_decorators_TESTENTITYA_USES_TESTENTITYB"                        jsonb
 );
 
-ALTER TABLE ONLY ties_data."TestEntityB" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-ALTER TABLE ONLY ties_data."TestEntityB" ALTER COLUMN "REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "REL_CD_classifiers_TESTENTITYA_USES_TESTENTITYB" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ALTER COLUMN "REL_CD_decorators_TESTENTITYA_USES_TESTENTITYB" SET DEFAULT '{}';
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_GROUPS_TESTENTITYB',
+       '70003c8082751e1832e7bc5c0d83db6d22c4fcdc',
  'PK_TESTENTITYA_GROUPS_TESTENTITYB_id',
- 'ALTER TABLE ties_data."TESTENTITYA_GROUPS_TESTENTITYB" ADD CONSTRAINT "PK_TESTENTITYA_GROUPS_TESTENTITYB_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ADD CONSTRAINT "PK_TESTENTITYA_GROUPS_TESTENTITYB_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_PROVIDES_TESTENTITYB',
+       '73936e503f137d82d1422c0f08c66c7ff8b90209',
  'PK_TESTENTITYA_PROVIDES_TESTENTITYB_id',
- 'ALTER TABLE ties_data."TESTENTITYA_PROVIDES_TESTENTITYB" ADD CONSTRAINT "PK_TESTENTITYA_PROVIDES_TESTENTITYB_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ADD CONSTRAINT "PK_TESTENTITYA_PROVIDES_TESTENTITYB_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TestEntityA',
+       'o-ran-smo-teiv-ran-logical_TestEntityA',
  'PK_TestEntityA_id',
- 'ALTER TABLE ties_data."TestEntityA" ADD CONSTRAINT "PK_TestEntityA_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" ADD CONSTRAINT "PK_TestEntityA_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TestEntityB',
+       'o-ran-smo-teiv-ran-logical_TestEntityB',
  'PK_TestEntityB_id',
- 'ALTER TABLE ties_data."TestEntityB" ADD CONSTRAINT "PK_TestEntityB_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ADD CONSTRAINT "PK_TestEntityB_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_GROUPS_TESTENTITYB',
+       '70003c8082751e1832e7bc5c0d83db6d22c4fcdc',
  'FK_TESTENTITYA_GROUPS_TESTENTITYB_aSide_TestEntityA',
- 'ALTER TABLE ties_data."TESTENTITYA_GROUPS_TESTENTITYB" ADD CONSTRAINT "FK_TESTENTITYA_GROUPS_TESTENTITYB_aSide_TestEntityA" FOREIGN KEY ("aSide_TestEntityA") REFERENCES ties_data."TestEntityA" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ADD CONSTRAINT "FK_TESTENTITYA_GROUPS_TESTENTITYB_aSide_TestEntityA" FOREIGN KEY ("aSide_TestEntityA") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_GROUPS_TESTENTITYB',
+       '70003c8082751e1832e7bc5c0d83db6d22c4fcdc',
  'FK_TESTENTITYA_GROUPS_TESTENTITYB_bSide_TestEntityB',
- 'ALTER TABLE ties_data."TESTENTITYA_GROUPS_TESTENTITYB" ADD CONSTRAINT "FK_TESTENTITYA_GROUPS_TESTENTITYB_bSide_TestEntityB" FOREIGN KEY ("bSide_TestEntityB") REFERENCES ties_data."TestEntityB" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."70003c8082751e1832e7bc5c0d83db6d22c4fcdc" ADD CONSTRAINT "FK_TESTENTITYA_GROUPS_TESTENTITYB_bSide_TestEntityB" FOREIGN KEY ("bSide_TestEntityB") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_PROVIDES_TESTENTITYB',
+       '73936e503f137d82d1422c0f08c66c7ff8b90209',
  'FK_TESTENTITYA_PROVIDES_TESTENTITYB_aSide_TestEntityA',
- 'ALTER TABLE ties_data."TESTENTITYA_PROVIDES_TESTENTITYB" ADD CONSTRAINT "FK_TESTENTITYA_PROVIDES_TESTENTITYB_aSide_TestEntityA" FOREIGN KEY ("aSide_TestEntityA") REFERENCES ties_data."TestEntityA" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ADD CONSTRAINT "FK_TESTENTITYA_PROVIDES_TESTENTITYB_aSide_TestEntityA" FOREIGN KEY ("aSide_TestEntityA") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TESTENTITYA_PROVIDES_TESTENTITYB',
+       '73936e503f137d82d1422c0f08c66c7ff8b90209',
  'FK_TESTENTITYA_PROVIDES_TESTENTITYB_bSide_TestEntityB',
- 'ALTER TABLE ties_data."TESTENTITYA_PROVIDES_TESTENTITYB" ADD CONSTRAINT "FK_TESTENTITYA_PROVIDES_TESTENTITYB_bSide_TestEntityB" FOREIGN KEY ("bSide_TestEntityB") REFERENCES ties_data."TestEntityB" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."73936e503f137d82d1422c0f08c66c7ff8b90209" ADD CONSTRAINT "FK_TESTENTITYA_PROVIDES_TESTENTITYB_bSide_TestEntityB" FOREIGN KEY ("bSide_TestEntityB") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TestEntityB',
+       'o-ran-smo-teiv-ran-logical_TestEntityB',
  'FK_TestEntityB_REL_FK_used-by-testEntityA',
- 'ALTER TABLE ties_data."TestEntityB" ADD CONSTRAINT "FK_TestEntityB_REL_FK_used-by-testEntityA" FOREIGN KEY ("REL_FK_used-by-testEntityA") REFERENCES ties_data."TestEntityA" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ADD CONSTRAINT "FK_TestEntityB_REL_FK_used-by-testEntityA" FOREIGN KEY ("REL_FK_used-by-testEntityA") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_TestEntityA" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'TestEntityB',
+       'o-ran-smo-teiv-ran-logical_TestEntityB',
  'UNIQUE_TestEntityB_REL_ID_TESTENTITYA_USES_TESTENTITYB',
- 'ALTER TABLE ties_data."TestEntityB" ADD CONSTRAINT "UNIQUE_TestEntityB_REL_ID_TESTENTITYA_USES_TESTENTITYB" UNIQUE ("REL_ID_TESTENTITYA_USES_TESTENTITYB");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_TestEntityB" ADD CONSTRAINT "UNIQUE_TestEntityB_REL_ID_TESTENTITYA_USES_TESTENTITYB" UNIQUE ("REL_ID_TESTENTITYA_USES_TESTENTITYB");'
 );
 
-ALTER TABLE ONLY ties_data."Site" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."o-ran-smo-teiv-ran-equipment_Site" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
-CREATE TABLE IF NOT EXISTS ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" (
+CREATE TABLE IF NOT EXISTS ties_data."341622dca4e0350289717b52df5883edc3fa0280" (
        "id"                    VARCHAR(511),
        "fdn"                   TEXT,
-    "CD_sourceIds"                     jsonb
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
 );
 
-ALTER TABLE ONLY ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."341622dca4e0350289717b52df5883edc3fa0280" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."341622dca4e0350289717b52df5883edc3fa0280" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+ALTER TABLE ONLY ties_data."341622dca4e0350289717b52df5883edc3fa0280" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F',
+       'ef701af8e1445ed5d377664ba1d3d1c645e31639',
  'PK_F568C5029499EE188A168886B2EF09C0D1FAAA9F',
- 'ALTER TABLE ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" ADD CONSTRAINT "PK_F568C5029499EE188A168886B2EF09C0D1FAAA9F" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ADD CONSTRAINT "PK_F568C5029499EE188A168886B2EF09C0D1FAAA9F" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '1EF2A41C34A961CD8AE603E020B7B8B57345267F',
+       'fa2dceaf53e045c136ce9db9bc5faae65a29fa4d',
  'PK_19E2CBE3A8BBA12A7D9EC9923573BC0A65B1EC4A',
- 'ALTER TABLE ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ADD CONSTRAINT "PK_19E2CBE3A8BBA12A7D9EC9923573BC0A65B1EC4A" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ADD CONSTRAINT "PK_19E2CBE3A8BBA12A7D9EC9923573BC0A65B1EC4A" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '25978231183BE3B9ADD7DBE6C77F5E59696CDE5F',
+       '5f8facd51b2bbddc90d9dee9be697907441892d0',
  'PK_F52E445B46B712C0D9014D194AB039C205E69818',
- 'ALTER TABLE ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ADD CONSTRAINT "PK_F52E445B46B712C0D9014D194AB039C205E69818" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ADD CONSTRAINT "PK_F52E445B46B712C0D9014D194AB039C205E69818" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '50AC08AB775076E74FC4891954F1D99D3D293ACC',
+       '300672c8a708d6af0b9af2f9accdff5e6e005721',
  'PK_CCB39BED50FEF60B1B1F86A7C938BE89B7D90D38',
- 'ALTER TABLE ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ADD CONSTRAINT "PK_CCB39BED50FEF60B1B1F86A7C938BE89B7D90D38" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ADD CONSTRAINT "PK_CCB39BED50FEF60B1B1F86A7C938BE89B7D90D38" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '78682DB1FFA2533BA45F8E4FAA5596E1A98479FC',
+       'bc563e4310b0538e6bdd35f52684160af5b23671',
  'PK_77881E9D6F659316F836050DDC6E26FA4DE425EE',
- 'ALTER TABLE ties_data."78682DB1FFA2533BA45F8E4FAA5596E1A98479FC" ADD CONSTRAINT "PK_77881E9D6F659316F836050DDC6E26FA4DE425EE" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" ADD CONSTRAINT "PK_77881E9D6F659316F836050DDC6E26FA4DE425EE" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '7D7AACEBB0E4E4732835BA4BFE708DDD3738962D',
+       '3fdb9cd7557edf559a0e4de88df220e7545884b5',
  'PK_079D5D67E043B09F9C7CD4F6EA1DB12688D43F69',
- 'ALTER TABLE ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ADD CONSTRAINT "PK_079D5D67E043B09F9C7CD4F6EA1DB12688D43F69" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ADD CONSTRAINT "PK_079D5D67E043B09F9C7CD4F6EA1DB12688D43F69" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AC201B3A42917A9A983A1E3683B67C38C50630FC',
+       'f86057a8762a50b1c7fb07af9d5c001bffaefd15',
  'PK_5D1AC46C58E1FE44FB266F86CE79B3AEBE1D92B3',
- 'ALTER TABLE ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" ADD CONSTRAINT "PK_5D1AC46C58E1FE44FB266F86CE79B3AEBE1D92B3" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ADD CONSTRAINT "PK_5D1AC46C58E1FE44FB266F86CE79B3AEBE1D92B3" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE',
- 'PK_ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE_id',
- 'ALTER TABLE ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "PK_ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE_id" PRIMARY KEY ("id");'
+       '5b8a47d4a8297a0a1d31e091af06e26d25ef6caf',
+ 'PK_5b8a47d4a8297a0a1d31e091af06e26d25ef6caf_id',
+ 'ALTER TABLE ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ADD CONSTRAINT "PK_5b8a47d4a8297a0a1d31e091af06e26d25ef6caf_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaCapability',
+       '88f1bd76c7a935fb505cf235e6819f46c55ec98a',
  'PK_AntennaCapability_id',
- 'ALTER TABLE ties_data."AntennaCapability" ADD CONSTRAINT "PK_AntennaCapability_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ADD CONSTRAINT "PK_AntennaCapability_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaModule',
+       'f8caf5ebe876c3001d67efe06e4d83abf0babe31',
  'PK_AntennaModule_id',
- 'ALTER TABLE ties_data."AntennaModule" ADD CONSTRAINT "PK_AntennaModule_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ADD CONSTRAINT "PK_AntennaModule_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'PK_CloudNativeApplication_id',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "PK_CloudNativeApplication_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "PK_CloudNativeApplication_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeSystem',
+       '163276fa439cdfccabb80f7acacb6fa638e8d314',
  'PK_CloudNativeSystem_id',
- 'ALTER TABLE ties_data."CloudNativeSystem" ADD CONSTRAINT "PK_CloudNativeSystem_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ADD CONSTRAINT "PK_CloudNativeSystem_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudSite',
+       'o-ran-smo-teiv-ran-cloud_CloudSite',
  'PK_CloudSite_id',
- 'ALTER TABLE ties_data."CloudSite" ADD CONSTRAINT "PK_CloudSite_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" ADD CONSTRAINT "PK_CloudSite_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ENodeBFunction',
+       'o-ran-smo-teiv-ran-logical_ENodeBFunction',
  'PK_ENodeBFunction_id',
- 'ALTER TABLE ties_data."ENodeBFunction" ADD CONSTRAINT "PK_ENodeBFunction_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ADD CONSTRAINT "PK_ENodeBFunction_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'EUtranCell',
+       'o-ran-smo-teiv-ran-logical_EUtranCell',
  'PK_EUtranCell_id',
- 'ALTER TABLE ties_data."EUtranCell" ADD CONSTRAINT "PK_EUtranCell_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ADD CONSTRAINT "PK_EUtranCell_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7',
  'PK_GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id',
- 'ALTER TABLE ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "PK_GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ADD CONSTRAINT "PK_GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFunction',
+       'c4a425179d3089b5288fdf059079d0ea26977f0f',
  'PK_GNBCUCPFunction_id',
- 'ALTER TABLE ties_data."GNBCUCPFunction" ADD CONSTRAINT "PK_GNBCUCPFunction_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ADD CONSTRAINT "PK_GNBCUCPFunction_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '70a4a84bca01ea022ab24d8cb82422c572922675',
  'PK_GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id',
- 'ALTER TABLE ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "PK_GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ADD CONSTRAINT "PK_GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFunction',
+       '8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb',
  'PK_GNBCUUPFunction_id',
- 'ALTER TABLE ties_data."GNBCUUPFunction" ADD CONSTRAINT "PK_GNBCUUPFunction_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ADD CONSTRAINT "PK_GNBCUUPFunction_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '10484f157f490eb5b27e40dbfaf4d5f2be17c57c',
  'PK_GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id',
- 'ALTER TABLE ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "PK_GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ADD CONSTRAINT "PK_GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFunction',
+       'o-ran-smo-teiv-ran-logical_GNBDUFunction',
  'PK_GNBDUFunction_id',
- 'ALTER TABLE ties_data."GNBDUFunction" ADD CONSTRAINT "PK_GNBDUFunction_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ADD CONSTRAINT "PK_GNBDUFunction_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'PK_LTESectorCarrier_id',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "PK_LTESectorCarrier_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "PK_LTESectorCarrier_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ManagedElement',
+       'o-ran-smo-teiv-ran-oam_ManagedElement',
  'PK_ManagedElement_id',
- 'ALTER TABLE ties_data."ManagedElement" ADD CONSTRAINT "PK_ManagedElement_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ADD CONSTRAINT "PK_ManagedElement_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellCU',
+       'o-ran-smo-teiv-ran-logical_NRCellCU',
  'PK_NRCellCU_id',
- 'ALTER TABLE ties_data."NRCellCU" ADD CONSTRAINT "PK_NRCellCU_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ADD CONSTRAINT "PK_NRCellCU_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellDU',
+       'o-ran-smo-teiv-ran-logical_NRCellDU',
  'PK_NRCellDU_id',
- 'ALTER TABLE ties_data."NRCellDU" ADD CONSTRAINT "PK_NRCellDU_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ADD CONSTRAINT "PK_NRCellDU_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'PK_NRSectorCarrier_id',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "PK_NRSectorCarrier_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "PK_NRSectorCarrier_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'Namespace',
+       'o-ran-smo-teiv-ran-cloud_Namespace',
  'PK_Namespace_id',
- 'ALTER TABLE ties_data."Namespace" ADD CONSTRAINT "PK_Namespace_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ADD CONSTRAINT "PK_Namespace_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NodeCluster',
+       'o-ran-smo-teiv-ran-cloud_NodeCluster',
  'PK_NodeCluster_id',
- 'ALTER TABLE ties_data."NodeCluster" ADD CONSTRAINT "PK_NodeCluster_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ADD CONSTRAINT "PK_NodeCluster_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'PhysicalNetworkAppliance',
+       '57a20807ab3f39c86b0b5bf9a819e0881353fa1e',
  'PK_PhysicalNetworkAppliance_id',
- 'ALTER TABLE ties_data."PhysicalNetworkAppliance" ADD CONSTRAINT "PK_PhysicalNetworkAppliance_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ADD CONSTRAINT "PK_PhysicalNetworkAppliance_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'Sector',
+       '22174a23af5d5a96143c83ddfa78654df0acb697',
  'PK_Sector_id',
- 'ALTER TABLE ties_data."Sector" ADD CONSTRAINT "PK_Sector_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" ADD CONSTRAINT "PK_Sector_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'Site',
+       'o-ran-smo-teiv-ran-equipment_Site',
  'PK_Site_id',
- 'ALTER TABLE ties_data."Site" ADD CONSTRAINT "PK_Site_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-equipment_Site" ADD CONSTRAINT "PK_Site_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F',
+       'ef701af8e1445ed5d377664ba1d3d1c645e31639',
  'FK_54FE608944AC8EFFFBE7E55744B8BA52F6B29ABB',
- 'ALTER TABLE ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" ADD CONSTRAINT "FK_54FE608944AC8EFFFBE7E55744B8BA52F6B29ABB" FOREIGN KEY ("REL_FK_C2F5EC33C0760F653CE7263A49C0B697FCA2D542") REFERENCES ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ADD CONSTRAINT "FK_54FE608944AC8EFFFBE7E55744B8BA52F6B29ABB" FOREIGN KEY ("REL_FK_C2F5EC33C0760F653CE7263A49C0B697FCA2D542") REFERENCES ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '1EF2A41C34A961CD8AE603E020B7B8B57345267F',
+       'fa2dceaf53e045c136ce9db9bc5faae65a29fa4d',
  'FK_9C091709D40D51DEE4DC87A44695F6EBA2E965DE',
- 'ALTER TABLE ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ADD CONSTRAINT "FK_9C091709D40D51DEE4DC87A44695F6EBA2E965DE" FOREIGN KEY ("REL_FK_26958E3A529C4C8B68A29FDA906F8CD290F66078") REFERENCES ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ADD CONSTRAINT "FK_9C091709D40D51DEE4DC87A44695F6EBA2E965DE" FOREIGN KEY ("REL_FK_26958E3A529C4C8B68A29FDA906F8CD290F66078") REFERENCES ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '1EF2A41C34A961CD8AE603E020B7B8B57345267F',
+       'fa2dceaf53e045c136ce9db9bc5faae65a29fa4d',
  'UNIQUE_9A721779BB5547778B9258ACD73261B9AABFF302',
- 'ALTER TABLE ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ADD CONSTRAINT "UNIQUE_9A721779BB5547778B9258ACD73261B9AABFF302" UNIQUE ("REL_ID_B7945BFD83380F3E12CF99F2B0F838F364027F92");'
+ 'ALTER TABLE ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ADD CONSTRAINT "UNIQUE_9A721779BB5547778B9258ACD73261B9AABFF302" UNIQUE ("REL_ID_B7945BFD83380F3E12CF99F2B0F838F364027F92");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '25978231183BE3B9ADD7DBE6C77F5E59696CDE5F',
+       '5f8facd51b2bbddc90d9dee9be697907441892d0',
  'FK_899FCB466B0BBCC040E945A3E746F5DE53CCCB29',
- 'ALTER TABLE ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ADD CONSTRAINT "FK_899FCB466B0BBCC040E945A3E746F5DE53CCCB29" FOREIGN KEY ("REL_FK_AB87B417CCD05C332DDD0C60F0C6AB41D38B05E5") REFERENCES ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ADD CONSTRAINT "FK_899FCB466B0BBCC040E945A3E746F5DE53CCCB29" FOREIGN KEY ("REL_FK_AB87B417CCD05C332DDD0C60F0C6AB41D38B05E5") REFERENCES ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '25978231183BE3B9ADD7DBE6C77F5E59696CDE5F',
+       '5f8facd51b2bbddc90d9dee9be697907441892d0',
  'UNIQUE_3DDA71C08F678AA7303FE0BD127CC27A80D1DDED',
- 'ALTER TABLE ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ADD CONSTRAINT "UNIQUE_3DDA71C08F678AA7303FE0BD127CC27A80D1DDED" UNIQUE ("REL_ID_FC2F6A5A12917357B548C83F4B0C1AD58FA61413");'
+ 'ALTER TABLE ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ADD CONSTRAINT "UNIQUE_3DDA71C08F678AA7303FE0BD127CC27A80D1DDED" UNIQUE ("REL_ID_FC2F6A5A12917357B548C83F4B0C1AD58FA61413");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '25978231183BE3B9ADD7DBE6C77F5E59696CDE5F',
+       '5f8facd51b2bbddc90d9dee9be697907441892d0',
  'FK_E33FB71E6FAC69C92ADEEC55E63D401D21DF91AE',
- 'ALTER TABLE ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ADD CONSTRAINT "FK_E33FB71E6FAC69C92ADEEC55E63D401D21DF91AE" FOREIGN KEY ("REL_FK_8C98B70070BBD11F90F192DDA3ECF6302390E956") REFERENCES ties_data."78682DB1FFA2533BA45F8E4FAA5596E1A98479FC" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ADD CONSTRAINT "FK_E33FB71E6FAC69C92ADEEC55E63D401D21DF91AE" FOREIGN KEY ("REL_FK_8C98B70070BBD11F90F192DDA3ECF6302390E956") REFERENCES ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '25978231183BE3B9ADD7DBE6C77F5E59696CDE5F',
+       '5f8facd51b2bbddc90d9dee9be697907441892d0',
  'UNIQUE_287E65679DC2108F55F43D62A4325F6DECF372E1',
- 'ALTER TABLE ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ADD CONSTRAINT "UNIQUE_287E65679DC2108F55F43D62A4325F6DECF372E1" UNIQUE ("REL_ID_AFBF10D23507AD3B6408947D2A9AF8465BA7B08C");'
+ 'ALTER TABLE ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ADD CONSTRAINT "UNIQUE_287E65679DC2108F55F43D62A4325F6DECF372E1" UNIQUE ("REL_ID_AFBF10D23507AD3B6408947D2A9AF8465BA7B08C");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '50AC08AB775076E74FC4891954F1D99D3D293ACC',
+       '300672c8a708d6af0b9af2f9accdff5e6e005721',
  'FK_D43434F9F6FD1C14BE14A0EEDA4C9918B26E82F1',
- 'ALTER TABLE ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ADD CONSTRAINT "FK_D43434F9F6FD1C14BE14A0EEDA4C9918B26E82F1" FOREIGN KEY ("REL_FK_609963BFEE15FF824280FBE201313C3CDACDDDCE") REFERENCES ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ADD CONSTRAINT "FK_D43434F9F6FD1C14BE14A0EEDA4C9918B26E82F1" FOREIGN KEY ("REL_FK_609963BFEE15FF824280FBE201313C3CDACDDDCE") REFERENCES ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '50AC08AB775076E74FC4891954F1D99D3D293ACC',
+       '300672c8a708d6af0b9af2f9accdff5e6e005721',
  'UNIQUE_4E6028C8AF5DB6D082B612C5CBB5B32A943C0AAD',
- 'ALTER TABLE ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ADD CONSTRAINT "UNIQUE_4E6028C8AF5DB6D082B612C5CBB5B32A943C0AAD" UNIQUE ("REL_ID_040FC8B06B420BA5708AF4798102D1E65FB4DC61");'
+ 'ALTER TABLE ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ADD CONSTRAINT "UNIQUE_4E6028C8AF5DB6D082B612C5CBB5B32A943C0AAD" UNIQUE ("REL_ID_040FC8B06B420BA5708AF4798102D1E65FB4DC61");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '7D7AACEBB0E4E4732835BA4BFE708DDD3738962D',
+       '3fdb9cd7557edf559a0e4de88df220e7545884b5',
  'FK_C5EB2FEB41FDD27A7CED04A3FD665B4BDEF994F5',
- 'ALTER TABLE ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ADD CONSTRAINT "FK_C5EB2FEB41FDD27A7CED04A3FD665B4BDEF994F5" FOREIGN KEY ("REL_FK_48B14FA5B787C6398AD1DE5EE670AD0D2A2CB36F") REFERENCES ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ADD CONSTRAINT "FK_C5EB2FEB41FDD27A7CED04A3FD665B4BDEF994F5" FOREIGN KEY ("REL_FK_48B14FA5B787C6398AD1DE5EE670AD0D2A2CB36F") REFERENCES ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       '7D7AACEBB0E4E4732835BA4BFE708DDD3738962D',
+       '3fdb9cd7557edf559a0e4de88df220e7545884b5',
  'UNIQUE_176E72F1225D7EEFC222D87B6EC4D66DD968BD13',
- 'ALTER TABLE ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ADD CONSTRAINT "UNIQUE_176E72F1225D7EEFC222D87B6EC4D66DD968BD13" UNIQUE ("REL_ID_BDE0B6C74D14AC109D29A08D80E92D4D0DCAEB0B");'
+ 'ALTER TABLE ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ADD CONSTRAINT "UNIQUE_176E72F1225D7EEFC222D87B6EC4D66DD968BD13" UNIQUE ("REL_ID_BDE0B6C74D14AC109D29A08D80E92D4D0DCAEB0B");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AC201B3A42917A9A983A1E3683B67C38C50630FC',
+       'f86057a8762a50b1c7fb07af9d5c001bffaefd15',
  'FK_BFC9C18D6DBCD1FFC021B021CF31444EAA1FEDCA',
- 'ALTER TABLE ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" ADD CONSTRAINT "FK_BFC9C18D6DBCD1FFC021B021CF31444EAA1FEDCA" FOREIGN KEY ("aSide_B0FD0521695A211BFF76F413A31F28CBA32E57ED") REFERENCES ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ADD CONSTRAINT "FK_BFC9C18D6DBCD1FFC021B021CF31444EAA1FEDCA" FOREIGN KEY ("aSide_B0FD0521695A211BFF76F413A31F28CBA32E57ED") REFERENCES ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AC201B3A42917A9A983A1E3683B67C38C50630FC',
+       'f86057a8762a50b1c7fb07af9d5c001bffaefd15',
  'FK_EADC754A352728E72F7320F69D802725C71EDE3E',
- 'ALTER TABLE ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" ADD CONSTRAINT "FK_EADC754A352728E72F7320F69D802725C71EDE3E" FOREIGN KEY ("bSide_84EF1134719BB6FCF33A94FF770311FC722BCF41") REFERENCES ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ADD CONSTRAINT "FK_EADC754A352728E72F7320F69D802725C71EDE3E" FOREIGN KEY ("bSide_84EF1134719BB6FCF33A94FF770311FC722BCF41") REFERENCES ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE',
+       '5b8a47d4a8297a0a1d31e091af06e26d25ef6caf',
  'FK_03713853A2B7ACDC198858CAFBFF355026FEA0B3',
- 'ALTER TABLE ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "FK_03713853A2B7ACDC198858CAFBFF355026FEA0B3" FOREIGN KEY ("aSide_AntennaCapability") REFERENCES ties_data."AntennaCapability" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ADD CONSTRAINT "FK_03713853A2B7ACDC198858CAFBFF355026FEA0B3" FOREIGN KEY ("aSide_AntennaCapability") REFERENCES ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE',
+       '5b8a47d4a8297a0a1d31e091af06e26d25ef6caf',
  'FK_5059CE8D2FEE5A1FAD9E06F4FAAFC148BAEA70E3',
- 'ALTER TABLE ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "FK_5059CE8D2FEE5A1FAD9E06F4FAAFC148BAEA70E3" FOREIGN KEY ("bSide_AntennaModule") REFERENCES ties_data."AntennaModule" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ADD CONSTRAINT "FK_5059CE8D2FEE5A1FAD9E06F4FAAFC148BAEA70E3" FOREIGN KEY ("bSide_AntennaModule") REFERENCES ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaCapability',
+       '88f1bd76c7a935fb505cf235e6819f46c55ec98a',
  'FK_AntennaCapability_REL_FK_used-by-lteSectorCarrier',
- 'ALTER TABLE ties_data."AntennaCapability" ADD CONSTRAINT "FK_AntennaCapability_REL_FK_used-by-lteSectorCarrier" FOREIGN KEY ("REL_FK_used-by-lteSectorCarrier") REFERENCES ties_data."LTESectorCarrier" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ADD CONSTRAINT "FK_AntennaCapability_REL_FK_used-by-lteSectorCarrier" FOREIGN KEY ("REL_FK_used-by-lteSectorCarrier") REFERENCES ties_data."c88307168935f02fdecc084ea5040bb9db16c701" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaModule',
+       'f8caf5ebe876c3001d67efe06e4d83abf0babe31',
  'FK_AntennaModule_REL_FK_grouped-by-sector',
- 'ALTER TABLE ties_data."AntennaModule" ADD CONSTRAINT "FK_AntennaModule_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."Sector" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ADD CONSTRAINT "FK_AntennaModule_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaModule',
+       'f8caf5ebe876c3001d67efe06e4d83abf0babe31',
  'UNIQUE_AntennaModule_REL_ID_SECTOR_GROUPS_ANTENNAMODULE',
- 'ALTER TABLE ties_data."AntennaModule" ADD CONSTRAINT "UNIQUE_AntennaModule_REL_ID_SECTOR_GROUPS_ANTENNAMODULE" UNIQUE ("REL_ID_SECTOR_GROUPS_ANTENNAMODULE");'
+ 'ALTER TABLE ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ADD CONSTRAINT "UNIQUE_AntennaModule_REL_ID_SECTOR_GROUPS_ANTENNAMODULE" UNIQUE ("REL_ID_SECTOR_GROUPS_ANTENNAMODULE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaModule',
+       'f8caf5ebe876c3001d67efe06e4d83abf0babe31',
  'FK_AntennaModule_REL_FK_installed-at-site',
- 'ALTER TABLE ties_data."AntennaModule" ADD CONSTRAINT "FK_AntennaModule_REL_FK_installed-at-site" FOREIGN KEY ("REL_FK_installed-at-site") REFERENCES ties_data."Site" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ADD CONSTRAINT "FK_AntennaModule_REL_FK_installed-at-site" FOREIGN KEY ("REL_FK_installed-at-site") REFERENCES ties_data."o-ran-smo-teiv-ran-equipment_Site" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'AntennaModule',
+       'f8caf5ebe876c3001d67efe06e4d83abf0babe31',
  'UNIQUE_AntennaModule_REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE',
- 'ALTER TABLE ties_data."AntennaModule" ADD CONSTRAINT "UNIQUE_AntennaModule_REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE" UNIQUE ("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE");'
+ 'ALTER TABLE ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ADD CONSTRAINT "UNIQUE_AntennaModule_REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE" UNIQUE ("REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'FK_CloudNativeApplication_REL_FK_realised-managedElement',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_realised-managedElement" FOREIGN KEY ("REL_FK_realised-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_realised-managedElement" FOREIGN KEY ("REL_FK_realised-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'UNIQUE_DAB3C12479849DA6C222B812C2A8CD1535D0C186',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "UNIQUE_DAB3C12479849DA6C222B812C2A8CD1535D0C186" UNIQUE ("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION");'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "UNIQUE_DAB3C12479849DA6C222B812C2A8CD1535D0C186" UNIQUE ("REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'FK_CloudNativeApplication_REL_FK_comprised-by-cloudNativeSystem',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_comprised-by-cloudNativeSystem" FOREIGN KEY ("REL_FK_comprised-by-cloudNativeSystem") REFERENCES ties_data."CloudNativeSystem" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_comprised-by-cloudNativeSystem" FOREIGN KEY ("REL_FK_comprised-by-cloudNativeSystem") REFERENCES ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'UNIQUE_F2774BC0806E925ADA0B1CAA50B5A41DFB7BF79A',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "UNIQUE_F2774BC0806E925ADA0B1CAA50B5A41DFB7BF79A" UNIQUE ("REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION");'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "UNIQUE_F2774BC0806E925ADA0B1CAA50B5A41DFB7BF79A" UNIQUE ("REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'FK_CloudNativeApplication_REL_FK_deployed-on-namespace',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_deployed-on-namespace" FOREIGN KEY ("REL_FK_deployed-on-namespace") REFERENCES ties_data."Namespace" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "FK_CloudNativeApplication_REL_FK_deployed-on-namespace" FOREIGN KEY ("REL_FK_deployed-on-namespace") REFERENCES ties_data."o-ran-smo-teiv-ran-cloud_Namespace" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeApplication',
+       'e01fcb87ad2c34ce66c34420255e25aaca270e5e',
  'UNIQUE_1A317D31DA93B0CF9A9F8A04077B0F60ABCFF49C',
- 'ALTER TABLE ties_data."CloudNativeApplication" ADD CONSTRAINT "UNIQUE_1A317D31DA93B0CF9A9F8A04077B0F60ABCFF49C" UNIQUE ("REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE");'
+ 'ALTER TABLE ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ADD CONSTRAINT "UNIQUE_1A317D31DA93B0CF9A9F8A04077B0F60ABCFF49C" UNIQUE ("REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'CloudNativeSystem',
+       '163276fa439cdfccabb80f7acacb6fa638e8d314',
  'FK_CloudNativeSystem_REL_FK_deployed-managedElement',
- 'ALTER TABLE ties_data."CloudNativeSystem" ADD CONSTRAINT "FK_CloudNativeSystem_REL_FK_deployed-managedElement" FOREIGN KEY ("REL_FK_deployed-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ADD CONSTRAINT "FK_CloudNativeSystem_REL_FK_deployed-managedElement" FOREIGN KEY ("REL_FK_deployed-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ENodeBFunction',
+       'o-ran-smo-teiv-ran-logical_ENodeBFunction',
  'FK_ENodeBFunction_REL_FK_managed-by-managedElement',
- 'ALTER TABLE ties_data."ENodeBFunction" ADD CONSTRAINT "FK_ENodeBFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ADD CONSTRAINT "FK_ENodeBFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ENodeBFunction',
+       'o-ran-smo-teiv-ran-logical_ENodeBFunction',
  'UNIQUE_F33037EE8037D0606D15FFB45EE8A27FD6DE30EE',
- 'ALTER TABLE ties_data."ENodeBFunction" ADD CONSTRAINT "UNIQUE_F33037EE8037D0606D15FFB45EE8A27FD6DE30EE" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ADD CONSTRAINT "UNIQUE_F33037EE8037D0606D15FFB45EE8A27FD6DE30EE" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ENodeBFunction',
+       'o-ran-smo-teiv-ran-logical_ENodeBFunction',
  'FK_ENodeBFunction_REL_FK_realised-by-physicalNetworkAppliance',
- 'ALTER TABLE ties_data."ENodeBFunction" ADD CONSTRAINT "FK_ENodeBFunction_REL_FK_realised-by-physicalNetworkAppliance" FOREIGN KEY ("REL_FK_realised-by-physicalNetworkAppliance") REFERENCES ties_data."PhysicalNetworkAppliance" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ADD CONSTRAINT "FK_ENodeBFunction_REL_FK_realised-by-physicalNetworkAppliance" FOREIGN KEY ("REL_FK_realised-by-physicalNetworkAppliance") REFERENCES ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ENodeBFunction',
+       'o-ran-smo-teiv-ran-logical_ENodeBFunction',
  'UNIQUE_6964DA7D7CC1F79A3DB8B43E5F77E42DF8DFBF73',
- 'ALTER TABLE ties_data."ENodeBFunction" ADD CONSTRAINT "UNIQUE_6964DA7D7CC1F79A3DB8B43E5F77E42DF8DFBF73" UNIQUE ("REL_ID_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ADD CONSTRAINT "UNIQUE_6964DA7D7CC1F79A3DB8B43E5F77E42DF8DFBF73" UNIQUE ("REL_ID_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'EUtranCell',
+       'o-ran-smo-teiv-ran-logical_EUtranCell',
  'FK_EUtranCell_REL_FK_grouped-by-sector',
- 'ALTER TABLE ties_data."EUtranCell" ADD CONSTRAINT "FK_EUtranCell_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."Sector" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ADD CONSTRAINT "FK_EUtranCell_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'EUtranCell',
+       'o-ran-smo-teiv-ran-logical_EUtranCell',
  'UNIQUE_EUtranCell_REL_ID_SECTOR_GROUPS_EUTRANCELL',
- 'ALTER TABLE ties_data."EUtranCell" ADD CONSTRAINT "UNIQUE_EUtranCell_REL_ID_SECTOR_GROUPS_EUTRANCELL" UNIQUE ("REL_ID_SECTOR_GROUPS_EUTRANCELL");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ADD CONSTRAINT "UNIQUE_EUtranCell_REL_ID_SECTOR_GROUPS_EUTRANCELL" UNIQUE ("REL_ID_SECTOR_GROUPS_EUTRANCELL");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'EUtranCell',
+       'o-ran-smo-teiv-ran-logical_EUtranCell',
  'FK_EUtranCell_REL_FK_provided-by-enodebFunction',
- 'ALTER TABLE ties_data."EUtranCell" ADD CONSTRAINT "FK_EUtranCell_REL_FK_provided-by-enodebFunction" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."ENodeBFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ADD CONSTRAINT "FK_EUtranCell_REL_FK_provided-by-enodebFunction" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'EUtranCell',
+       'o-ran-smo-teiv-ran-logical_EUtranCell',
  'UNIQUE_EUtranCell_REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL',
- 'ALTER TABLE ties_data."EUtranCell" ADD CONSTRAINT "UNIQUE_EUtranCell_REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ADD CONSTRAINT "UNIQUE_EUtranCell_REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7',
  'FK_B2DDDC542E95DD31826EECEBBF67FD01DAF48833',
- 'ALTER TABLE ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_B2DDDC542E95DD31826EECEBBF67FD01DAF48833" FOREIGN KEY ("aSide_GNBCUCPFunction") REFERENCES ties_data."GNBCUCPFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ADD CONSTRAINT "FK_B2DDDC542E95DD31826EECEBBF67FD01DAF48833" FOREIGN KEY ("aSide_GNBCUCPFunction") REFERENCES ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7',
  'FK_95C3AD1FCFBD310B9947B9B622CA8E0FC2135DC5',
- 'ALTER TABLE ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_95C3AD1FCFBD310B9947B9B622CA8E0FC2135DC5" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."CloudNativeApplication" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ADD CONSTRAINT "FK_95C3AD1FCFBD310B9947B9B622CA8E0FC2135DC5" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFunction',
+       'c4a425179d3089b5288fdf059079d0ea26977f0f',
  'FK_GNBCUCPFunction_REL_FK_managed-by-managedElement',
- 'ALTER TABLE ties_data."GNBCUCPFunction" ADD CONSTRAINT "FK_GNBCUCPFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ADD CONSTRAINT "FK_GNBCUCPFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUCPFunction',
+       'c4a425179d3089b5288fdf059079d0ea26977f0f',
  'UNIQUE_249F73FF1F4316A56DEF4424FA43C2064FFBE4DD',
- 'ALTER TABLE ties_data."GNBCUCPFunction" ADD CONSTRAINT "UNIQUE_249F73FF1F4316A56DEF4424FA43C2064FFBE4DD" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");'
+ 'ALTER TABLE ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ADD CONSTRAINT "UNIQUE_249F73FF1F4316A56DEF4424FA43C2064FFBE4DD" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '70a4a84bca01ea022ab24d8cb82422c572922675',
  'FK_F3346189A1BB0DA705219A4136349DF50AE8AA33',
- 'ALTER TABLE ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_F3346189A1BB0DA705219A4136349DF50AE8AA33" FOREIGN KEY ("aSide_GNBCUUPFunction") REFERENCES ties_data."GNBCUUPFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ADD CONSTRAINT "FK_F3346189A1BB0DA705219A4136349DF50AE8AA33" FOREIGN KEY ("aSide_GNBCUUPFunction") REFERENCES ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '70a4a84bca01ea022ab24d8cb82422c572922675',
  'FK_36215EA9FC5F31CC0F131E526A84A54CB006C66B',
- 'ALTER TABLE ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_36215EA9FC5F31CC0F131E526A84A54CB006C66B" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."CloudNativeApplication" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ADD CONSTRAINT "FK_36215EA9FC5F31CC0F131E526A84A54CB006C66B" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFunction',
+       '8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb',
  'FK_GNBCUUPFunction_REL_FK_managed-by-managedElement',
- 'ALTER TABLE ties_data."GNBCUUPFunction" ADD CONSTRAINT "FK_GNBCUUPFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ADD CONSTRAINT "FK_GNBCUUPFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBCUUPFunction',
+       '8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb',
  'UNIQUE_BDB349CDF0C4055902881ECCB71F460AE1DD323E',
- 'ALTER TABLE ties_data."GNBCUUPFunction" ADD CONSTRAINT "UNIQUE_BDB349CDF0C4055902881ECCB71F460AE1DD323E" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION");'
+ 'ALTER TABLE ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ADD CONSTRAINT "UNIQUE_BDB349CDF0C4055902881ECCB71F460AE1DD323E" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '10484f157f490eb5b27e40dbfaf4d5f2be17c57c',
  'FK_69C6800CC81731E475893CC85582971C7530C98E',
- 'ALTER TABLE ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_69C6800CC81731E475893CC85582971C7530C98E" FOREIGN KEY ("aSide_GNBDUFunction") REFERENCES ties_data."GNBDUFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ADD CONSTRAINT "FK_69C6800CC81731E475893CC85582971C7530C98E" FOREIGN KEY ("aSide_GNBDUFunction") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION',
+       '10484f157f490eb5b27e40dbfaf4d5f2be17c57c',
  'FK_CA6721EE0944CBBB8E071CEA630162ABD7DFF2DA',
- 'ALTER TABLE ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ADD CONSTRAINT "FK_CA6721EE0944CBBB8E071CEA630162ABD7DFF2DA" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."CloudNativeApplication" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ADD CONSTRAINT "FK_CA6721EE0944CBBB8E071CEA630162ABD7DFF2DA" FOREIGN KEY ("bSide_CloudNativeApplication") REFERENCES ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFunction',
+       'o-ran-smo-teiv-ran-logical_GNBDUFunction',
  'FK_GNBDUFunction_REL_FK_managed-by-managedElement',
- 'ALTER TABLE ties_data."GNBDUFunction" ADD CONSTRAINT "FK_GNBDUFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."ManagedElement" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ADD CONSTRAINT "FK_GNBDUFunction_REL_FK_managed-by-managedElement" FOREIGN KEY ("REL_FK_managed-by-managedElement") REFERENCES ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'GNBDUFunction',
+       'o-ran-smo-teiv-ran-logical_GNBDUFunction',
  'UNIQUE_08DFEFAF56EDDE43CBDC336F459D28C6518D3E1D',
- 'ALTER TABLE ties_data."GNBDUFunction" ADD CONSTRAINT "UNIQUE_08DFEFAF56EDDE43CBDC336F459D28C6518D3E1D" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ADD CONSTRAINT "UNIQUE_08DFEFAF56EDDE43CBDC336F459D28C6518D3E1D" UNIQUE ("REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'FK_LTESectorCarrier_REL_FK_provided-by-enodebFunction',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_provided-by-enodebFunction" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."ENodeBFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_provided-by-enodebFunction" FOREIGN KEY ("REL_FK_provided-by-enodebFunction") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'UNIQUE_B9770D6C26DDA0173DB9690F6E3B42C111AF26E9',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "UNIQUE_B9770D6C26DDA0173DB9690F6E3B42C111AF26E9" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER");'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "UNIQUE_B9770D6C26DDA0173DB9690F6E3B42C111AF26E9" UNIQUE ("REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'FK_LTESectorCarrier_REL_FK_used-antennaCapability',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_used-antennaCapability" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."AntennaCapability" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_used-antennaCapability" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'UNIQUE_5D5FEB6B4B09D5D42A589753C684994CD0B96E88',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "UNIQUE_5D5FEB6B4B09D5D42A589753C684994CD0B96E88" UNIQUE ("REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY");'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "UNIQUE_5D5FEB6B4B09D5D42A589753C684994CD0B96E88" UNIQUE ("REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'FK_LTESectorCarrier_REL_FK_used-by-euTranCell',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_used-by-euTranCell" FOREIGN KEY ("REL_FK_used-by-euTranCell") REFERENCES ties_data."EUtranCell" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "FK_LTESectorCarrier_REL_FK_used-by-euTranCell" FOREIGN KEY ("REL_FK_used-by-euTranCell") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'LTESectorCarrier',
+       'c88307168935f02fdecc084ea5040bb9db16c701',
  'UNIQUE_LTESectorCarrier_REL_ID_EUTRANCELL_USES_LTESECTORCARRIER',
- 'ALTER TABLE ties_data."LTESectorCarrier" ADD CONSTRAINT "UNIQUE_LTESectorCarrier_REL_ID_EUTRANCELL_USES_LTESECTORCARRIER" UNIQUE ("REL_ID_EUTRANCELL_USES_LTESECTORCARRIER");'
+ 'ALTER TABLE ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ADD CONSTRAINT "UNIQUE_LTESectorCarrier_REL_ID_EUTRANCELL_USES_LTESECTORCARRIER" UNIQUE ("REL_ID_EUTRANCELL_USES_LTESECTORCARRIER");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ManagedElement',
+       'o-ran-smo-teiv-ran-oam_ManagedElement',
  'FK_ManagedElement_REL_FK_deployed-as-cloudNativeSystem',
- 'ALTER TABLE ties_data."ManagedElement" ADD CONSTRAINT "FK_ManagedElement_REL_FK_deployed-as-cloudNativeSystem" FOREIGN KEY ("REL_FK_deployed-as-cloudNativeSystem") REFERENCES ties_data."CloudNativeSystem" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ADD CONSTRAINT "FK_ManagedElement_REL_FK_deployed-as-cloudNativeSystem" FOREIGN KEY ("REL_FK_deployed-as-cloudNativeSystem") REFERENCES ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ManagedElement',
+       'o-ran-smo-teiv-ran-oam_ManagedElement',
  'UNIQUE_ADD7C124AEF822CB0293FC75E39449DC1AD097E5',
- 'ALTER TABLE ties_data."ManagedElement" ADD CONSTRAINT "UNIQUE_ADD7C124AEF822CB0293FC75E39449DC1AD097E5" UNIQUE ("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ADD CONSTRAINT "UNIQUE_ADD7C124AEF822CB0293FC75E39449DC1AD097E5" UNIQUE ("REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellCU',
+       'o-ran-smo-teiv-ran-logical_NRCellCU',
  'FK_NRCellCU_REL_FK_provided-by-gnbcucpFunction',
- 'ALTER TABLE ties_data."NRCellCU" ADD CONSTRAINT "FK_NRCellCU_REL_FK_provided-by-gnbcucpFunction" FOREIGN KEY ("REL_FK_provided-by-gnbcucpFunction") REFERENCES ties_data."GNBCUCPFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ADD CONSTRAINT "FK_NRCellCU_REL_FK_provided-by-gnbcucpFunction" FOREIGN KEY ("REL_FK_provided-by-gnbcucpFunction") REFERENCES ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellCU',
+       'o-ran-smo-teiv-ran-logical_NRCellCU',
  'UNIQUE_NRCellCU_REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU',
- 'ALTER TABLE ties_data."NRCellCU" ADD CONSTRAINT "UNIQUE_NRCellCU_REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" UNIQUE ("REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ADD CONSTRAINT "UNIQUE_NRCellCU_REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" UNIQUE ("REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellDU',
+       'o-ran-smo-teiv-ran-logical_NRCellDU',
  'FK_NRCellDU_REL_FK_grouped-by-sector',
- 'ALTER TABLE ties_data."NRCellDU" ADD CONSTRAINT "FK_NRCellDU_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."Sector" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ADD CONSTRAINT "FK_NRCellDU_REL_FK_grouped-by-sector" FOREIGN KEY ("REL_FK_grouped-by-sector") REFERENCES ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellDU',
+       'o-ran-smo-teiv-ran-logical_NRCellDU',
  'UNIQUE_NRCellDU_REL_ID_SECTOR_GROUPS_NRCELLDU',
- 'ALTER TABLE ties_data."NRCellDU" ADD CONSTRAINT "UNIQUE_NRCellDU_REL_ID_SECTOR_GROUPS_NRCELLDU" UNIQUE ("REL_ID_SECTOR_GROUPS_NRCELLDU");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ADD CONSTRAINT "UNIQUE_NRCellDU_REL_ID_SECTOR_GROUPS_NRCELLDU" UNIQUE ("REL_ID_SECTOR_GROUPS_NRCELLDU");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellDU',
+       'o-ran-smo-teiv-ran-logical_NRCellDU',
  'FK_NRCellDU_REL_FK_provided-by-gnbduFunction',
- 'ALTER TABLE ties_data."NRCellDU" ADD CONSTRAINT "FK_NRCellDU_REL_FK_provided-by-gnbduFunction" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."GNBDUFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ADD CONSTRAINT "FK_NRCellDU_REL_FK_provided-by-gnbduFunction" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRCellDU',
+       'o-ran-smo-teiv-ran-logical_NRCellDU',
  'UNIQUE_NRCellDU_REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU',
- 'ALTER TABLE ties_data."NRCellDU" ADD CONSTRAINT "UNIQUE_NRCellDU_REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ADD CONSTRAINT "UNIQUE_NRCellDU_REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'FK_NRSectorCarrier_REL_FK_used-by-nrCellDu',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_used-by-nrCellDu" FOREIGN KEY ("REL_FK_used-by-nrCellDu") REFERENCES ties_data."NRCellDU" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_used-by-nrCellDu" FOREIGN KEY ("REL_FK_used-by-nrCellDu") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'UNIQUE_NRSectorCarrier_REL_ID_NRCELLDU_USES_NRSECTORCARRIER',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "UNIQUE_NRSectorCarrier_REL_ID_NRCELLDU_USES_NRSECTORCARRIER" UNIQUE ("REL_ID_NRCELLDU_USES_NRSECTORCARRIER");'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "UNIQUE_NRSectorCarrier_REL_ID_NRCELLDU_USES_NRSECTORCARRIER" UNIQUE ("REL_ID_NRCELLDU_USES_NRSECTORCARRIER");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'FK_NRSectorCarrier_REL_FK_provided-by-gnbduFunction',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_provided-by-gnbduFunction" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."GNBDUFunction" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_provided-by-gnbduFunction" FOREIGN KEY ("REL_FK_provided-by-gnbduFunction") REFERENCES ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'UNIQUE_872BE05F1989443F2595D99A77BC03733B2D1E2F',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "UNIQUE_872BE05F1989443F2595D99A77BC03733B2D1E2F" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "UNIQUE_872BE05F1989443F2595D99A77BC03733B2D1E2F" UNIQUE ("REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'FK_NRSectorCarrier_REL_FK_used-antennaCapability',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_used-antennaCapability" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."AntennaCapability" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "FK_NRSectorCarrier_REL_FK_used-antennaCapability" FOREIGN KEY ("REL_FK_used-antennaCapability") REFERENCES ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NRSectorCarrier',
+       '39a335dca201ef99ae06f4ffd1908b534f8c6c39',
  'UNIQUE_EDF7D5C78EF6505848B1679B714D7831F5863991',
- 'ALTER TABLE ties_data."NRSectorCarrier" ADD CONSTRAINT "UNIQUE_EDF7D5C78EF6505848B1679B714D7831F5863991" UNIQUE ("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY");'
+ 'ALTER TABLE ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ADD CONSTRAINT "UNIQUE_EDF7D5C78EF6505848B1679B714D7831F5863991" UNIQUE ("REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'Namespace',
+       'o-ran-smo-teiv-ran-cloud_Namespace',
  'FK_Namespace_REL_FK_deployed-on-nodeCluster',
- 'ALTER TABLE ties_data."Namespace" ADD CONSTRAINT "FK_Namespace_REL_FK_deployed-on-nodeCluster" FOREIGN KEY ("REL_FK_deployed-on-nodeCluster") REFERENCES ties_data."NodeCluster" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ADD CONSTRAINT "FK_Namespace_REL_FK_deployed-on-nodeCluster" FOREIGN KEY ("REL_FK_deployed-on-nodeCluster") REFERENCES ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'Namespace',
+       'o-ran-smo-teiv-ran-cloud_Namespace',
  'UNIQUE_Namespace_REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER',
- 'ALTER TABLE ties_data."Namespace" ADD CONSTRAINT "UNIQUE_Namespace_REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER" UNIQUE ("REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ADD CONSTRAINT "UNIQUE_Namespace_REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER" UNIQUE ("REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NodeCluster',
+       'o-ran-smo-teiv-ran-cloud_NodeCluster',
  'FK_NodeCluster_REL_FK_located-at-cloudSite',
- 'ALTER TABLE ties_data."NodeCluster" ADD CONSTRAINT "FK_NodeCluster_REL_FK_located-at-cloudSite" FOREIGN KEY ("REL_FK_located-at-cloudSite") REFERENCES ties_data."CloudSite" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ADD CONSTRAINT "FK_NodeCluster_REL_FK_located-at-cloudSite" FOREIGN KEY ("REL_FK_located-at-cloudSite") REFERENCES ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'NodeCluster',
+       'o-ran-smo-teiv-ran-cloud_NodeCluster',
  'UNIQUE_NodeCluster_REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE',
- 'ALTER TABLE ties_data."NodeCluster" ADD CONSTRAINT "UNIQUE_NodeCluster_REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE" UNIQUE ("REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE");'
+ 'ALTER TABLE ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ADD CONSTRAINT "UNIQUE_NodeCluster_REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE" UNIQUE ("REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'PhysicalNetworkAppliance',
+       '57a20807ab3f39c86b0b5bf9a819e0881353fa1e',
  'FK_PhysicalNetworkAppliance_REL_FK_installed-at-site',
- 'ALTER TABLE ties_data."PhysicalNetworkAppliance" ADD CONSTRAINT "FK_PhysicalNetworkAppliance_REL_FK_installed-at-site" FOREIGN KEY ("REL_FK_installed-at-site") REFERENCES ties_data."Site" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ADD CONSTRAINT "FK_PhysicalNetworkAppliance_REL_FK_installed-at-site" FOREIGN KEY ("REL_FK_installed-at-site") REFERENCES ties_data."o-ran-smo-teiv-ran-equipment_Site" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'PhysicalNetworkAppliance',
+       '57a20807ab3f39c86b0b5bf9a819e0881353fa1e',
  'UNIQUE_A9110A77514C472452AC80053A8010FBAF481AD0',
- 'ALTER TABLE ties_data."PhysicalNetworkAppliance" ADD CONSTRAINT "UNIQUE_A9110A77514C472452AC80053A8010FBAF481AD0" UNIQUE ("REL_ID_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE");'
+ 'ALTER TABLE ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ADD CONSTRAINT "UNIQUE_A9110A77514C472452AC80053A8010FBAF481AD0" UNIQUE ("REL_ID_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNAMODULE_REALISED_BY_ANTENNAMODULE',
+       '5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6',
  'PK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_id',
- 'ALTER TABLE ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "PK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_id" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ADD CONSTRAINT "PK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_id" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNAMODULE_REALISED_BY_ANTENNAMODULE',
+       '5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6',
  'FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_aSide_AntennaModule',
- 'ALTER TABLE ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_aSide_AntennaModule" FOREIGN KEY ("aSide_AntennaModule") REFERENCES ties_data."AntennaModule" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ADD CONSTRAINT "FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_aSide_AntennaModule" FOREIGN KEY ("aSide_AntennaModule") REFERENCES ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'ANTENNAMODULE_REALISED_BY_ANTENNAMODULE',
+       '5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6',
  'FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_bSide_AntennaModule',
- 'ALTER TABLE ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" ADD CONSTRAINT "FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_bSide_AntennaModule" FOREIGN KEY ("bSide_AntennaModule") REFERENCES ties_data."AntennaModule" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ADD CONSTRAINT "FK_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE_bSide_AntennaModule" FOREIGN KEY ("bSide_AntennaModule") REFERENCES ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'B69D3E92CA22CE61B921AE61BD3CF031791CF714',
+       '341622dca4e0350289717b52df5883edc3fa0280',
  'PK_2673E8FB17E57FD56D5E897DA13412B9165B90AA',
- 'ALTER TABLE ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" ADD CONSTRAINT "PK_2673E8FB17E57FD56D5E897DA13412B9165B90AA" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."341622dca4e0350289717b52df5883edc3fa0280" ADD CONSTRAINT "PK_2673E8FB17E57FD56D5E897DA13412B9165B90AA" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6',
+       'cd39d44beed963d50df42cd301e63d288f911c97',
  'PK_E3722EAF721B41FACDCF065D2017267CE2C90BED',
- 'ALTER TABLE ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" ADD CONSTRAINT "PK_E3722EAF721B41FACDCF065D2017267CE2C90BED" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ADD CONSTRAINT "PK_E3722EAF721B41FACDCF065D2017267CE2C90BED" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6',
+       'cd39d44beed963d50df42cd301e63d288f911c97',
  'FK_00AE9B9921E38ACFEE934695787FA8794817A6ED',
- 'ALTER TABLE ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" ADD CONSTRAINT "FK_00AE9B9921E38ACFEE934695787FA8794817A6ED" FOREIGN KEY ("aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C") REFERENCES ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ADD CONSTRAINT "FK_00AE9B9921E38ACFEE934695787FA8794817A6ED" FOREIGN KEY ("aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C") REFERENCES ties_data."341622dca4e0350289717b52df5883edc3fa0280" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6',
+       'cd39d44beed963d50df42cd301e63d288f911c97',
  'FK_68EED3C83D2C93559F7A61E7D05B4363CDF1DB8F',
- 'ALTER TABLE ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" ADD CONSTRAINT "FK_68EED3C83D2C93559F7A61E7D05B4363CDF1DB8F" FOREIGN KEY ("bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E") REFERENCES ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ADD CONSTRAINT "FK_68EED3C83D2C93559F7A61E7D05B4363CDF1DB8F" FOREIGN KEY ("bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E") REFERENCES ties_data."341622dca4e0350289717b52df5883edc3fa0280" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'C35AE10CFF62DEDC5E3FC3C40E47373B10800818',
+       'c6f3a3396e9165e886da928c5fe1382fb20dc850',
  'PK_F03D1DD176CD75707BD6217EF652705007C0F272',
- 'ALTER TABLE ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" ADD CONSTRAINT "PK_F03D1DD176CD75707BD6217EF652705007C0F272" PRIMARY KEY ("id");'
+ 'ALTER TABLE ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ADD CONSTRAINT "PK_F03D1DD176CD75707BD6217EF652705007C0F272" PRIMARY KEY ("id");'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'C35AE10CFF62DEDC5E3FC3C40E47373B10800818',
+       'c6f3a3396e9165e886da928c5fe1382fb20dc850',
  'FK_E19DA712FB443E0212578638DF62281CFD6BFA7A',
- 'ALTER TABLE ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" ADD CONSTRAINT "FK_E19DA712FB443E0212578638DF62281CFD6BFA7A" FOREIGN KEY ("aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C") REFERENCES ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ADD CONSTRAINT "FK_E19DA712FB443E0212578638DF62281CFD6BFA7A" FOREIGN KEY ("aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C") REFERENCES ties_data."341622dca4e0350289717b52df5883edc3fa0280" (id) ON DELETE CASCADE;'
 );
 
 SELECT ties_data.create_constraint_if_not_exists(
-       'C35AE10CFF62DEDC5E3FC3C40E47373B10800818',
+       'c6f3a3396e9165e886da928c5fe1382fb20dc850',
  'FK_7772B14325D2340707AF687BF0F70F32914F935D',
- 'ALTER TABLE ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" ADD CONSTRAINT "FK_7772B14325D2340707AF687BF0F70F32914F935D" FOREIGN KEY ("bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E") REFERENCES ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" (id) ON DELETE CASCADE;'
+ 'ALTER TABLE ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ADD CONSTRAINT "FK_7772B14325D2340707AF687BF0F70F32914F935D" FOREIGN KEY ("bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E") REFERENCES ties_data."341622dca4e0350289717b52df5883edc3fa0280" (id) ON DELETE CASCADE;'
 );
diff --git a/teiv/src/test/resources/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql b/teiv/src/test/resources/pgsqlschema/01_init-oran-smo-teiv-model-v1.sql
new file mode 100644 (file)
index 0000000..0bb48d2
--- /dev/null
@@ -0,0 +1,430 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+DROP SCHEMA IF EXISTS ties_model cascade;
+CREATE SCHEMA IF NOT EXISTS ties_model;
+
+CREATE TABLE IF NOT EXISTS ties_model.execution_status (
+    "schema" VARCHAR(127) PRIMARY KEY,
+    "status" VARCHAR(127)
+);
+
+CREATE TABLE IF NOT EXISTS ties_model.hash_info (
+    "name"        VARCHAR(511) PRIMARY KEY,
+    "hashedValue" VARCHAR(511) NOT NULL,
+    "type"        VARCHAR(511)
+);
+
+CREATE TABLE IF NOT EXISTS ties_model.module_reference (
+    "name"            VARCHAR(511) PRIMARY KEY,
+    "namespace"       VARCHAR(511),
+    "domain"          VARCHAR(511),
+    "includedModules" jsonb DEFAULT '[]'::jsonb,
+    "revision"        VARCHAR(511) NOT NULL,
+    "content"         TEXT NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS ties_model.entity_info (
+    "storedAt"            VARCHAR(511) PRIMARY KEY,
+    "name"                VARCHAR(511) NOT NULL,
+    "moduleReferenceName" VARCHAR(511) NOT NULL,
+    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS ties_model.relationship_info (
+    "name"                     VARCHAR(511) NOT NULL,
+    "aSideAssociationName"     TEXT NOT NULL,
+    "aSideMOType"              TEXT NOT NULL,
+    "aSideModule"              TEXT NOT NULL,
+    "aSideMinCardinality"      BIGINT NOT NULL,
+    "aSideMaxCardinality"      BIGINT NOT NULL,
+    "bSideAssociationName"     TEXT NOT NULL,
+    "bSideMOType"              TEXT NOT NULL,
+    "bSideModule"              TEXT NOT NULL,
+    "bSideMinCardinality"      BIGINT NOT NULL,
+    "bSideMaxCardinality"      BIGINT NOT NULL,
+    "associationKind"          TEXT NOT NULL,
+    "relationshipDataLocation" TEXT NOT NULL,
+    "connectSameEntity"        BOOLEAN NOT NULL,
+    "storedAt"                 VARCHAR(511) NOT NULL,
+    "moduleReferenceName"      TEXT NOT NULL,
+    PRIMARY KEY ("name", "moduleReferenceName"),
+    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
+);
+
+-- Update model schema exec status
+INSERT INTO ties_model.execution_status("schema", "status") VALUES ('ties_model', 'success');
+
+COPY ties_model.hash_info("name", "hashedValue", "type") FROM stdin;
+CD_classifiers CD_classifiers  COLUMN
+CD_decorators  CD_decorators   COLUMN
+CD_sourceIds   CD_sourceIds    COLUMN
+FK_o-ran-smo-teiv-equipment_AntennaModule_REL_FK_grouped-by-sector     FK_078764B2F3D613D44CC6E3586F564C83164D2481     CONSTRAINT
+FK_o-ran-smo-teiv-equipment_AntennaModule_REL_FK_installed-at-site     FK_E3BAEF04443354C0FC1837CF7964E05BEF9FD6CC     CONSTRAINT
+FK_o-ran-smo-teiv-ran_ENodeBFunction_REL_FK_managed-by-managedElement  FK_6C99B14BF3C9BC6DE2D69AD55DF323ADCB174167     CONSTRAINT
+FK_o-ran-smo-teiv-ran_EUtranCell_REL_FK_grouped-by-sector      FK_o-ran-smo-teiv-ran_EUtranCell_REL_FK_grouped-by-sector       CONSTRAINT
+FK_o-ran-smo-teiv-ran_EUtranCell_REL_FK_provided-by-enodebFunction     FK_2D1FA89480BF856AB865D58FAFB6AC0B476015EB     CONSTRAINT
+FK_o-ran-smo-teiv-ran_GNBCUCPFunction_REL_FK_managed-by-managedElement FK_F1FB8F88851067901B66D53EE1420D2ECCEC98A3     CONSTRAINT
+FK_o-ran-smo-teiv-ran_GNBCUUPFunction_REL_FK_managed-by-managedElement FK_34D6E2537E8EE1D395CAF5BF9B2182A4696A1EAA     CONSTRAINT
+FK_o-ran-smo-teiv-ran_GNBDUFunction_REL_FK_managed-by-managedElement   FK_F67FAF9D3E82B97104E2392DA0AC8A86DF2407CC     CONSTRAINT
+FK_o-ran-smo-teiv-ran_LTESectorCarrier_REL_FK_provided-by-enodebFunction       FK_D0868FBC0BBE2754F4B765C4898C1A1700E2BEFD     CONSTRAINT
+FK_o-ran-smo-teiv-ran_LTESectorCarrier_REL_FK_used-antennaCapability   FK_3D8DF3FBD9C042A888CEB382688C1E8F39D85AFE     CONSTRAINT
+FK_o-ran-smo-teiv-ran_LTESectorCarrier_REL_FK_used-by-euTranCell       FK_96E6D4983CFFDF30FCA20423B5913DEE486E42D0     CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRCellCU_REL_FK_provided-by-gnbcucpFunction      FK_F2CDD1E84C7F07BF8065F99A5F3488E91E3BB7B2     CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_grouped-by-sector        FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_grouped-by-sector CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_provided-by-gnbduFunction        FK_o-ran-smo-teiv-ran_NRCellDU_REL_FK_provided-by-gnbduFunction CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_provided-by-gnbduFunction FK_F7978366174C82E41F0A6ABF29005FF01603858F     CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_used-antennaCapability    FK_65D538D54EB33081C808540235FEB28823428E64     CONSTRAINT
+FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_used-by-nrCellDu  FK_o-ran-smo-teiv-ran_NRSectorCarrier_REL_FK_used-by-nrCellDu   CONSTRAINT
+FK_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_aSide_AntennaModule FK_D80D1E6B26DF620B4DE659C600A3B7F709A41960     CONSTRAINT
+FK_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_bSide_AntennaCapability     FK_7148BEED02C0617DE1DEEB6639F34A9FA9251B06     CONSTRAINT
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_CD_classifiers        IDX_1C0CAFD80FDD6444044E3F76C7C0A7BDC35F9BC8    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_CD_sourceIds  IDX_905011128A2C218B5352C19ED1FE9851F43EB911    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE    IDX_17E417F7EF56809674BE1D5F5154DCCE01E00A96    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE        IDX_83B6347C0C0A005D5E3D856D973D3322DFEDEA35    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE      IDX_F497DEC01DA066CB09DA2AA7EDE3F4410078491B    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE  IDX_5ABDB19E55A6BDEF33855F14CB1B3B8CF457912C    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_AntennaModule_antennaBeamWidth      IDX_21B0F1FE632B6CB185C49BA6F00224068F443215    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_Site_CD_classifiers IDX_EEBF1BC3344E97988232825777AB13FAB6C4F3F0    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-equipment_Site_CD_sourceIds   IDX_102A50584376DE25B6BBD7157594C607A5C957F2    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-oam_ManagedElement_CD_classifiers     IDX_98AC4232BC02323E03416954215889CEE874A1E9    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-oam_ManagedElement_CD_sourceIds       IDX_DDD73D6F4004BF3A96AA118281EE3E565A922B47    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_AntennaCapability_CD_classifiers  IDX_E7FFE8F4A166AA9A382A0659762FFEC313A9EB5C    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_AntennaCapability_CD_sourceIds    IDX_CC3E208A4EE51D3B505416A599F36F3C99F466C8    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_AntennaCapability_eUtranFqBands   IDX_5FB80647AE3E5C0443A792618D65B9090EE2A3FC    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_AntennaCapability_geranFqBands    IDX_A94722FF7B95D8974B494793908B57B4E1A9743B    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_AntennaCapability_nRFqBands       IDX_441B5C05448D63552C6414BD59C13641D8A4408D    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_ENodeBFunction_CD_classifiers     IDX_B598B74193845587BA03553CEDBA058D33956847    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_ENodeBFunction_CD_sourceIds       IDX_3F7D14B4CF2CA74F28BA1600606E82C6E8C447C0    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_ENodeBFunction_REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION   IDX_61CDCD3F69CF67EE740358D2C76FA796CFDA19BF    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_ENodeBFunction_REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION     IDX_252AF4814C67384A7B05EA116316E83AFF9EB6AE    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_CD_classifiers IDX_C9C19F8F83F50C130F2EB6502ABB7B2833F1F783    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_CD_sourceIds   IDX_84E36DC53519D3E334C60B5B02C1AB27130CFA24    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL  IDX_4C77E3A51BFAB2FCD30425E4EB21CC7636438299    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL    IDX_8A15E61498725DA9D8C78FC4B99053C06E88DCEC    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL    IDX_976F6A0F8991F64592B6F9E716EFEECBD5400FDA    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_EUtranCell_REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL      IDX_173887418DD4FD6FD592F6404EA784150B1822C0    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUCPFunction_CD_classifiers    IDX_588840BAE32C7FF8CF0553F631DAAF8BB6E8E7C1    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUCPFunction_CD_sourceIds      IDX_BE4B476041D559760931630000D3F4A6DFF42707    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUCPFunction_REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION IDX_1324070754C1EBF8EA78EF40743AFC1713733BA8    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUCPFunction_REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION   IDX_E01081465B87F46E1CC7A22FE406C7B41C817E8C    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUUPFunction_CD_classifiers    IDX_4C2B68358221A7FF0E68012DEDD3CBA2C4ED669F    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUUPFunction_CD_sourceIds      IDX_C6D2419F8DC299FBC98342AA00BE92308C7566A7    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUUPFunction_REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION IDX_EB07ADD66F6CF51B9330403DE4500D05CA067647    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBCUUPFunction_REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION   IDX_883506CAA3E742D82EEFCEE8C8F29927983B73B1    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBDUFunction_CD_classifiers      IDX_601A4514FFACA8985471531013AFC8F760361F09    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBDUFunction_CD_sourceIds        IDX_2BEF269CED354C2454AC2B2EABB134AC267A0C62    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBDUFunction_REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION     IDX_04C614FDE6A4AE2AA106A1233D1DF95803FC122D    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_GNBDUFunction_REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION       IDX_3065F7FB78C5AA9FF17972F825F89AED127A6324    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_CD_classifiers   IDX_E754EB8AD825DB3111B07B9E5DA3B30C38DB406B    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_CD_sourceIds     IDX_6EC539C61EA7078DBA264C9877B87FC263605D42    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER      IDX_846B7740E8AA756B8C1409CD909D2DF73A47ED4C    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER      IDX_B291D7EFCAD3BF06A2C11F8C0429ABABEEF8308B    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY       IDX_3D3EFECFB917DAC074F56334224B19F8FD6BF8A5    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER        IDX_1EBC7271CEA658156DE25286404CBC4593340F8E    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER        IDX_F2D46817C2D618D8C33945F282299BF9EB49465E    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY IDX_7D01A5D21C990ACCBE65035C062C7D881A05F1EE    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellCU_CD_classifiers   IDX_E5930226819982DC0CFC1FA64FB3600647222435    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellCU_CD_sourceIds     IDX_0C443A16285D233F16966C2F0314CDC9D0F6D0B8    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellCU_REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU     IDX_04BE1EB39848069422B97C28EE3C8ED18BCC6D33    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellCU_REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU       IDX_36A671754CD510FFBDC2713FD142303DCA75DD65    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_CD_classifiers   IDX_C437D39632DC79BAB6AC4F0880826A05425F9C32    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_CD_sourceIds     IDX_FFD60DD99D80C276F402E66546F5DACB2D81EE26    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU       IDX_2F4C43ED084968FDAF9943DB96741885C145FE1D    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU        IDX_7CB4A7724F68D1CB2D12E8DE779BA9103F7DBE0A    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU IDX_1F6708B1E34FC908473DD7A7E5641E650B359BEF    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRCellDU_REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU  IDX_6325926B4D2FDD1FBBB34250DABEA5E7229FF9F5    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_CD_classifiers    IDX_050A80BEEF775E4D3CE216F282F23DB99DA2D798    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_CD_sourceIds      IDX_8E34EC0B1DE7DDCE3B32ADD85B11E15F95C5644E    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER IDX_273D43FDDD1C4643ECF8BBE51B6B369C657F0861    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER  IDX_ED50A5139F1449DBAD8DA10D45F5A5BF819EACBA    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY IDX_B975D24291849007D4AA6686C5D3983885D5C884    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER   IDX_CD293AD1111E344D150340A13BD299924D29A9DA    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER    IDX_7BFD17A71AB1B7765FE6431DA4E66C2EDE88AC3B    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY   IDX_1F27C515A028616FAC422A02ABBEC402D5DBB2E5    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_Sector_CD_classifiers     IDX_19C19556F9714850389595E0A16218FA229205FE    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-ran_Sector_CD_sourceIds       IDX_E234B43A7CD7843672F08F2197AB46A2A50BECB0    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_CD_classifiers       IDX_DD0D676834B12CA2F7E8219310998376A08D7F5F    INDEX
+IDX_GIN_TRGM_OPS_ON_LIST_AS_JSONB_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_CD_sourceIds IDX_E896A9EB22A3F9F96CE75A271475316A98B629C8    INDEX
+IDX_GIN_o-ran-smo-teiv-equipment_AntennaModule_CD_decorators   IDX_GIN_o-ran-smo-teiv-equipment_AntennaModule_CD_decorators    INDEX
+IDX_GIN_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE       IDX_2321BFA482AD2700F41E2BA359F6EB00F47601B9    INDEX
+IDX_GIN_o-ran-smo-teiv-equipment_AntennaModule_REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE   IDX_6C6FBD69F47F41970595A8775DC99CA0F5E894A1    INDEX
+IDX_GIN_o-ran-smo-teiv-equipment_Site_CD_decorators    IDX_GIN_o-ran-smo-teiv-equipment_Site_CD_decorators     INDEX
+IDX_GIN_o-ran-smo-teiv-oam_ManagedElement_CD_decorators        IDX_GIN_o-ran-smo-teiv-oam_ManagedElement_CD_decorators INDEX
+IDX_GIN_o-ran-smo-teiv-ran_AntennaCapability_CD_decorators     IDX_GIN_o-ran-smo-teiv-ran_AntennaCapability_CD_decorators      INDEX
+IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_CD_decorators        IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_CD_decorators INDEX
+IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION      IDX_35C17C8A9BA3EF3AEADA72C21F8090C38F575BAF    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_eNodeBPlmnId IDX_GIN_o-ran-smo-teiv-ran_ENodeBFunction_eNodeBPlmnId  INDEX
+IDX_GIN_o-ran-smo-teiv-ran_EUtranCell_CD_decorators    IDX_GIN_o-ran-smo-teiv-ran_EUtranCell_CD_decorators     INDEX
+IDX_GIN_o-ran-smo-teiv-ran_EUtranCell_REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL     IDX_FC7D79187227E0BFA69149048CC10E39AE540B8A    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_EUtranCell_REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL       IDX_E4EF3C904939ED4C0996EAB7CDFE1895CDF34BFB    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_CD_decorators       IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_CD_decorators        INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION    IDX_13E734DE57346378DA4F21FC4EA030290A7E532F    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_pLMNId      IDX_GIN_o-ran-smo-teiv-ran_GNBCUCPFunction_pLMNId       INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBCUUPFunction_CD_decorators       IDX_GIN_o-ran-smo-teiv-ran_GNBCUUPFunction_CD_decorators        INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBCUUPFunction_REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION    IDX_C3141DD7D2695EF74B13981AB378A58390D203D6    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_CD_decorators IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_CD_decorators  INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION        IDX_298FCD184347DEC995B06FED2B1AE61F12BF766A    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_dUpLMNId      IDX_GIN_o-ran-smo-teiv-ran_GNBDUFunction_dUpLMNId       INDEX
+IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_CD_decorators      IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_CD_decorators       INDEX
+IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER IDX_44075E1D464599B61924196C20F2B88332520CD8    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER IDX_EAE482189F45D63CD1A88B0DD5F76EEE163D9E53    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_LTESectorCarrier_REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY  IDX_4EE2AA643311DFCC13B6ED832EBE2FAB4CFDF494    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_CD_decorators      IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_CD_decorators       INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU        IDX_229957181BBC9D7B4535807BB397E8AA1378ED85    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_plmnId     IDX_GIN_o-ran-smo-teiv-ran_NRCellCU_plmnId      INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellDU_CD_decorators      IDX_GIN_o-ran-smo-teiv-ran_NRCellDU_CD_decorators       INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellDU_REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU  IDX_0E63D6B76B229961CD45D998C63175B569DDECD1    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRCellDU_REL_CD_decorators_SECTOR_GROUPS_NRCELLDU   IDX_0A03C47C13AD3B5C84D3D8081493D670E9CBDCD1    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_CD_decorators       IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_CD_decorators        INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER    IDX_EDE8B88F488F9380DB49CB2C141318FB33C2CCEC    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER     IDX_2ADB5C6DCAEE8811FB1CA8FD9EB53381F35FCB70    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_NRSectorCarrier_REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY    IDX_902B73F741160B9D4FBF62406D3D9ABBECAD8BE7    INDEX
+IDX_GIN_o-ran-smo-teiv-ran_Sector_CD_decorators        IDX_GIN_o-ran-smo-teiv-ran_Sector_CD_decorators INDEX
+IDX_GIN_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_CD_decorators  IDX_7BF09D0227840279556AD27ACECB068705893D28    INDEX
+PK_o-ran-smo-teiv-equipment_AntennaModule_id   PK_o-ran-smo-teiv-equipment_AntennaModule_id    CONSTRAINT
+PK_o-ran-smo-teiv-equipment_Site_id    PK_o-ran-smo-teiv-equipment_Site_id     CONSTRAINT
+PK_o-ran-smo-teiv-oam_ManagedElement_id        PK_o-ran-smo-teiv-oam_ManagedElement_id CONSTRAINT
+PK_o-ran-smo-teiv-ran_AntennaCapability_id     PK_o-ran-smo-teiv-ran_AntennaCapability_id      CONSTRAINT
+PK_o-ran-smo-teiv-ran_ENodeBFunction_id        PK_o-ran-smo-teiv-ran_ENodeBFunction_id CONSTRAINT
+PK_o-ran-smo-teiv-ran_EUtranCell_id    PK_o-ran-smo-teiv-ran_EUtranCell_id     CONSTRAINT
+PK_o-ran-smo-teiv-ran_GNBCUCPFunction_id       PK_o-ran-smo-teiv-ran_GNBCUCPFunction_id        CONSTRAINT
+PK_o-ran-smo-teiv-ran_GNBCUUPFunction_id       PK_o-ran-smo-teiv-ran_GNBCUUPFunction_id        CONSTRAINT
+PK_o-ran-smo-teiv-ran_GNBDUFunction_id PK_o-ran-smo-teiv-ran_GNBDUFunction_id  CONSTRAINT
+PK_o-ran-smo-teiv-ran_LTESectorCarrier_id      PK_o-ran-smo-teiv-ran_LTESectorCarrier_id       CONSTRAINT
+PK_o-ran-smo-teiv-ran_NRCellCU_id      PK_o-ran-smo-teiv-ran_NRCellCU_id       CONSTRAINT
+PK_o-ran-smo-teiv-ran_NRCellDU_id      PK_o-ran-smo-teiv-ran_NRCellDU_id       CONSTRAINT
+PK_o-ran-smo-teiv-ran_NRSectorCarrier_id       PK_o-ran-smo-teiv-ran_NRSectorCarrier_id        CONSTRAINT
+PK_o-ran-smo-teiv-ran_Sector_id        PK_o-ran-smo-teiv-ran_Sector_id CONSTRAINT
+PK_o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY_id  PK_63E61CB6802F21FE7A04A80A095F6AF8ABF067CE     CONSTRAINT
+REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE     REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE      COLUMN
+REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL  REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL   COLUMN
+REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER    REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER     COLUMN
+REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER    REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER     COLUMN
+REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU   REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU    COLUMN
+REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU     REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU      COLUMN
+REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER      REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER       COLUMN
+REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY     REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY      COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION       REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION        COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION      REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION       COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION      REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION       COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION        REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION COLUMN
+REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER       REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER        COLUMN
+REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY      REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY       COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE  COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL    REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL     COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU      REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU       COLUMN
+REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE      REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE       COLUMN
+REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL   REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL    COLUMN
+REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER     REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER      COLUMN
+REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER     REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER      COLUMN
+REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU    REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU     COLUMN
+REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU      REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU       COLUMN
+REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER       REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER        COLUMN
+REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY      REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY       COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION        REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION       REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION        COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION       REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION        COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION  COLUMN
+REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER        REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER COLUMN
+REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY       REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY        COLUMN
+REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE  REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE   COLUMN
+REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL     REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL      COLUMN
+REL_CD_decorators_SECTOR_GROUPS_NRCELLDU       REL_CD_decorators_SECTOR_GROUPS_NRCELLDU        COLUMN
+REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE       REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE        COLUMN
+REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL    REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL     COLUMN
+REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER      REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER       COLUMN
+REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER      REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER       COLUMN
+REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU     REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU      COLUMN
+REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU       REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU        COLUMN
+REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER        REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER COLUMN
+REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY       REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY        COLUMN
+REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION  COLUMN
+REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION        REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION COLUMN
+REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION        REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION COLUMN
+REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION  REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION   COLUMN
+REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER  COLUMN
+REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY        REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY COLUMN
+REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE   REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE    COLUMN
+REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL      REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL       COLUMN
+REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU        REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU COLUMN
+REL_FK_grouped-by-sector       REL_FK_grouped-by-sector        COLUMN
+REL_FK_installed-at-site       REL_FK_installed-at-site        COLUMN
+REL_FK_managed-by-managedElement       REL_FK_managed-by-managedElement        COLUMN
+REL_FK_provided-by-enodebFunction      REL_FK_provided-by-enodebFunction       COLUMN
+REL_FK_provided-by-gnbcucpFunction     REL_FK_provided-by-gnbcucpFunction      COLUMN
+REL_FK_provided-by-gnbduFunction       REL_FK_provided-by-gnbduFunction        COLUMN
+REL_FK_used-antennaCapability  REL_FK_used-antennaCapability   COLUMN
+REL_FK_used-by-euTranCell      REL_FK_used-by-euTranCell       COLUMN
+REL_FK_used-by-nrCellDu        REL_FK_used-by-nrCellDu COLUMN
+REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE  COLUMN
+REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL      REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL       COLUMN
+REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER        REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER COLUMN
+REL_ID_EUTRANCELL_USES_LTESECTORCARRIER        REL_ID_EUTRANCELL_USES_LTESECTORCARRIER COLUMN
+REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU       REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU        COLUMN
+REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU  COLUMN
+REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER  REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER   COLUMN
+REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY  COLUMN
+REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION   REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION    COLUMN
+REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION  REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION   COLUMN
+REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION  REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION   COLUMN
+REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION    REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION     COLUMN
+REL_ID_NRCELLDU_USES_NRSECTORCARRIER   REL_ID_NRCELLDU_USES_NRSECTORCARRIER    COLUMN
+REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY  REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY   COLUMN
+REL_ID_SECTOR_GROUPS_ANTENNAMODULE     REL_ID_SECTOR_GROUPS_ANTENNAMODULE      COLUMN
+REL_ID_SECTOR_GROUPS_EUTRANCELL        REL_ID_SECTOR_GROUPS_EUTRANCELL COLUMN
+REL_ID_SECTOR_GROUPS_NRCELLDU  REL_ID_SECTOR_GROUPS_NRCELLDU   COLUMN
+UNIQUE_o-ran-smo-teiv-equipment_AntennaModule_REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE   UNIQUE_9DF414C2F0CD7FA8BFCB3E9BF851784AC4BC49B1 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-equipment_AntennaModule_REL_ID_SECTOR_GROUPS_ANTENNAMODULE       UNIQUE_78B1D3DCD903AFFB1965D440D87B2D194CA028A0 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_ENodeBFunction_REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION  UNIQUE_A30444B7D036FA579730F0D2853E52FD08DEDCF0 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_EUtranCell_REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL UNIQUE_CA88C7E60C1A332FA7561FC965ED41DD4125CDED CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_EUtranCell_REL_ID_SECTOR_GROUPS_EUTRANCELL   UNIQUE_0513FE4A675A02C31E5EDD6BCB3728911FBDA2FA CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_GNBCUCPFunction_REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION        UNIQUE_50E9E4A87D93AC833B1D1AC05E3B58805909E20E CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_GNBCUUPFunction_REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION        UNIQUE_0CA05800AC7D277BDCB5CF0097DC35978E9311F4 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_GNBDUFunction_REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION    UNIQUE_5BD09ED226520A0BE27904AEAF0557416808E7E2 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_LTESectorCarrier_REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER     UNIQUE_FD943EE596337B11E0C640E1176CADF9CD69E19A CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_LTESectorCarrier_REL_ID_EUTRANCELL_USES_LTESECTORCARRIER     UNIQUE_0A76398FBBC8E01A2D3BA602AB47835794E997E5 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_LTESectorCarrier_REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY      UNIQUE_EA18F1D278EAFE834B8A80BCF8A7D8355CD013DF CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRCellCU_REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU    UNIQUE_EA2A6F5BA36ABB0DA357542E05AA2D07415E127A CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRCellDU_REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU      UNIQUE_C3D8E5331EC71D46D4B8CED29FE5F6CEB1D8E67A CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRCellDU_REL_ID_SECTOR_GROUPS_NRCELLDU       UNIQUE_AC1C114ABED77D6DEC3F3AE3F9EBE8231924AEF4 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRSectorCarrier_REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER        UNIQUE_0AC16A840F6ACDC50136E71EC6D4F3D4E04B8198 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRSectorCarrier_REL_ID_NRCELLDU_USES_NRSECTORCARRIER UNIQUE_1AB577E5AC207ED4C99A9A96BA1C9C35544AFD25 CONSTRAINT
+UNIQUE_o-ran-smo-teiv-ran_NRSectorCarrier_REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY        UNIQUE_A799EC9DA6624651081E1DA21B5F0C2D38F6A192 CONSTRAINT
+aSide_AntennaModule    aSide_AntennaModule     COLUMN
+antennaBeamWidth       antennaBeamWidth        COLUMN
+antennaModelNumber     antennaModelNumber      COLUMN
+arfcnDL        arfcnDL COLUMN
+arfcnUL        arfcnUL COLUMN
+azimuth        azimuth COLUMN
+bSChannelBwDL  bSChannelBwDL   COLUMN
+bSide_AntennaCapability        bSide_AntennaCapability COLUMN
+cellId cellId  COLUMN
+cellLocalId    cellLocalId     COLUMN
+channelBandwidth       channelBandwidth        COLUMN
+dUpLMNId       dUpLMNId        COLUMN
+dlChannelBandwidth     dlChannelBandwidth      COLUMN
+duplexType     duplexType      COLUMN
+eNBId  eNBId   COLUMN
+eNodeBPlmnId   eNodeBPlmnId    COLUMN
+eUtranFqBands  eUtranFqBands   COLUMN
+earfcn earfcn  COLUMN
+earfcndl       earfcndl        COLUMN
+earfcnul       earfcnul        COLUMN
+electricalAntennaTilt  electricalAntennaTilt   COLUMN
+frequencyDL    frequencyDL     COLUMN
+frequencyUL    frequencyUL     COLUMN
+gNBCUName      gNBCUName       COLUMN
+gNBDUId        gNBDUId COLUMN
+gNBId  gNBId   COLUMN
+gNBIdLength    gNBIdLength     COLUMN
+geo-location   geo-location    COLUMN
+geranFqBands   geranFqBands    COLUMN
+id     id      COLUMN
+mechanicalAntennaBearing       mechanicalAntennaBearing        COLUMN
+mechanicalAntennaTilt  mechanicalAntennaTilt   COLUMN
+nCI    nCI     COLUMN
+nRFqBands      nRFqBands       COLUMN
+nRPCI  nRPCI   COLUMN
+nRTAC  nRTAC   COLUMN
+name   name    COLUMN
+o-ran-smo-teiv-equipment_AntennaModule o-ran-smo-teiv-equipment_AntennaModule  TABLE
+o-ran-smo-teiv-equipment_Site  o-ran-smo-teiv-equipment_Site   TABLE
+o-ran-smo-teiv-oam_ManagedElement      o-ran-smo-teiv-oam_ManagedElement       TABLE
+o-ran-smo-teiv-ran_AntennaCapability   o-ran-smo-teiv-ran_AntennaCapability    TABLE
+o-ran-smo-teiv-ran_ENodeBFunction      o-ran-smo-teiv-ran_ENodeBFunction       TABLE
+o-ran-smo-teiv-ran_EUtranCell  o-ran-smo-teiv-ran_EUtranCell   TABLE
+o-ran-smo-teiv-ran_GNBCUCPFunction     o-ran-smo-teiv-ran_GNBCUCPFunction      TABLE
+o-ran-smo-teiv-ran_GNBCUUPFunction     o-ran-smo-teiv-ran_GNBCUUPFunction      TABLE
+o-ran-smo-teiv-ran_GNBDUFunction       o-ran-smo-teiv-ran_GNBDUFunction        TABLE
+o-ran-smo-teiv-ran_LTESectorCarrier    o-ran-smo-teiv-ran_LTESectorCarrier     TABLE
+o-ran-smo-teiv-ran_NRCellCU    o-ran-smo-teiv-ran_NRCellCU     TABLE
+o-ran-smo-teiv-ran_NRCellDU    o-ran-smo-teiv-ran_NRCellDU     TABLE
+o-ran-smo-teiv-ran_NRSectorCarrier     o-ran-smo-teiv-ran_NRSectorCarrier      TABLE
+o-ran-smo-teiv-ran_Sector      o-ran-smo-teiv-ran_Sector       TABLE
+o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY        CFC235E0404703D1E4454647DF8AAE2C193DB402        TABLE
+pLMNId pLMNId  COLUMN
+plmnId plmnId  COLUMN
+positionWithinSector   positionWithinSector    COLUMN
+sectorCarrierType      sectorCarrierType       COLUMN
+sectorId       sectorId        COLUMN
+tac    tac     COLUMN
+totalTilt      totalTilt       COLUMN
+\.
+
+COPY ties_model.module_reference("name", "namespace", "domain", "includedModules", "revision", "content") FROM stdin;
+_3gpp-common-yang-extensions   urn:3gpp:sa5:_3gpp-common-yang-extensions       \N      []      2019-06-23      bW9kdWxlIF8zZ3BwLWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgewogIHlhbmctdmVyc2lvbiAxLjE7CiAgbmFtZXNwYWNlIHVybjozZ3BwOnNhNTpfM2dwcC1jb21tb24teWFuZy1leHRlbnNpb25zIDsKICBwcmVmaXggeWV4dDNncHAgOwoKICBvcmdhbml6YXRpb24gIjNHUFAgU0E1IjsKICBkZXNjcmlwdGlvbiAiVGhlIG1vZHVsZSBkZWZpbmVzIFlBTkcgZXh0ZW5zaW9ucyBuZWVkZWQKICAgIDNHUFAgWUFORyBtb2RlbGluZy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTkgM0dQUC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBFeHRlbnNpb25zIE1VU1QgYmUgZGVmaW5lZCB3aXRoIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlIGluIHRoZQogICAgZGVzY3JpcHRpb24gc3RhdGVtZW50OgogICAgICAgIC0gV2hhdCBpcyB0aGlzIHN0YXRlbWVudC4KICAgICAgICAtIE5ld2xpbmUsCiAgICAgICAgLSBUaGlzIHN0YXRlbWVudCBjYW4gYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlIHh4eCBzdGF0ZW1lbnRzIHdpdGgKICAgICAgICBjYXJkaW5hbGl0eSB4Li55LgogICAgICAgIC0gVGhpcyBzdGF0ZW1lbnQgY2FuIGhhdmUgdGhlIGZvbGxvd2luZyBzdWJzdGF0ZW1lbnRzIHdpdGgKICAgICAgICBjYXJkaW5hbGl0eSB4Li55LgogICAgICAgIC0gTmV3bGluZQogICAgICAgIC0gSXMgY2hhbmdpbmcgdGhpcyBzdGF0ZW1lbnQgYW4gZWRpdG9yaWFsLCBCQyhiYWNrd2FyZHMgY29tcGF0aWJsZSkKICAgICAgICBvciBOQkMobm9uLUJDKSBjaGFuZ2U/CiAgICAgICAgLSBOZXdsaW5lLgogICAgICAgIC0gVGhlIGFyZ3VtZW50IGl0cyBtZWFuaW5nIGFuZCB0eXBlLiBQcmVmZXJhYmx5IHVzZSBZQU5HIHR5cGVzIGFuZAogICAgICAgICAgY29uc3RyYWludHMgdG8gZGVmaW5lIHRoZSBhcmd1bWVudCdzIHR5cGUuCgogICAgQW55IGV4dGVuc2lvbiBzdGF0ZW1lbnQgY2FuIGJlIGFkZGVkIHdpdGggYQogICAgZGV2aWF0aW9uL2RldmlhdGUgYWRkIHN0YXRlbWVudC4gSW4gdGhpcyBjYXNlIHRoZSByZXN0cmljdGlvbiBhYm91dAogICAgdGhlIHBhcmVudCBzdGF0ZW1lbnQgb2YgdGhlIGV4dGVuc2lvbiBTSEFMTCBiZSBldmFsdWF0ZWQgYmFzZWQgb24gdGhlCiAgICB0YXJnZXQgb2YgdGhlIGRldmlhdGlvbiBzdGF0ZW1lbnQuCgogICAgU3VwcG9ydCBmb3IgdGhpcyBtb2R1bGUgZG9lcyBub3QgbWVhbiB0aGF0IGEgWUFORyBzZXJ2ZXIgaW1wbGVtZW50cwogICAgc3VwcG9ydCBmb3IgZWFjaCBvZiB0aGVzZSBleHRlbnNpb25zLgogICAgSW1wbGVtZW50ZXJzIG9mIGVhY2ggc3BlY2lmaWMgbW9kdWxlIHVzaW5nIGFuIGV4dGVuc2lvbnMgTVVTVCBjaGVjawogICAgaWYgdGhlIHNlcnZlciBpbXBsZW1lbnRzIHN1cHBvcnQgZm9yIHRoZSB1c2VkIGV4dGVuc2lvbi4KICAgIE5vdGU6IG1vZHVsZXMgdXNlIG1hbnkgZXh0ZW5zaW9ucyB3aGljaCBpbmRpdmlkdWFsCiAgICBpbXBsZW1lbnRhdGlvbnMgTUFZIG9yIE1BWSBOT1Qgc3VwcG9ydC4KICAgIElmIHN1cHBvcnQgZm9yIGFuIGV4dGVuc2lvbiBpcyBtaXNzaW5nIHRoZSBleHRlbnNpb24gc3RhdGVtZW50IG5lZWRzCiAgICBpbmRpdmlkdWFsIGhhbmRsaW5nIG9yIGl0IFNIT1VMRCBiZSByZW1vdmVkIGZyb20gdGhlIG1vZHVsZSB1c2luZwogICAgdGhlIGV4dGVuc2lvbiBlLmcuIHdpdGggYSBkZXZpYXRpb24uCiAgICAgICAgICAiOwoKICByZXZpc2lvbiAiMjAxOS0wNi0yMyIgewogICAgZGVzY3JpcHRpb24gIkluaXRpYWwgdmVyc2lvbiI7CiAgfQoKICBleHRlbnNpb24gaW5WYXJpYW50IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgICJJbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgZm9yIHRoZSBkYXRhIG5vZGUgY2FuIG9ubHkgYmUgc2V0IHdoZW4gaXRzCiAgICAgIHBhcmVudCBkYXRhIG5vZGUgaXMgYmVpbmcgY3JlYXRlZC4gVG8gY2hhbmdlIHRoZSB2YWx1ZSBhZnRlciB0aGF0LCB0aGUKICAgICAgcGFyZW50IGRhdGEgbm9kZSBtdXN0IGJlIGRlbGV0ZWQgYW5kIHJlY3JlYXRlZCB3aXRoIHRoZSBkYXRhIG5vZGUKICAgICAgaGF2aW5nIHRoZSBuZXcgdmFsdWUuCgogICAgICBJdCBpcyB1bm5lY2Vzc2FyeSB0byB1c2UgYW5kIE1VU1QgTk9UIGJlIHVzZWQgZm9yIGtleSBsZWFmcy4KCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgbGVhZiwgbGVhZi1saXN0LCBsaXN0CiAgICAgIHN0YXRlbWVudHMgdGhhdCBpcyBjb25maWc9dHJ1ZS4KICAgICAgWmVybyBvciBvbmUgaW5WYXJpYW50IHN0YXRlbWVudCBpcyBhbGxvd2VkIHBlciBwYXJlbnQgc3RhdGVtZW50LgogICAgICBOTyBzdWJzdGF0ZW1lbnRzIGFyZSBhbGxvd2VkLgoKICAgICAgQWRkaW5nIHRoaXMgc3RhdGVtZW50IGlzIGFuIE5CQyBjaGFuZ2UsIHJlbW92aW5nIGl0IGlzIEJDLiI7CiAgfQoKICBleHRlbnNpb24gaW5pdGlhbC12YWx1ZSB7CiAgICBkZXNjcmlwdGlvbiAiU3BlY2lmaWVzIGEgdmFsdWUgdGhhdCB0aGUgc3lzdGVtIHdpbGwgc2V0IGZvciBhIGxlYWYKICAgICAgbGVhZi1saXN0IGlmIGEgdmFsdWUgaXMgbm90IHNwZWNpZmllZCBmb3IgaXQgd2hlbiBpdHMgcGFyZW50IGxpc3QKICAgICAgb3IgY29udGFpbmVyIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSBoYXMgbm8gZWZmZWN0IGluIGFueSBvdGhlcgogICAgICBtb2RpZmljYXRpb24gZS5nLiBjaGFuZ2luZyBvciByZW1vdmluZyB0aGUgdmFsdWUuCgogICAgICBUaGUgZGVzY3JpcHRpb24gc3RhdGVtZW50IG9mIHRoZSBwYXJlbnQgc3RhdGVtZW50IFNIT1VMRCBjb250YWluCiAgICAgIHRoZSBsYWJlbCAnSW5pdGlhbC12YWx1ZTogJyBmb2xsb3dlZCBieSB0aGUgdGV4dCBmcm9tIHRoZSBhcmd1bWVudC4KCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgbGVhZiBvciBsZWFmLWxpc3QuCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBOT1QgYmUgcHJlc2VudCBpZiB0aGUgbGVhZiBvciB0aGUgbGVhZi1saXN0CiAgICAgIGhhcyBhIGRlZmF1bHQgc3RhdGVtZW50IG9yIHRoZSB0eXBlIHVzZWQgZm9yIHRoZSBkYXRhIG5vZGUKICAgICAgaGFzIGEgZGVmYXVsdCB2YWx1ZS4KICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIE5PVCBiZSB1c2VkIGZvciBjb25maWc9ZmFsc2UgZGF0YSBvciBpbiBhbgogICAgICBhY3Rpb24sIHJwYyBvciBub3RpZmljYXRpb24uCiAgICAgIFplcm8gb3Igb25lIGluaXRpYWwtdmFsdWUgc3RhdGVtZW50cyBhcmUgYWxsb3dlZCBmb3IgYSBsZWFmIHBhcmVudAogICAgICBzdGF0ZW1lbnQuIFplcm8gb3IgbW9yZSBpbml0aWFsLXZhbHVlIHN0YXRlbWVudHMgYXJlIGFsbG93ZWQgZm9yIGEKICAgICAgbGVhZi1saXN0IHBhcmVudCBzdGF0ZW1lbnQuIElmIHRoZSBsZWFmLWxpc3QgaXMgb3JkZXJlZC1ieSB1c2VyLCB0aGUKICAgICAgaW5pdGlhbCB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgb3JkZXIgdGhleSBhcHBlYXIgaW4gdGhlIFlBTkcgZGVmaW5pdGlvbi4KICAgICAgTk8gc3Vic3RhdGVtZW50cyBhcmUgYWxsb3dlZC4KCiAgICAgIEFsd2F5cyBjb25zaWRlciB1c2luZyBhIFlBTkctZGVmYXVsdCBzdGF0ZW1lbnQgaW5zdGVhZC4KCiAgICAgIE1vZGlmaWNhdGlvbiBvZiB0aGUgaW5pdGlhbC12YWx1ZSBpcyBhIG5vbi1iYWNrd2FyZHMtY29tcGF0aWJsZSBjaGFuZ2UuCgogICAgICBUaGUgYXJndW1lbnQgc3BlY2lmaWVzIGEgc2luZ2xlIGluaXRpYWwgdmFsdWUgZm9yIGEgbGVhZiBvciBsZWFmLWxpc3QuCiAgICAgIFRoZSB2YWx1ZSBNVVNUIGJlIHBhcnQgb2YgdGhlIHZhbHVlc3BhY2Ugb2YgdGhlIGxlYWYvbGVhZi1saXN0LgogICAgICBJdCBmb2xsb3dzIHRoZSBzYW1lIHJ1bGVzIGFzIHRoZSBhcmd1bWVudCBvZiB0aGUgZGVmYXVsdCBzdGF0ZW1lbnQuIjsKCiAgICBhcmd1bWVudCAiaW5pdGlhbC12YWx1ZSI7CiAgfQp9Cg==
+_3gpp-common-yang-types        urn:3gpp:sa5:_3gpp-common-yang-types    \N      []      2023-11-06      bW9kdWxlIF8zZ3BwLWNvbW1vbi15YW5nLXR5cGVzIHsKICB5YW5nLXZlcnNpb24gMS4xOwogIG5hbWVzcGFjZSAidXJuOjNncHA6c2E1Ol8zZ3BwLWNvbW1vbi15YW5nLXR5cGVzIjsKICBwcmVmaXggInR5cGVzM2dwcCI7CgogIGltcG9ydCBpZXRmLWluZXQtdHlwZXMgeyBwcmVmaXggaW5ldDsgfQogIGltcG9ydCBpZXRmLXlhbmctdHlwZXMgeyBwcmVmaXggeWFuZzsgfQogIGltcG9ydCBfM2dwcC1jb21tb24teWFuZy1leHRlbnNpb25zIHsgcHJlZml4IHlleHQzZ3BwOyB9CgogIG9yZ2FuaXphdGlvbiAiM0dQUCBTQTUiOwogIGNvbnRhY3QgImh0dHBzOi8vd3d3LjNncHAub3JnL0R5bmFSZXBvcnQvVFNHLVdHLS1TNS0tb2ZmaWNpYWxzLmh0bT9JdGVtaWQ9NDY0IjsKICBkZXNjcmlwdGlvbiAiVGhlIG1vZGVsIGRlZmluZXMgYSBZQU5HIG1hcHBpbmcgb2YgdGhlIHRvcCBsZXZlbAogICAgaW5mb3JtYXRpb24gY2xhc3NlcyB1c2VkIGZvciBtYW5hZ2VtZW50IG9mIDVHIG5ldHdvcmtzIGFuZAogICAgbmV0d29yayBzbGljaW5nLgogICAgQ29weXJpZ2h0IDIwMjMsIDNHUFAgT3JnYW5pemF0aW9uYWwgUGFydG5lcnMgKEFSSUIsIEFUSVMsIENDU0EsIEVUU0ksIFRTRFNJLAogICAgVFRBLCBUVEMpLiBBbGwgcmlnaHRzIHJlc2VydmVkLiI7CiAgcmVmZXJlbmNlICIzR1BQIFRTIDI4LjYyMyI7CgogIHJldmlzaW9uIDIwMjMtMTEtMDYgeyByZWZlcmVuY2UgQ1ItMDMwNTsgfQogIHJldmlzaW9uIDIwMjMtMDktMTggeyByZWZlcmVuY2UgQ1ItMDI3MSA7IH0KICByZXZpc2lvbiAyMDIzLTA4LTA5IHsgcmVmZXJlbmNlIENSLTAyNjY7IH0KICByZXZpc2lvbiAyMDIzLTA1LTEwIHsgcmVmZXJlbmNlIENSLTAyNTA7IH0KICByZXZpc2lvbiAyMDIzLTAyLTE0IHsgcmVmZXJlbmNlIENSLTAyMzQ7IH0KICByZXZpc2lvbiAyMDIyLTExLTA0IHsgcmVmZXJlbmNlICJDUi0wMTk0IjsgfQogIHJldmlzaW9uIDIwMjItMTAtMjQgeyByZWZlcmVuY2UgQ1ItMDE5NjsgIH0KICByZXZpc2lvbiAyMDIyLTA3LTI2IHsgcmVmZXJlbmNlICJDUi0wMTgwIiA7IH0KICByZXZpc2lvbiAyMDIyLTAyLTA5IHsgcmVmZXJlbmNlICJDUi0wMTQ0IjsgfQogIHJldmlzaW9uIDIwMjEtMTEtMDEgeyByZWZlcmVuY2UgIkNSLTAxNDEiOyB9CgogIHJldmlzaW9uIDIwMjEtMDktMzAgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIExvbmdpdHVkZSwgTGF0aXR1ZGUsIFRlbnRoT2ZEZWdyZWVzLCBPbk9mZi4iOwogICAgcmVmZXJlbmNlICJDUi0wMTM4IjsKICB9CgogIHJldmlzaW9uIDIwMjAtMTEtMDYgewogICAgZGVzY3JpcHRpb24gIlJlbW92ZWQgaW5jb3JyZWN0IFMtTlNTQUkgZGVmaW5pdGlvbnMuIjsKICAgIHJlZmVyZW5jZSAiQ1ItMDExOCI7CiAgfQoKICByZXZpc2lvbiAyMDIwLTAzLTEwIHsKICAgIGRlc2NyaXB0aW9uICJSZW1vdmVkIGZhdWx0eSB3aGVuIHN0YXRlbWVudHMuIjsKICAgIHJlZmVyZW5jZSAiU1AtMjAwMjI5IjsKICB9CgogIHJldmlzaW9uIDIwMTktMTAtMjUgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIE1hbmFnZWRORlByb2ZpbGUuIjsKICAgIHJlZmVyZW5jZSAiUzUtMTk0NDU3IjsKICB9CgogIHJldmlzaW9uIDIwMTktMTAtMTYgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIFNBUCBhbmQgdXNhZ2VTdGF0ZS4iOwogICAgcmVmZXJlbmNlICJTNS0xOTM1MTgiOwogIH0KCiAgcmV2aXNpb24gMjAxOS0wNi0yMyB7CiAgICByZWZlcmVuY2UgICJJbml0aWFsIHZlcnNpb24uIjsKICB9CgogIHR5cGVkZWYgRW5hYmxlZERpc2FibGVkIHsKICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICBlbnVtIERJU0FCTEVEIDsKICAgICAgZW51bSBFTkFCTEVEIDsKICAgIH0KICB9CgogIGdyb3VwaW5nIG5hbWVWYWx1ZVBhaXIgewogICAgbGVhZiBuYW1lIHsgdHlwZSBzdHJpbmc7IH0KICAgIGxlYWYgdmFsdWUgeyB0eXBlIHN0cmluZzsgfQogIH0KCiAgZ3JvdXBpbmcgUHJvY2Vzc01vbml0b3JHcnAgewogICAgZGVzY3JpcHRpb24gIlByb3ZpZGVzIGF0dHJpYnV0ZXMgdG8gbW9uaXRvciB0aGUgcHJvZ3Jlc3Mgb2YgcHJvY2Vzc2VzCiAgICAgIHdpdGggc3BlY2lmaWMgcHVycG9zZSBhbmQgbGltaXRlZCBsaWZldGltZSBydW5uaW5nIG9uIE1uUyBwcm9kdWNlcnMuCiAgICAgIEl0IG1heSBiZSB1c2VkIGFzIGRhdGEgdHlwZSBmb3IgZGVkaWNhdGVkIHByb2dyZXNzIG1vbml0b3IgYXR0cmlidXRlcwogICAgICB3aGVuIHNwZWNpZnlpbmcgdGhlIG1hbmFnZW1lbnQgcmVwcmVzZW50YXRpb24gb2YgdGhlc2UgcHJvY2Vzc2VzLgogICAgICBUaGUgYXR0cmlidXRlcyBpbiB0aGlzIGNsYXVzZSBhcmUgZGVmaW5lZCBpbiBhIGdlbmVyaWMgd2F5LgogICAgICBGb3Igc29tZSBhdHRyaWJ1dGVzIHNwZWNpYWxpc2F0aW9ucyBtYXkgYmUgcHJvdmlkZWQgd2hlbiBzcGVjaWZ5aW5nIGEKICAgICAgY29uY3JldGUgcHJvY2VzcyByZXByZXNlbnRhdGlvbi4KCiAgICAgIElmIGEgbWFuYWdlbWVudCBvcGVyYXRpb24gb24gc29tZSBJT0NzIHRyaWdnZXJzIGFuIGFzc29jaWF0ZWQKICAgICAgYXN5bmNocm9ub3VzIHByb2Nlc3MgKHdob3NlIHByb2dyZXNzIHNoYWxsIGJlIG1vbml0b3JlZCksIHRoaXMgc2hvdWxkCiAgICAgIGFsc28gcmVzdWx0IGluIGNyZWF0aW5nIGFuIGF0dHJpYnV0ZSBuYW1lZCAncHJvY2Vzc01vbml0b3InIChvZiB0eXBlCiAgICAgICdQcm9jZXNzTW9uaXRvcicpIGluIHRoZXNlIElPQyhzKS4gVGhlIHByb2Nlc3NNb25pdG9yIGF0dHJpYnV0ZSBtYXkgYmUKICAgICAgYWNjb21wYW5pZWQgYnkgdXNlLWNhc2Ugc3BlY2lmaWMgYWRkaXRpb25hbCBkYXRhIGl0ZW1zLgoKICAgICAgVGhlIHByb2dyZXNzIG9mIHRoZSBwcm9jZXNzIGlzIGRlc2NyaWJlZCBieSB0aGUgJ3N0YXR1cycgYW5kCiAgICAgICdwcm9ncmVzc1BlcmNlbnRhZ2UnIGF0dHJpYnV0ZXMuIEFkZGl0aW9uYWwgdGV4dHVhbCBxdWFsaWZpY2F0aW9ucyBmb3IKICAgICAgdGhlICdzdGF0dXMnIGF0dHJpYnV0ZSBtYXkgYmUgcHJvdmlkZWQgYnkgdGhlICdwcm9ncmVzc1N0YXRlSW5mbycgYW5kCiAgICAgICdyZXN1bHRTdGF0ZUluZm8nIGF0dHJpYnV0ZXMuCgogICAgICBXaGVuIHRoZSBwcm9jZXNzIGlzIGluc3RhbnRpYXRlZCwgdGhlICdzdGF0dXMnIGlzIHNldCB0byAnTk9UX1JVTk5JTkcnCiAgICAgIGFuZCB0aGUgJ3Byb2dyZXNzUGVyY2VudGFnZScgdG8gJzAnLiBUaGUgTW5TIHByb2R1Y2VyIGRlY2lkZXMgd2hlbiB0bwogICAgICBzdGFydCBleGVjdXRpbmcgdGhlIHByb2Nlc3MgYW5kIHRvIHRyYW5zaXRpb24gaW50byB0aGUgJ1JVTk5JTkcnIHN0YXRlLgogICAgICBUaGlzIHRpbWUgaXMgY2FwdHVyZWQgaW4gdGhlICdzdGFydFRpbWUnIGF0dHJpYnV0ZS4gQWx0ZXJuYXRpdmVseSwgdGhlCiAgICAgIHByb2Nlc3MgbWF5IHN0YXJ0IHRvIGV4ZWN1dGUgZGlyZWN0bHkgdXBvbiBpdHMgaW5zdGFudGlhdGlvbi4gT25lCiAgICAgIGFsdGVybmF0aXZlIG11c3QgYmUgc2VsZWN0ZWQgd2hlbiB1c2luZyB0aGlzIGRhdGEgdHlwZS4KCiAgICAgIER1cmluZyB0aGUgJ1JVTk5JTkcnIHN0YXRlIHRoZSAncHJvZ3Jlc3NQZXJjZW50YWdlJyBhdHRyaWJ1dGUgbWF5IGJlCiAgICAgIHJlcGVhdGVkbHkgdXBkYXRlZC4gVGhlIGV4YWN0IHNlbWFudGljIG9mIHRoaXMgYXR0cmlidXRlIGlzIHN1YmplY3QgdG8KICAgICAgZnVydGhlciBzcGVjaWFsaXNhdGlvbi4gVGhlICdwcm9ncmVzc0luZm8nIGF0dHJpYnV0ZSBtYXkgYmUgdXNlZCB0bwogICAgICBwcm92aWRlIGFkZGl0aW9uYWwgdGV4dHVhbCBpbmZvcm1hdGlvbiBpbiB0aGUgJ05PVF9SVU5OSU5HJywgJ0NBTkNFTExJTkcnCiAgICAgIGFuZCAnUlVOTklORycgc3RhdGVzLiBGdXJ0aGVyIHNwZWNpYWxpc2F0aW9uIG9mCiAgICAgICdwcm9ncmVzc1N0YXRlSW5mbycgbWF5IGJlIHByb3ZpZGVkIHdoZXJlIHRoaXMgZGF0YSB0eXBlIGlzCiAgICAgIHVzZWQuCgogICAgICBVcG9uIHN1Y2Nlc3NmdWwgY29tcGxldGlvbiBvZiB0aGUgcHJvY2VzcywgdGhlICdzdGF0dXMnIGF0dHJpYnV0ZSBpcyBzZXQKICAgICAgdG8gJ0ZJTklTSEVEJywgdGhlICdwcm9ncmVzc1BlcmNlbnRhZ2UnIHRvIDEwMCUuIFRoZSB0aW1lIGlzIGNhcHR1cmVkIGluCiAgICAgIHRoZSAnZW5kVGltZScgYXR0cmlidXRlLiBBZGRpdGlvbmFsIHRleHR1YWwgaW5mb3JtYXRpb24gbWF5IGJlIHByb3ZpZGVkCiAgICAgIGluIHRoZSAncmVzdWx0U3RhdGVJbmZvJyBhdHRyaWJ1dGUuIFRoZSB0eXBlIG9mCiAgICAgICdyZXN1bHRTdGF0ZUluZm8nIGluIHRoaXMgZGF0YSB0eXBlIGRlZmluaXRpb24gaXMgJ1N0cmluZycuCiAgICAgIEZ1cnRoZXIgc3BlY2lhbGlzYXRpb24gb2YgJ3Jlc3VsdFN0YXRlSW5mbycgbWF5IGJlIHByb3ZpZGVkCiAgICAgIHdoZXJlIHRoaXMgZGF0YSB0eXBlIGlzIHVzZWQuCgogICAgICBJbiBjYXNlIHRoZSBwcm9jZXNzIGZhaWxzIHRvIGNvbXBsZXRlIHN1Y2Nlc3NmdWxseSwgdGhlICdzdGF0dXMnCiAgICAgIGF0dHJpYnV0ZSBpcyBzZXQgdG8gJ0ZBSUxFRCcgb3IgJ1BBUlRJQUxMWV9GQUlMRUQnLCB0aGUgY3VycmVudCB2YWx1ZSBvZgogICAgICAncHJvZ3Jlc3NQZXJjZW50YWdlJyBpcyBmcm96ZW4sIGFuZCB0aGUgdGltZSBjYXB0dXJlZCBpbiAnZW5kVGltZScuIFRoZQogICAgICAncmVzdWx0U3RhdGVJbmZvJyBzcGVjaWZpZXMgdGhlIHJlYXNvbiBmb3IgdGhlIGZhaWx1cmUuCiAgICAgIFNwZWNpZmljIGZhaWx1cmUgcmVhc29ucyBtYXkgYmUgc3BlY2lmaWVkIHdoZXJlIHRoZSBkYXRhIHR5cGUgZGVmaW5lZCBpbgogICAgICB0aGlzIGNsYXVzZSBpcyB1c2VkLiBUaGUgZXhhY3Qgc2VtYW50aWMgb2YgZmFpbHVyZSBtYXkgYmUgc3ViamVjdCBmb3IKICAgICAgZnVydGhlciBzcGVjaWFsaXNhdGlvbiBhcyB3ZWxsLgoKICAgICAgSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBjYW5jZWxsZWQsIHRoZSAnc3RhdHVzJyBhdHRyaWJ1dGUgaXMgZmlyc3Qgc2V0IHRvCiAgICAgICdDQU5DRUxMSU5HJyBhbmQgd2hlbiB0aGUgcHJvY2VzcyBpcyByZWFsbHkgY2FuY2VsbGVkIHRoZW4gdG8gJ0NBTkNFTExFRCcuCiAgICAgIFRoZSB0cmFuc2l0aW9uIHRvICdDQU5DRUxMRUQnIGlzIGNhcHR1cmVkIGluIHRoZSAnZW5kVGltZScgYXR0cmlidXRlLgogICAgICBUaGUgdmFsdWUgb2YgJ3Byb2dyZXNzUGVyY2VudGFnZScgaXMgZnJvemVuLiBBZGRpdGlvbmFsIHRleHR1YWwKICAgICAgaW5mb3JtYXRpb24gbWF5IGJlIHByb3ZpZGVkIGluIHRoZSAncmVzdWx0U3RhdGVJbmZvJyBhdHRyaWJ1dGUuCgogICAgICBUaGUgJ3Jlc3VsdFN0YXRlSW5mbycgYXR0cmlidXRlIGlzIHByb3ZpZGVkIG9ubHkgZm9yIGFkZGl0aW9uYWwgdGV4dHVhbAogICAgICBxdWFsaWZpY2F0aW9uIG9mIHRoZSBzdGF0ZXMgJ0ZJTklTSEVEJywgJ0ZBSUxFRCcsICdQQVJUSUFMTFlfRkFJTEVEJyBvcgogICAgICAnQ0FOQ0VMTEVEJy4gSXQgc2hhbGwgbm90IGJlIHVzZWQgZm9yIG1ha2luZyB0aGUgb3V0Y29tZSwgdGhhdCB0aGUKICAgICAgcHJvY2VzcyBtYXkgcHJvZHVjZSBpbiBjYXNlIG9mIHN1Y2Nlc3MsIGF2YWlsYWJsZS4KCiAgICAgIFRoZSBwcm9jZXNzIG1heSBoYXZlIHRvIGJlIGNvbXBsZXRlZCB3aXRoaW4gYSBjZXJ0YWluIHRpbWUgYWZ0ZXIgaXRzCiAgICAgIGNyZWF0aW9uLCBmb3IgZXhhbXBsZSBiZWNhdXNlIHJlcXVpcmVkIGRhdGEgbWF5IG5vdCBiZSBhdmFpbGFibGUgYW55CiAgICAgIG1vcmUgYWZ0ZXIgYSBjZXJ0YWluIHRpbWUsIG9yIHRoZSBwcm9jZXNzIG91dGNvbWUgaXMgbmVlZGVkIHVudGlsIGEKICAgICAgY2VydGFpbiB0aW1lIGFuZCB3aGVuIG5vdCBwcm92aWRlZCBieSB0aGlzIHRpbWUgaXMgbm90IG5lZWRlZCBhbnkgbW9yZS4KICAgICAgVGhlIHRpbWUgdW50aWwgdGhlIE1uUyBwcm9kdWNlciBhdXRvbWF0aWNhbGx5IGNhbmNlbHMgdGhlIHByb2Nlc3MgaXMKICAgICAgaW5kaWNhdGVkIGJ5IHRoZSAndGltZXInIGF0dHJpYnV0ZS4iOwoKICAgIGxlYWYgaWQgewogICAgICB0eXBlIHN0cmluZzsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIGRlc2NyaXB0aW9uICJJZCBvZiB0aGUgcHJvY2Vzcy4gSXQgaXMgdW5pcXVlIHdpdGhpbiBhIHNpbmdsZQogICAgICAgIG11bHRpdmFsdWUgYXR0cmlidXRlIG9mIHR5cGUgUHJvY2Vzc01vbml0b3IuIjsKICAgIH0KCiAgICBsZWFmIHN0YXR1cyB7CiAgICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICAgIGVudW0gTk9UX1NUQVJURUQgOwogICAgICAgIGVudW0gUlVOTklORyA7CiAgICAgICAgZW51bSBDQU5DRUxMSU5HIDsKICAgICAgICBlbnVtIEZJTklTSEVEIDsKICAgICAgICBlbnVtIEZBSUxFRCA7CiAgICAgICAgZW51bSBQQVJUSUFMTFlfRkFJTEVEIDsKICAgICAgICBlbnVtIENBTkNFTExFRCA7CiAgICAgIH0KICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZWZhdWx0ICBSVU5OSU5HOwogICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyB0aGUgc3RhdHVzIG9mIHRoZSBhc3NvY2lhdGVkIHByb2Nlc3MsCiAgICAgICAgd2hldGhlciBpdCBmYWlscywgc3VjY2VlZHMgZXRjLgogICAgICAgIEl0IGRvZXMgbm90IHJlcHJlc2VudCB0aGUgcmV0dXJuZWQgdmFsdWVzIG9mIGEgc3VjY2Vzc2Z1bGx5IGZpbmlzaGVkCiAgICAgICAgcHJvY2Vzcy4gIjsKICAgIH0KCiAgICBsZWFmIHByb2dyZXNzUGVyY2VudGFnZSB7CiAgICAgIHR5cGUgdWludDggewogICAgICAgIHJhbmdlIDAuLjEwMDsKICAgICAgfQogICAgICBjb25maWcgZmFsc2U7CiAgICAgIGRlc2NyaXB0aW9uICJQcm9ncmVzcyBvZiB0aGUgYXNzb2NpYXRlZCBwcm9jZXNzIGFzIHBlcmNlbnRhZ2UiOwogICAgfQoKICAgIGxlYWYtbGlzdCBwcm9ncmVzc1N0YXRlSW5mbyB7CiAgICAgIHR5cGUgc3RyaW5nOwogICAgICBjb25maWcgZmFsc2U7CiAgICAgIGRlc2NyaXB0aW9uICJBZGRpdGlvbmFsIHRleHR1YWwgcXVhbGlmaWNhdGlvbiBvZiB0aGUgc3RhdGVzCiAgICAgICAgJ05PVF9TVEFSVEVEJywgJ0NBTkNFTExJTkcnIGFuZCAnUlVOTklORycuCgogICAgICAgIEZvciBzcGVjaWZpYyBwcm9jZXNzZXMsIHNwZWNpZmljIHdlbGwtZGVmaW5lZCBzdHJpbmdzIChlLmcuIHN0cmluZwogICAgICAgIHBhdHRlcm5zIG9yIGVudW1zKSBtYXkgYmUgZGVmaW5lZCBhcyBhIHNwZWNpYWxpc2F0aW9uLiI7CiAgICB9CgogICAgbGVhZiByZXN1bHRTdGF0ZUluZm8gewogICAgICB0eXBlIHN0cmluZzsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZXNjcmlwdGlvbiAiQWRkaXRpb25hbCB0ZXh0dWFsIHF1YWxpZmljYXRpb24gb2YgdGhlIHN0YXRlcwogICAgICAgICdGSU5JU0hFRCcsICdGQUlMRUQnLCAnUEFSVElBTExZX0ZBSUxFRCBhbmQgJ0NBTkNFTExFRCcuCiAgICAgICAgRm9yIGV4YW1wbGUsIGluIHRoZSAnRkFJTEVEJyBvciAnUEFSVElBTExZX0ZBSUxFRCcgc3RhdGUgdGhpcwogICAgICAgIGF0dHJpYnV0ZSBtYXkgYmUgdXNlZCB0byBwcm92aWRlIGVycm9yIHJlYXNvbnMuCgogICAgICAgIFRoaXMgYXR0cmlidXRlIHNoYWxsIG5vdCBiZSB1c2VkIHRvIG1ha2UgdGhlIG91dGNvbWUgb2YgdGhlIHByb2Nlc3MKICAgICAgICBhdmFpbGFibGUgZm9yIHJldHJpZXZhbCwgaWYgYW55LiBGb3IgdGhpcyBwdXJwb3NlLCBkZWRpY2F0ZWQKICAgICAgICBhdHRyaWJ1dGVzIHNoYWxsIGJlIHNwZWNpZmllZCB3aGVuIHNwZWNpZnlpbmcgdGhlIHJlcHJlc2VudGF0aW9uIG9mCiAgICAgICAgYSBzcGVjaWZpYyBwcm9jZXNzLgoKICAgICAgICBGb3Igc3BlY2lmaWMgcHJvY2Vzc2VzLCBzcGVjaWZpYyB3ZWxsLWRlZmluZWQgc3RyaW5ncyAoZS5nLiBzdHJpbmcKICAgICAgICBwYXR0ZXJucyBvciBlbnVtcykgbWF5IGJlIGRlZmluZWQgYXMgYSBzcGVjaWFsaXNhdGlvbi4iOwogICAgfQoKICAgIGxlYWYgc3RhcnRUaW1lIHsKICAgICAgdHlwZSB5YW5nOmRhdGUtYW5kLXRpbWU7CiAgICAgIGNvbmZpZyBmYWxzZTsKICAgICAgZGVzY3JpcHRpb24gIlN0YXJ0IHRpbWUgb2YgdGhlIGFzc29jaWF0ZWQgcHJvY2VzcywgaS5lLiB0aGUgdGltZSB3aGVuIHRoZQogICAgICAgIHN0YXR1cyBjaGFuZ2VkIGZyb20gJ05PVF9TVEFSVEVEJyB0byAnUlVOTklORycuIjsKICAgIH0KCiAgICBsZWFmIGVuZFRpbWUgewogICAgICB0eXBlIHlhbmc6ZGF0ZS1hbmQtdGltZTsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZXNjcmlwdGlvbiAiRGF0ZSBhbmQgdGltZSB3aGVuIHN0YXR1cyBjaGFuZ2VkIHRvICdTVUNDRVNTJywgJ0NBTkNFTExFRCcsCiAgICAgICAgJ0ZBSUxFRCcgb3IgJ1BBUlRJQUxMWV9GQUlMRUQnLgoKICAgICAgICBJZiB0aGUgdGltZSBpcyBpbiB0aGUgZnV0dXJlLCBpdCBpcyB0aGUgZXN0aW1hdGVkIHRpbWUKICAgICAgICB0aGUgcHJvY2VzcyB3aWxsIGVuZC4iOwogICAgfQoKICAgIGxlYWYgdGltZXIgewogICAgICB0eXBlIHVpbnQzMjsKICAgICAgdW5pdHMgbWludXRlczsKICAgICAgZGVzY3JpcHRpb24gIlRpbWUgdW50aWwgdGhlIGFzc29jaWF0ZWQgcHJvY2VzcyBpcyBhdXRvbWF0aWNhbGx5IGNhbmNlbGxlZC4KICAgICAgICBJZiBzZXQsIHRoZSBzeXN0ZW0gZGVjcmVhc2VzIHRoZSB0aW1lciB3aXRoIHRpbWUuIFdoZW4gaXQgcmVhY2hlcyB6ZXJvCiAgICAgICAgdGhlIGNhbmNlbGxhdGlvbiBvZiB0aGUgYXNzb2NpYXRlZCBwcm9jZXNzIGlzIGluaXRpYXRlZCBieSB0aGUKICAgICAgICBNblNfUHJvZHVjZXIuCiAgICAgICAgSWYgbm90IHNldCwgdGhlcmUgaXMgbm8gdGltZSBsaW1pdCBmb3IgdGhlIHByb2Nlc3MuCgogICAgICAgIE9uY2UgdGhlIHRpbWVyIGlzIHNldCwgdGhlIGNvbnN1bWVyIGNhbiBub3QgY2hhbmdlIGl0IGFueW1vcmUuCiAgICAgICAgSWYgdGhlIGNvbnN1bWVyIGhhcyBub3Qgc2V0IHRoZSB0aW1lciB0aGUgTW5TIFByb2R1Y2VyIG1heSBzZXQgaXQuIjsKICAgICAgeWV4dDNncHA6bm90Tm90aWZ5YWJsZTsKICAgIH0KICB9CgogIHR5cGVkZWYgVGVudGhPZkRlZ3JlZXMgewogICAgdHlwZSB1aW50MTYgewogICAgICByYW5nZSAwLi4zNjAwOwogICAgfQogICAgdW5pdHMgIjAuMSBkZWdyZWVzIjsKICAgIGRlc2NyaXB0aW9uICJBIHNpbmdsZSBpbnRlZ3JhbCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIGFuIGFuZ2xlIGluIGRlZ3JlZXMKICAgICAgYmV0d2VlbiAwIGFuZCAzNjAgd2l0aCBhIHJlc29sdXRpb24gb2YgMC4xIGRlZ3JlZXMuIjsKICB9CgogIHR5cGVkZWYgTGF0aXR1ZGUgewogICAgdHlwZSBkZWNpbWFsNjQgewogICAgICBmcmFjdGlvbi1kaWdpdHMgNDsKICAgICAgcmFuZ2UgIi05MC4wMDAwLi4rOTAuMDAwMCI7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiTGF0aXR1ZGUgdmFsdWVzIjsKICB9CgogIHR5cGVkZWYgTG9uZ2l0dWRlIHsKICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgZnJhY3Rpb24tZGlnaXRzIDQ7CiAgICAgIHJhbmdlICItMTgwLjAwMDAuLisxODAuMDAwMCI7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiTG9uZ2l0dWRlIHZhbHVlcyI7CiAgfQoKICB0eXBlZGVmIEFsdGl0dWRlICB7CiAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgIGZyYWN0aW9uLWRpZ2l0cyA2OwogICAgfQogICAgdW5pdHMgIm1ldGVycyI7CiAgICBkZXNjcmlwdGlvbgogICAgICAiSGVpZ2h0IGZyb20gYSByZWZlcmVuY2UgMCB2YWx1ZS4iOwogIH0KCiAgZ3JvdXBpbmcgR2VvZ3JhcGhpY2FsQ29vcmRpbmF0ZXMgewogICAgZGVzY3JpcHRpb24gIlRoaXMgZGF0YXR5cGUgcmVwcmVzZW50cyB0aGUgZ2VvZ3JhcGhpY2FsIGNvb3JkaW5hdGVzIjsKICAgIHJlZmVyZW5jZSAiI0dQUCBUUyAyOC41NTggY2xhdXNlIDYuMy44IjsKCiAgICBsZWFmIGxhdGl0dWRlIHsKICAgICAgdHlwZSBMYXRpdHVkZTsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CgogICAgbGVhZiBsb25naXR1ZGUgewogICAgICB0eXBlIExvbmdpdHVkZTsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CgogICAgbGVhZiBhbHRpdHVkZSB7CiAgICAgIHR5cGUgQWx0aXR1ZGU7CiAgICB9CgogIH0KCiAgdHlwZWRlZiBPbk9mZiB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBPTjsKICAgICAgZW51bSBPRkY7CiAgICB9CiAgfQoKICAvLyBncm91cGluZyBNYW5hZ2VkTkZQcm9maWxlIHdpbGwgYmUgcmVtb3ZlZCBhcyBpdCBpcwogIC8vICBiZWluZyBtb3ZlZCB0byBfM2dwcC01Z2MtbnJtLW5mcHJvZmlsZQogIGdyb3VwaW5nIE1hbmFnZWRORlByb2ZpbGUgewogICAgZGVzY3JpcHRpb24gIkRlZmluZXMgcHJvZmlsZSBmb3IgbWFuYWdlZCBORiI7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuNTAxIjsKCiAgICBsZWFmIGlkeCB7IHR5cGUgdWludDMyIDsgfQoKICAgIGxlYWYgbmZJbnN0YW5jZUlEIHsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSB5YW5nOnV1aWQgOwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBwcm9maWxlIGZvciBtYW5hZ2VkIE5GLgogICAgICAgIFRoZSBmb3JtYXQgb2YgdGhlIE5GIEluc3RhbmNlIElEIHNoYWxsIGJlIGEKICAgICAgICBVbml2ZXJzYWxseSBVbmlxdWUgSWRlbnRpZmllciAoVVVJRCkgdmVyc2lvbiA0LAogICAgICAgIGFzIGRlc2NyaWJlZCBpbiBJRVRGIFJGQyA0MTIyICIgOwogICAgICB5ZXh0M2dwcDppblZhcmlhbnQ7CiAgICB9CgogICAgbGVhZi1saXN0IG5mVHlwZSB7CiAgICAgIGNvbmZpZyBmYWxzZTsKICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgIHR5cGUgTmZUeXBlOwogICAgICBkZXNjcmlwdGlvbiAiVHlwZSBvZiB0aGUgTmV0d29yayBGdW5jdGlvbiIgOwogICAgfQoKICAgIGxlYWYgaG9zdEFkZHIgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSBpbmV0Omhvc3QgOwogICAgICBkZXNjcmlwdGlvbiAiSG9zdCBhZGRyZXNzIG9mIGEgTkYiOwogICAgfQoKICAgIGxlYWYgYXV0aHpJbmZvIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBORiBTcGVjaWZpYyBTZXJ2aWNlIGF1dGhvcml6YXRpb24KICAgICAgICBpbmZvcm1hdGlvbi4gSXQgc2hhbGwgaW5jbHVkZSB0aGUgTkYgdHlwZSAocykgYW5kIE5GIHJlYWxtcy9vcmlnaW5zCiAgICAgICAgYWxsb3dlZCB0byBjb25zdW1lIE5GIFNlcnZpY2Uocykgb2YgTkYgU2VydmljZSBQcm9kdWNlci4iOwogICAgICByZWZlcmVuY2UgIlNlZSBUUyAyMy41MDEiIDsKICAgIH0KCiAgICBsZWFmIGxvY2F0aW9uIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiSW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uIG9mIHRoZSBORiBpbnN0YW5jZQogICAgICAgIChlLmcuIGdlb2dyYXBoaWMgbG9jYXRpb24sIGRhdGEgY2VudGVyKSBkZWZpbmVkIGJ5IG9wZXJhdG9yIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmIGNhcGFjaXR5IHsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIHR5cGUgdWludDE2IDsKICAgICAgZGVzY3JpcHRpb24gIlRoaXMgcGFyYW1ldGVyIGRlZmluZXMgc3RhdGljIGNhcGFjaXR5IGluZm9ybWF0aW9uCiAgICAgICAgaW4gdGhlIHJhbmdlIG9mIDAtNjU1MzUsIGV4cHJlc3NlZCBhcyBhIHdlaWdodCByZWxhdGl2ZSB0byBvdGhlcgogICAgICAgIE5GIGluc3RhbmNlcyBvZiB0aGUgc2FtZSB0eXBlOyBpZiBjYXBhY2l0eSBpcyBhbHNvIHByZXNlbnQgaW4gdGhlCiAgICAgICAgbmZTZXJ2aWNlTGlzdCBwYXJhbWV0ZXJzLCB0aG9zZSB3aWxsIGhhdmUgcHJlY2VkZW5jZSBvdmVyIHRoaXMgdmFsdWUuIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmIG5GU3J2R3JvdXBJZCB7CiAgICAgIHR5cGUgc3RyaW5nIDsKICAgICAgZGVzY3JpcHRpb24gIlRoaXMgcGFyYW1ldGVyIGRlZmluZXMgaWRlbnRpdHkgb2YgdGhlIGdyb3VwIHRoYXQgaXMKICAgICAgICBzZXJ2ZWQgYnkgdGhlIE5GIGluc3RhbmNlLgogICAgICAgIE1heSBiZSBjb25maWcgZmFsc2Ugb3IgdHJ1ZSBkZXBlbmRpbmcgb24gdGhlIE1hbmFnZWRGdW5jdGlvbi4KICAgICAgICBDb25maWc9dHJ1ZSBmb3IgVWRyaW5mby4gQ29uZmlnPWZhbHNlIGZvciBVZG1JbmZvIGFuZCBBdXNmSW5mby4KICAgICAgICBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IFVETSBvciBBVVNGIG9yIFVEUi4gIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmLWxpc3Qgc3VwcG9ydGVkRGF0YVNldElkcyB7CiAgICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICAgIGVudW0gU1VCU0NSSVBUSU9OOwogICAgICAgIGVudW0gUE9MSUNZOwogICAgICAgIGVudW0gRVhQT1NVUkU7CiAgICAgICAgZW51bSBBUFBMSUNBVElPTjsKICAgICAgfQogICAgICBkZXNjcmlwdGlvbiAiTGlzdCBvZiBzdXBwb3J0ZWQgZGF0YSBzZXRzIGluIHRoZSBVRFIgaW5zdGFuY2UuCiAgICAgICAgTWF5IGJlIHByZXNlbnQgaWYgLi4vbmZUeXBlID0gVURSIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmLWxpc3Qgc21mU2VydmluZ0FyZWFzIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiRGVmaW5lcyB0aGUgU01GIHNlcnZpY2UgYXJlYShzKSB0aGUgVVBGIGNhbiBzZXJ2ZS4KICAgICAgICBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IFVQRiI7CiAgICAgIHJlZmVyZW5jZSAiVFMgMjkuNTEwIiA7CiAgICB9CgogICAgbGVhZiBwcmlvcml0eSB7CiAgICAgIHR5cGUgdWludDE2OwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBQcmlvcml0eSAocmVsYXRpdmUgdG8gb3RoZXIgTkZzCiAgICAgICAgb2YgdGhlIHNhbWUgdHlwZSkgaW4gdGhlIHJhbmdlIG9mIDAtNjU1MzUsIHRvIGJlIHVzZWQgZm9yIE5GIHNlbGVjdGlvbjsKICAgICAgICBsb3dlciB2YWx1ZXMgaW5kaWNhdGUgYSBoaWdoZXIgcHJpb3JpdHkuIElmIHByaW9yaXR5IGlzIGFsc28gcHJlc2VudAogICAgICAgIGluIHRoZSBuZlNlcnZpY2VMaXN0IHBhcmFtZXRlcnMsIHRob3NlIHdpbGwgaGF2ZSBwcmVjZWRlbmNlIG92ZXIKICAgICAgICB0aGlzIHZhbHVlLiBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IEFNRiAiOwogICAgICByZWZlcmVuY2UgIlRTIDI5LjUxMCIgOwogICAgfQogIH0KCiAgdHlwZWRlZiB1c2FnZVN0YXRlIHsKICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICBlbnVtIElETEU7CiAgICAgIGVudW0gQUNUSVZFOwogICAgICBlbnVtIEJVU1k7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiSXQgZGVzY3JpYmVzIHdoZXRoZXIgb3Igbm90IHRoZSByZXNvdXJjZSBpcyBhY3RpdmVseSBpbgogICAgICB1c2UgYXQgYSBzcGVjaWZpYyBpbnN0YW50LCBhbmQgaWYgc28sIHdoZXRoZXIgb3Igbm90IGl0IGhhcyBzcGFyZQogICAgICBjYXBhY2l0eSBmb3IgYWRkaXRpb25hbCB1c2VycyBhdCB0aGF0IGluc3RhbnQuIFRoZSB2YWx1ZSBpcyBSRUFELU9OTFkuIjsKICAgIHJlZmVyZW5jZSAiSVRVIFQgUmVjb21tZW5kYXRpb24gWC43MzEiOwogIH0KCiAgZ3JvdXBpbmcgU0FQR3JwIHsKICAgIGxlYWYgaG9zdCB7CiAgICAgIHR5cGUgaW5ldDpob3N0OwogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgIH0KICAgIGxlYWYgcG9ydCB7CiAgICAgIHR5cGUgaW5ldDpwb3J0LW51bWJlcjsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiU2VydmljZSBhY2Nlc3MgcG9pbnQuIjsKICAgIHJlZmVyZW5jZSAiVFMgMjguNjIyIjsKICB9CgogIHR5cGVkZWYgTWNjIHsKICAgIGRlc2NyaXB0aW9uICJUaGUgbW9iaWxlIGNvdW50cnkgY29kZSBjb25zaXN0cyBvZiB0aHJlZSBkZWNpbWFsIGRpZ2l0cywKICAgICAgVGhlIGZpcnN0IGRpZ2l0IG9mIHRoZSBtb2JpbGUgY291bnRyeSBjb2RlIGlkZW50aWZpZXMgdGhlIGdlb2dyYXBoaWMKICAgICAgcmVnaW9uICh0aGUgZGlnaXRzIDEgYW5kIDggYXJlIG5vdCB1c2VkKToiOwogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMDItNzldWzAtOV1bMC05XSc7CiAgICB9CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuMDAzIHN1YmNsYXVzZSAyLjIgYW5kIDEyLjEiOwogIH0KCiAgdHlwZWRlZiBNbmMgewogICAgZGVzY3JpcHRpb24gIlRoZSBtb2JpbGUgbmV0d29yayBjb2RlIGNvbnNpc3RzIG9mIHR3byBvciB0aHJlZQogICAgICBkZWNpbWFsIGRpZ2l0cyAoZm9yIGV4YW1wbGU6IE1OQyBvZiAwMDEgaXMgbm90IHRoZSBzYW1lIGFzIE1OQyBvZiAwMSkiOwogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMC05XVswLTldWzAtOV18WzAtOV1bMC05XSc7CiAgICB9CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuMDAzIHN1YmNsYXVzZSAyLjIgYW5kIDEyLjEiOwogIH0KCiAgZ3JvdXBpbmcgUExNTklkIHsKICAgIGxlYWYgbWNjIHsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIHR5cGUgTWNjOwogICAgfQogICAgbGVhZiBtbmMgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSBNbmM7CiAgICB9CiAgICByZWZlcmVuY2UgIlRTIDM4LjQxMyBjbGF1c2UgOS4zLjMuNSI7CiAgfQoKICB0eXBlZGVmIE5jaSB7CiAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbCBJZGVudGl0eS4gVGhlIE5DSSBzaGFsbCBiZSBvZiBmaXhlZCBsZW5ndGggb2YgMzYgYml0cwogICAgICBhbmQgc2hhbGwgYmUgY29kZWQgdXNpbmcgZnVsbCBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi4KICAgICAgVGhlIGV4YWN0IGNvZGluZyBvZiB0aGUgTkNJIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBlYWNoIFBMTU4gb3BlcmF0b3IiOwogICAgcmVmZXJlbmNlICJUUyAyMy4wMDMiOwogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggMzY7CiAgICAgICAgcGF0dGVybiAnWzAxXSsnOwogICAgICB9CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggOTsKICAgICAgICBwYXR0ZXJuICdbYS1mQS1GMC05XSonOwogICAgICB9CiAgICB9CiAgfQoKICB0eXBlZGVmIE9wZXJhdGlvbmFsU3RhdGUgewogICAgcmVmZXJlbmNlICIzR1BQIFRTIDI4LjYyNSBhbmQgSVRVLVQgWC43MzEiOwogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gRElTQUJMRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyB0b3RhbGx5IGlub3BlcmFibGUuIjsKICAgICAgfQoKICAgICAgZW51bSBFTkFCTEVEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgcGFydGlhbGx5IG9yIGZ1bGx5IG9wZXJhYmxlLiI7CiAgICAgIH0KCiAgICB9CiAgfQoKICB0eXBlZGVmIEJhc2ljQWRtaW5pc3RyYXRpdmVTdGF0ZSB7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjguNjI1IGFuZCBJVFUtVCBYLjczMSI7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBMT0NLRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyBhZG1pbmlzdHJhdGl2ZWx5IHByb2hpYml0ZWQgZnJvbSBwZXJmb3JtaW5nCiAgICAgICAgICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4iOwogICAgICB9CgogICAgICBlbnVtIFVOTE9DS0VEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgYWRtaW5pc3RyYXRpdmVseSBwZXJtaXR0ZWQgdG8gcGVyZm9ybQogICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4gVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBpdHMgaW5oZXJlbnQKICAgICAgICAgIG9wZXJhYmlsaXR5LiI7CiAgICAgIH0KICAgIH0KICB9CgogIHR5cGVkZWYgQWRtaW5pc3RyYXRpdmVTdGF0ZSB7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjguNjI1IGFuZCBJVFUtVCBYLjczMSI7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBMT0NLRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyBhZG1pbmlzdHJhdGl2ZWx5IHByb2hpYml0ZWQgZnJvbSBwZXJmb3JtaW5nCiAgICAgICAgICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4iOwogICAgICB9CgogICAgICBlbnVtIFVOTE9DS0VEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgYWRtaW5pc3RyYXRpdmVseSBwZXJtaXR0ZWQgdG8gcGVyZm9ybQogICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4gVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBpdHMgaW5oZXJlbnQKICAgICAgICAgIG9wZXJhYmlsaXR5LiI7CiAgICAgIH0KCiAgICAgIGVudW0gU0hVVFRJTkdET1dOIHsKICAgICAgICB2YWx1ZSAyOwogICAgICAgIGRlc2NyaXB0aW9uICJVc2Ugb2YgdGhlIHJlc291cmNlIGlzIGFkbWluaXN0cmF0aXZlbHkgcGVybWl0dGVkIHRvCiAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZXMgb2YgdXNlIG9ubHkuIFdoaWxlIHRoZSBzeXN0ZW0gcmVtYWlucyBpbgogICAgICAgICAgdGhlIHNodXR0aW5nIGRvd24gc3RhdGUgdGhlIG1hbmFnZXIgb3IgdGhlIG1hbmFnZWQgZWxlbWVudAogICAgICAgICAgbWF5IGF0IGFueSB0aW1lIGNhdXNlIHRoZSByZXNvdXJjZSB0byB0cmFuc2l0aW9uIHRvIHRoZQogICAgICAgICAgbG9ja2VkIHN0YXRlLiI7CiAgICAgIH0KICAgIH0KICB9CgogIHR5cGVkZWYgQXZhaWxhYmlsaXR5U3RhdHVzIHsKICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICBlbnVtIElOX1RFU1Q7CiAgICAgICAgICBlbnVtIEZBSUxFRDsKICAgICAgICAgIGVudW0gUE9XRVJfT0ZGOwogICAgICAgICAgZW51bSBPRkZfTElORTsKICAgICAgICAgIGVudW0gT0ZGX0RVVFk7CiAgICAgICAgICBlbnVtIERFUEVOREVOQ1k7CiAgICAgICAgICBlbnVtIERFR1JBREVEOwogICAgICAgICAgZW51bSBOT1RfSU5TVEFMTEVEOwogICAgICAgICAgZW51bSBMT0dfRlVMTDsKICAgICAgIH0KICB9CgogIHR5cGVkZWYgQ2VsbFN0YXRlIHsKICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgZW51bSBJRExFOwogICAgICAgIGVudW0gSU5BQ1RJVkU7CiAgICAgICAgZW51bSBBQ1RJVkU7CiAgICAgfQogIH0KCiAgdHlwZWRlZiBOcnBjaSB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uICJQaHlzaWNhbCBDZWxsIElkZW50aXR5IChQQ0kpIG9mIHRoZSBOUiBjZWxsLiI7CiAgICByZWZlcmVuY2UgIlRTIDM2LjIxMSBzdWJjbGF1c2UgNi4xMSI7CiAgfQoKICB0eXBlZGVmIFRhYyB7CiAgICB0eXBlIGludDMyIHsKICAgICAgcmFuZ2UgMC4uMTY3NzcyMTUgOwogICAgfQogICAgZGVzY3JpcHRpb24gIlRyYWNraW5nIEFyZWEgQ29kZSI7CiAgICByZWZlcmVuY2UgIlRTIDIzLjAwMyBjbGF1c2UgMTkuNC4yLjMiOwogIH0KCiAgZ3JvdXBpbmcgVGFpR3JwIHsKICAgIGRlc2NyaXB0aW9uICJUaGlzIDw8ZGF0YVR5cGU+PiBkZWZpbmVzIGEgVHJhY2tpbmcgQXJlYSBJZGVudGl0eSAoVEFJKQogICAgICBhcyBzcGVjaWZpZWQgaW4gY2xhdXNlIDI4LjYgb2YgVFMgMjMuMDAzLCBjbGF1c2UgOC4yIG9mIFRTIDM4LjMwMAogICAgICBhbmQgY2xhdXNlIDkuMy4zLjExIG9mIFRTIDM4LjQxMy4gSXQgaXMgY29tcG9zZWQgb2YgdGhlIFBMTU4KICAgICAgaWRlbnRpZmllciAoUExNTi1JZCwgd2hpY2ggaXMgY29tcG9zZWQgb2YgdGhlIE1DQyBhbmQgTU5DKSBhbmQKICAgICAgdGhlIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKS4gIjsKICAgIGxpc3QgcGxtbklkIHsKICAgICAgZGVzY3JpcHRpb24gIlBMTU4gSWRlbnRpdHkuIjsKICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgIG1heC1lbGVtZW50cyAxOwogICAgICBrZXkgIm1jYyBtbmMiOwogICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICB9CgogICAgbGVhZiB0YWMgeyB0eXBlIFRhYzsgfQogIH0KCiAgZ3JvdXBpbmcgR2VvQ29vcmRpbmF0ZUdycCB7CiAgICBkZXNjcmlwdGlvbiAiR2VvZ3JhcGhpY2FsIGxvY2F0aW9uIG9uIGVhcnRoIjsKICAgIGxlYWYgbGF0aXR1ZGUgewogICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDQ7CiAgICAgICAgcmFuZ2UgLTkwLi45MCA7CiAgICAgIH0KICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIGRlc2NyaXB0aW9uICJMYXRpdHVkZSBiYXNlZCBvbiBXb3JsZCBHZW9kZXRpYyBTeXN0ZW0gKDE5ODQgdmVyc2lvbikKICAgICAgICBnbG9iYWwgcmVmZXJlbmNlIGZyYW1lIChXR1MgODQpLiBQb3NpdGl2ZSB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUKICAgICAgICBub3J0aGVybiBoZW1pc3BoZXJlLiI7CiAgICAgIH0KCiAgICBsZWFmIGxvbmdpdHVkZSB7CiAgICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNDsKICAgICAgICByYW5nZSAtMTgwLi4xODAgOwogICAgICB9CiAgICAgIG1hbmRhdG9yeSB0cnVlOwogICAgICBkZXNjcmlwdGlvbiAiTG9uZ2l0dWRlIGJhc2VkIG9uIFdvcmxkIEdlb2RldGljIFN5c3RlbSAoMTk4NCB2ZXJzaW9uKQogICAgICAgIGdsb2JhbCByZWZlcmVuY2UgZnJhbWUgKFdHUyA4NCkuIFBvc2l0aXZlIHZhbHVlcyBjb3JyZXNwb25kIHRvCiAgICAgICAgZGVncmVlcyBlYXN0IG9mIDAgZGVncmVlcyBsb25naXR1ZGUuIjsKICAgIH0KICB9CgogIGdyb3VwaW5nIEdlb0FyZWFHcnAgewogICAgZGVzY3JpcHRpb24gIlRoaXMgZGF0YSB0eXBlIGRlZmluZXMgYSBnZW9ncmFwaGljYWwgYXJlYS4KICAgICAgVGhlIGdlby1hcmVhIGlzIGRlZmluZWQgdXNpbmcgYSBjb252ZXggcG9seWdvbiBpbiB0aGUgYXR0cmlidXRlCiAgICAgICdjb252ZXhHZW9Qb2x5Z29uJy4iOwoKICAgIGxpc3QgY29udmV4R2VvUG9seWdvbiB7CiAgICAgIGRlc2NyaXB0aW9uICJTcGVjaWZpZXMgdGhlIGdlb2dyYXBoaWNhbCBhcmVhIHdpdGggYSBjb252ZXggcG9seWdvbi4KICAgICAgICBUaGUgY29udmV4IHBvbHlnb24gaXMgc3BlY2lmaWVkIGJ5IGl0cyBjb3JuZXJzLiI7CiAgICAgICAga2V5ICJsYXRpdHVkZSBsb25naXR1ZGUiOwogICAgICBtaW4tZWxlbWVudHMgMzsKICAgICAgb3JkZXJlZC1ieSB1c2VyOwoKICAgICAgdXNlcyBHZW9Db29yZGluYXRlR3JwOwogICAgfQogIH0KCiAgdHlwZWRlZiBBbWZSZWdpb25JZCB7CiAgICB0eXBlIHVuaW9uIHsKICAgICAgdHlwZSB1aW50OCA7CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggODsKICAgICAgICBwYXR0ZXJuICdbMDFdKic7CiAgICAgIH0KICAgIH0KICAgIHJlZmVyZW5jZSAiY2xhdXNlIDIuMTAuMSBvZiAzR1BQIFRTIDIzLjAwMyI7CiAgfQoKICB0eXBlZGVmIEFtZlNldElkIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIHVpbnQxNiB7CiAgICAgICAgcmFuZ2UgJzAuLjEwMjMnOwogICAgICB9CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggODsKICAgICAgICBwYXR0ZXJuICdbMDFdKic7CiAgICAgIH0KICAgIH0KICAgIHJlZmVyZW5jZSAiY2xhdXNlIDIuMTAuMSBvZiAzR1BQIFRTIDIzLjAwMyI7CiAgfQoKICB0eXBlZGVmIEFtZlBvaW50ZXIgewogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgdWludDggewogICAgICAgIHJhbmdlICcwLi42Myc7CiAgICAgIH0KICAgICAgdHlwZSBzdHJpbmcgewogICAgICAgIGxlbmd0aCA2OwogICAgICAgIHBhdHRlcm4gJ1swMV0qJzsKICAgICAgfQogICAgfQogICAgcmVmZXJlbmNlICJjbGF1c2UgMi4xMC4xIG9mIDNHUFAgVFMgMjMuMDAzIjsKICB9CgogIGdyb3VwaW5nIEFtZklkZW50aWZpZXIgewogICAgbGVhZiBhbWZSZWdpb25JZCB7CiAgICAgIHR5cGUgQW1mUmVnaW9uSWQ7CiAgICB9CiAgICBsZWFmIGFtZlNldElkIHsKICAgICAgdHlwZSBBbWZTZXRJZDsKICAgIH0KICAgIGxlYWYgYW1mUG9pbnRlciB7CiAgICAgIHR5cGUgQW1mUG9pbnRlcjsKICAgIH0KICAgIGRlc2NyaXB0aW9uICJUaGUgQU1GSSBpcyBjb25zdHJ1Y3RlZCBmcm9tIGFuIEFNRiBSZWdpb24gSUQsCiAgICAgIGFuIEFNRiBTZXQgSUQgYW5kIGFuIEFNRiBQb2ludGVyLgogICAgICBUaGUgQU1GIFJlZ2lvbiBJRCBpZGVudGlmaWVzIHRoZSByZWdpb24sCiAgICAgIHRoZSBBTUYgU2V0IElEIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIEFNRiBTZXQgd2l0aGluIHRoZSBBTUYgUmVnaW9uLCBhbmQKICAgICAgdGhlIEFNRiBQb2ludGVyIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIEFNRiB3aXRoaW4gdGhlIEFNRiBTZXQuICI7CiAgfQoKLy8gdHlwZSBkZWZpbml0aW9ucyBlc3BlY2lhbGx5IGZvciBjb3JlIE5GcwoKICB0eXBlZGVmIE5mVHlwZSB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBOUkY7CiAgICAgIGVudW0gVURNOwogICAgICBlbnVtIEFNRjsKICAgICAgZW51bSBTTUY7CiAgICAgIGVudW0gQVVTRjsKICAgICAgZW51bSBORUY7CiAgICAgIGVudW0gUENGOwogICAgICBlbnVtIFNNU0Y7CiAgICAgIGVudW0gTlNTRjsKICAgICAgZW51bSBVRFI7CiAgICAgIGVudW0gTE1GOwogICAgICBlbnVtIEdNTEM7CiAgICAgIGVudW0gNUdfRUlSOwogICAgICBlbnVtIFNFUFA7CiAgICAgIGVudW0gVVBGOwogICAgICBlbnVtIE4zSVdGOwogICAgICBlbnVtIEFGOwogICAgICBlbnVtIFVEU0Y7CiAgICAgIGVudW0gQlNGOwogICAgICBlbnVtIENIRjsKICAgIH0KICB9CgogIHR5cGVkZWYgTm90aWZpY2F0aW9uVHlwZSB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBOMV9NRVNTQUdFUzsKICAgICAgZW51bSBOMl9JTkZPUk1BVElPTjsKICAgICAgZW51bSBMT0NBVElPTl9OT1RJRklDQVRJT047CiAgICB9CiAgfQoKICB0eXBlZGVmIExvYWQgewogICAgZGVzY3JpcHRpb24gIkxhdGVzdCBrbm93biBsb2FkIGluZm9ybWF0aW9uIG9mIHRoZSBORiwgcGVyY2VudGFnZSAiOwogICAgdHlwZSB1aW50OCB7CiAgICAgIHJhbmdlIDAuLjEwMDsKICAgIH0KICB9CgogIHR5cGVkZWYgTjFNZXNzYWdlQ2xhc3MgewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gNUdNTTsKICAgICAgZW51bSBTTTsKICAgICAgZW51bSBMUFA7CiAgICAgIGVudW0gU01TOwogICAgfQogIH0KCiAgdHlwZWRlZiBOMkluZm9ybWF0aW9uQ2xhc3MgewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gU007CiAgICAgIGVudW0gTlJQUEE7CiAgICAgIGVudW0gUFdTOwogICAgICBlbnVtIFBXU19CQ0FMOwogICAgICBlbnVtIFBXU19SRjsKICAgIH0KICB9CgogIGdyb3VwaW5nIERlZmF1bHROb3RpZmljYXRpb25TdWJzY3JpcHRpb24gewoKICAgIGxlYWYgbm90aWZpY2F0aW9uVHlwZSB7CiAgICAgIHR5cGUgTm90aWZpY2F0aW9uVHlwZTsKICAgIH0KCiAgICBsZWFmIGNhbGxiYWNrVXJpIHsKICAgICAgdHlwZSBpbmV0OnVyaTsKICAgIH0KCiAgICBsZWFmIG4xTWVzc2FnZUNsYXNzIHsKICAgICAgdHlwZSBOMU1lc3NhZ2VDbGFzczsKICAgIH0KCiAgICBsZWFmIG4ySW5mb3JtYXRpb25DbGFzcyB7CiAgICAgIHR5cGUgTjJJbmZvcm1hdGlvbkNsYXNzOwogICAgfQogIH0KCiAgZ3JvdXBpbmcgSXB2NEFkZHJlc3NSYW5nZSB7CiAgbGVhZiBzdGFydCB7CiAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzOwogICAgfQogIGxlYWYgZW5kIHsKICAgIHR5cGUgaW5ldDppcHY0LWFkZHJlc3M7CiAgICB9CiAgfQoKICBncm91cGluZyBJcHY2UHJlZml4UmFuZ2UgewogIGxlYWYgc3RhcnQgewogICAgdHlwZSBpbmV0OmlwdjYtcHJlZml4OwogICAgfQogIGxlYWYgZW5kIHsKICAgIHR5cGUgaW5ldDppcHY2LXByZWZpeDsKICAgIH0KICB9CgogIHR5cGVkZWYgTnNpSWQgewogICAgdHlwZSBzdHJpbmc7CiAgfQoKICB0eXBlZGVmIFVlTW9iaWxpdHlMZXZlbCB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBTVEFUSU9OQVJZOwogICAgICBlbnVtIE5PTUFESUM7CiAgICAgIGVudW0gUkVTVFJJQ1RFRF9NT0JJTElUWTsKICAgICAgZW51bSBGVUxMWV9NT0JJTElUWTsKICAgIH0KICB9CgogIHR5cGVkZWYgUmVzb3VyY2VTaGFyaW5nTGV2ZWwgewogICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICBlbnVtIFNIQVJFRDsKICAgICAgICBlbnVtIE5PVF9TSEFSRUQ7CiAgICAgIH0KICB9CgogIHR5cGVkZWYgVHhEaXJlY3Rpb24gewogICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICBlbnVtIERMOwogICAgICAgIGVudW0gVUw7CiAgICAgICAgZW51bSBETF9BTkRfVUw7CiAgICAgIH0KICB9CgogIGdyb3VwaW5nIEFkZHJlc3NXaXRoVmxhbiB7CiAgICBsZWFmIGlwQWRkcmVzcyB7CiAgICAgIHR5cGUgaW5ldDppcC1hZGRyZXNzOwogICAgfQogICAgbGVhZiB2bGFuSWQgewogICAgICAgdHlwZSB1aW50MTY7CiAgICB9CiAgfQoKICAvKiBEaXN0aW5ndWlzaGVkTmFtZSBwYXR0ZXJuIGlzIGJ1aWx0IHVwIGJhc2VkIG9uIHRoZQogICAgRUJORiBpbiAzMi4zMDAgY2xhdXNlIDcuMyAgRUJORiBvZiBETiBTdHJpbmcgUmVwcmVzZW50YXRpb24KCiAgICBsZWFmIEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vICBTYW1lIHBhdHRlcm4gYXMgTG9jYWxETgogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPygsW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKj0oW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pKic7CiAgICB9IH0KCiAgICBsZWFmIGZ1bGxMb2NhbEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIExvY2FsUkROICwgeyBSRE5TZXBhcmF0b3IgLCBMb2NhbFJETiB9ICAgIFJETlNlcGFyYXRvciBpcyBhIHNpbmdsZSAsIG5vIHNwYWNlIG9yIFxSIGFsbG93ZWQgICBNZS5teWtleT0xIGFsbG93ZWQKICAgICAgLy8gIChmdWxsTG9jYWxSRE4pKCwoZnVsbExvY2FsUkROKSkqCiAgICAgIHBhdHRlcm4gJygoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKikpPSgoW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pKSgsKChbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qfChbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qXC5bYS16XVteLD0rPD4jO1xcIlxyXG4qLl0qKSk9KChbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykpKSonOwogICAgfSB9CgogICAgbGVhZiBMb2NhbEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIExvY2FsUkROICwgeyBSRE5TZXBhcmF0b3IgLCBMb2NhbFJETiB9ICAgIFJETlNlcGFyYXRvciBpcyBhIHNpbmdsZSAsIG5vIHNwYWNlIG9yIFxSIGFsbG93ZWQKICAgICAgLy8gIExvY2FsUkROKCxMb2NhbFJETikqCiAgICAgIHBhdHRlcm4gJ1tBLVpdW14sPSs8PiM7XFwiXHJcbiouXSo9KFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/KCxbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykqJzsKICAgIH0gfQoKICAgIGxlYWYgZnVsbExvY2FsUkROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIHNhbWUgYXMgZnVsbExvY2FsRE5BdHRyaWJ1dGVUeXBlQW5kVmFsdWUKICAgICAgcGF0dGVybiAnKFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSp8KFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSpcLlthLXpdW14sPSs8PiM7XFwiXHJcbiouXSopKT0oKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/KSc7CiAgICB9IH0KCiAgICBsZWFmIExvY2FsUkROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIHNhbWUgYXMgTG9jYWxETkF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPyc7CiAgICB9IH0KCiAgICBsZWFmIGZ1bGxMb2NhbEROQXR0cmlidXRlVHlwZUFuZFZhbHVlIHsgdHlwZSBzdHJpbmcgeyAvLyBMb2NhbEROQXR0cmlidXRlVHlwZSAsIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZVNlcGFyYXRvciAsIFJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICAvLyBwYXR0ZXJuIExvY2FsRE5BdHRyaWJ1dGVUeXBlPVJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICBwYXR0ZXJuICcoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKikpPSgoW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pJzsKICAgIH0gfQoKICAgICAgLy8gbGltaXRhdGlvbjogTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlbm90IHN1cHBvcnRlZCBNZS5teWtleT0xCiAgICBsZWFmIExvY2FsRE5BdHRyaWJ1dGVUeXBlQW5kVmFsdWUgeyB0eXBlIHN0cmluZyB7CiAgICAgIC8vIGVibmYxICAgICAgICAgIExvY2FsRE5BdHRyaWJ1dGVUeXBlICwgQXR0cmlidXRlVHlwZUFuZFZhbHVlU2VwYXJhdG9yICwgUmVndWxhckF0dHJpYnV0ZVZhbHVlCiAgICAgIC8vIGVibmYyLWxpbWl0ZWQgIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlICwgQXR0cmlidXRlVHlwZUFuZFZhbHVlU2VwYXJhdG9yICwgUmVndWxhckF0dHJpYnV0ZVZhbHVlCiAgICAgIC8vIHBhdHRlcm4gICAgICAgIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlPVJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPyc7CiAgICB9IH0KCiAgICBsZWFmIExvY2FsRE5BdHRyaWJ1dGVUeXBlIHsgdHlwZSBzdHJpbmcgeyAgIC8vIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlIHwgTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlICBSRE5TZXBhcmF0b3IgaXMgYSBzaW5nbGUgLCBubyBzcGFjZSBvciBcUiBhbGxvd2VkCiAgICAgIC8vICBOYW1lT2ZDbGFzc1dpdGhJZEF0dHJpYnV0ZXxOYW1lc09mQ2xhc3NBbmROYW1pbmdBdHRyaWJ1dGUKICAgICAgcGF0dGVybiAnW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKiknOwogICAgfSB9CgogICAgbGVhZiBSZWd1bGFyQXR0cmlidXRlVmFsdWUgeyB0eXBlIHN0cmluZyB7ICAgICAgIC8vICggQXR0cmlidXRlVmFsdWVDaGFyIC0gU3BhY2VDaGFyICkgLCBbIHsgQXR0cmlidXRlVmFsdWVDaGFyIH0gLCAoIEF0dHJpYnV0ZVZhbHVlQ2hhciAtIFNwYWNlQ2hhciApIF0KICAgICAgcGF0dGVybiAnKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/JyA7CiAgICB9IH0KCiAgICBsZWFmIE5hbWVzT2ZDbGFzc0FuZE5hbWluZ0F0dHJpYnV0ZSAgeyB0eXBlIHN0cmluZyB7ICAvLyBDbGFzc05hbWUgLCBDbGFzc05hbWluZ0F0dHJpYnV0ZVNlcGFyYXRvciAsIE5hbWluZ0F0dHJpYnV0ZU5hbWUKICAgICAgLy8gcGF0dGVybjogQ2xhc3NOYW1lXC5OYW1pbmdBdHRyaWJ1dGVOYW1lCiAgICAgIHBhdHRlcm4gJ1tBLVpdW14sPSs8PiM7XFwiXHJcbiouXSpcLlthLXpdW14sPSs8PiM7XFwiXHJcbiouXSonIDsKICAgIH0gfQoKICAgIGxlYWYgcmVzdHJpY3RpdmVDbGFzc05hbWUgeyB0eXBlIHN0cmluZyB7ICAgICAvLwogICAgICBwYXR0ZXJuICdbYS16QS1aXVthLXpBLVowLTktX10qJyA7CiAgICB9IH0KCiAgICBsZWFmIENsYXNzTmFtZSB7IHR5cGUgc3RyaW5nIHsgICAgIC8vIENhcGl0YWxMZXR0ZXJDaGFyICwgeyBMb2NhbEROQXR0cmlidXRlVHlwZUNoYXIgfQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qJyA7CiAgICB9IH0KCiAgICBsZWFmIE5hbWluZ0F0dHJpYnV0ZU5hbWUgeyB0eXBlIHN0cmluZyB7ICAgLy8gU21hbGxMZXR0ZXJDaGFyICwgeyBMb2NhbEROQXR0cmlidXRlVHlwZUNoYXIgfQogICAgICBwYXR0ZXJuICdbYS16XVteLD0rPD4jO1xcIlxyXG4qLl0qJyA7CiAgICB9IH0KCiAgKi8KICB0eXBlZGVmIERpc3Rpbmd1aXNoZWROYW1lIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKj0oW14sPSs8PiM7XFwiXHJcbiogXXwnCiAgICAgICsgJyhcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKicKICAgICAgKyAnKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/JwogICAgICArICcoLFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSo9KFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKScKICAgICAgKyAnKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSonCiAgICAgICsgJyhbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykqJzsKICAgIH0KICAgIGRlc2NyaXB0aW9uICJSZXByZXNlbnRzIHRoZSAzR1BQIHN0YW5kYXJkIGZvciBEaXN0aW5ndWlzaGVkTmFtZS4KCiAgICAgIExpbWl0YXRpb25zOgogICAgICAtIFJETlNlcGFyYXRvcjogZG9uJ3QgYWxsb3cgU3BhY2VDaGFyIG9yIENhcnJpYWdlUmV0dXJuQ2hhcgogICAgICAtIE51bGxETjogRGlzYWxsb3cgbnVsbEROIHRoYXQgaXMgdGhlIHNhbWUgYXMgbm90IHByb3ZpZGluZyBhIEROCiAgICAgIC0gTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlIGZvcm1hdCBub3QgYWxsb3dlZAogICAgICAgIChlZy4gTWFuYWdlZEVsZW1lbnQubXlrZXk9MzQ1NDM2KSI7CiAgICByZWZlcmVuY2UgICIzR1BQIFRTIDMyLjMwMCI7CiAgfQoKICB0eXBlZGVmIFFPZmZzZXRSYW5nZSAgewogICAgdHlwZSBpbnQ4IHsKICAgICAgcmFuZ2UgIi0yNCB8IC0yMiB8IC0yMCB8IC0xOCB8IC0xNiB8IC0xNCB8IC0xMiB8IC0xMCB8IC04IHwgLTYgfCAiICsKICAgICAgICAiIC01IHwgLTQgfCAtMyB8IC0yIHwgLTEgfCAwIHwgMSB8IDIgfCAzIHwgNCB8IDUgfCA2IHwgOCB8IDEwIHwgIiArCiAgICAgICAgIiAxMiB8IDE0IHwgMTYgfCAxOCB8IDIwIHwgMjIgfCAyNCI7CiAgICB9CiAgICB1bml0cyBkQjsKICB9CgogIGdyb3VwaW5nIFJlcG9ydGluZ0N0cmwgewogICAgY2hvaWNlIHJlcG9ydGluZ0N0cmwgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgZGVzY3JpcHRpb24gIgogICAgICAgIFRoaXMgY2hvaWNlIGRlZmluZXMgdGhlIG1ldGhvZCBmb3IgcmVwb3J0aW5nIGNvbGxlY3RlZCBwZXJmb3JtYW5jZQogICAgICAgIG1ldHJpY3MgdG8gTW5TIGNvbnN1bWVycyBhcyB3ZWxsIGFzIHRoZSBwYXJhbWV0ZXJzIGZvciBjb25maWd1cmluZyB0aGUKICAgICAgICByZXBvcnRpbmcgZnVuY3Rpb24uIEl0IGlzIGEgY2hvaWNlIGJldHdlZW4gdGhlIGNvbnRyb2wgcGFyYW1ldGVyCiAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSByZXBvcnRpbmcgbWV0aG9kcywgd2hvc2UgcHJlc2VuY2Ugc2VsZWN0cyB0aGUKICAgICAgICByZXBvcnRpbmcgbWV0aG9kIGFzIGZvbGxvd3M6CgogICAgICAgIC0gV2hlbiBvbmx5IHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGF0dHJpYnV0ZSBpcyBwcmVzZW50LCB0aGUgTW5TCiAgICAgICAgcHJvZHVjZXIgc2hhbGwgc3RvcmUgZmlsZXMgb24gdGhlIE1uUyBwcm9kdWNlciBhdCBhIGxvY2F0aW9uIHNlbGVjdGVkCiAgICAgICAgYnkgdGhlIE1uUyBwcm9kdWNlciBhbmQsIG9uIGNvbmRpdGlvbiB0aGF0IGFuIGFwcHJvcHJpYXRlIHN1YnNjcmlwdGlvbgogICAgICAgIGlzIGluIHBsYWNlLCBpbmZvcm0gdGhlIE1uUyBjb25zdW1lciBhYm91dCB0aGUgYXZhaWxhYmlsaXR5IG9mIG5ldwogICAgICAgIGZpbGVzIGFuZCB0aGUgZmlsZSBsb2NhdGlvbiB1c2luZyB0aGUgbm90aWZ5RmlsZVJlYWR5IG5vdGlmaWNhdGlvbi4KICAgICAgICBJbiBjYXNlIHRoZSBwcmVwYXJhdGlvbiBvZiBhIGZpbGUgZmFpbHMsICdub3RpZnlGaWxlUHJlcGFyYXRpb25FcnJvcicKICAgICAgICBzaGFsbCBiZSBzZW50IGluc3RlYWQuCgogICAgICAgIC0gV2hlbiB0aGUgJ2ZpbGVSZXBvcnRpbmdQZXJpb2QnIGFuZCAnbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcycKICAgICAgICBhdHRyaWJ1dGVzIGFyZSBwcmVzZW50LCB0aGVuIHRoZSBNblMgcHJvZHVjZXIgc2hhbGwgYmVoYXZlIGxpa2UKICAgICAgICBkZXNjcmliZWQgZm9yIHRoZSBjYXNlIHRoYXQgb25seSB0aGUgJ2ZpbGVSZXBvcnRpbmdQZXJpb2QnIGlzIHByZXNlbnQuCiAgICAgICAgSW4gYWRkaXRpb24sIHRoZSBNblMgcHJvZHVjZXIgc2hhbGwgY3JlYXRlIG9uIGJlaGFsZiBvZiB0aGUgTW5TCiAgICAgICAgY29uc3VtZXIgYSBzdWJzY3JpcHRpb24sIHVzaW5nICdOdGZTdWJzY3JpcHRpb25Db250cm9sJywgZm9yIHRoZQogICAgICAgIG5vdGlmaWNhdGlvbiB0eXBlcyAnbm90aWZ5TU9JQ3JlYXRpb24nIGFuZCAnbm90aWZ5TU9JRGVsZXRpb24nIHJlbGF0ZWQKICAgICAgICB0byB0aGUgJ0ZpbGUnIGluc3RhbmNlcyB0aGF0IHdpbGwgYmUgcHJvZHVjZWQgbGF0ZXIuIEluIGNhc2UgYW4gZXhpc3RpbmcKICAgICAgICBzdWJzY3JpcHRpb24gZG9lcyBhbHJlYWR5IGluY2x1ZGUgdGhlICdGaWxlJyBpbnN0YW5jZXMgdG8gYmUgcHJvZHVjZWQsCiAgICAgICAgbm8gbmV3IHN1YnNjcmlwdGlvbiBzaGFsbCBiZSBjcmVhdGVkLiBUaGUKICAgICAgICAnbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcycgYXR0cmlidXRlIGluIHRoZSBjcmVhdGVkCiAgICAgICAgJ050ZlN1YnNjcmlwdGlvbkNvbnRyb2wnIGluc3RhbmNlIHNoYWxsIGJlIHNldCB0byB0aGUgdmFsdWUgb2YgdGhlCiAgICAgICAgJ25vdGlmaWNhdGlvblJlY2lwaWVudEFkZHJlc3MnIGluIHRoZSByZWxhdGVkICdQZXJmTWV0cmljSm9iJy4gVGhpcwogICAgICAgIGZlYXR1cmUgaXMgY2FsbGVkIGltcGxpY2l0IG5vdGlmaWNhdGlvbiBzdWJzY3JpcHRpb24sIGFzIG9wcG9zZWQgdG8gdGhlCiAgICAgICAgY2FzZSB3aGVyZSB0aGUgTW5TIGNvbnN1bWVyIGNyZWF0ZXMgdGhlIHN1YnNjcmlwdGlvbiAoZXhwbGljaXQKICAgICAgICBub3RpZmljYXRpb24gc3Vic2NyaXB0aW9uKS4gV2hlbiB0aGUgcmVsYXRlZCAnUGVyZk1ldHJpY0pvYicgaXMKICAgICAgICBkZWxldGVkLCB0aGUgJ050ZlN1YnNjcmlwdGlvbkNvbnRyb2wnIGluc3RhbmNlIGNyZWF0ZWQgZHVlIHRvIHRoZQogICAgICAgIHJlcXVlc3QgZm9yIGltcGxpY2l0IHN1YnNjcmlwdGlvbiBzaGFsbCBiZSBkZWxldGVkIGFzIHdlbGwuCgogICAgICAgIC0gV2hlbiBvbmx5IHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGFuZCBmaWxlTG9jYXRpb24gYXR0cmlidXRlcyBhcmUKICAgICAgICBwcmVzZW50LCB0aGUgTW5TIHByb2R1Y2VyIHNoYWxsIHN0b3JlIHRoZSBmaWxlcyBvbiBhIE1uUyBjb25zdW1lciwgdGhhdAogICAgICAgIGNhbiBiZSBhbnkgZW50aXR5IHN1Y2ggYXMgYSBmaWxlIHNlcnZlciwgYXQgdGhlIGxvY2F0aW9uIHNwZWNpZmllZCBieQogICAgICAgIGZpbGVMb2NhdGlvbi4gTm8gbm90aWZpY2F0aW9uIGlzIGVtaXR0ZWQgYnkgdGhlIE1uUyBwcm9kdWNlci4KCiAgICAgICAgLSBXaGVuIG9ubHkgdGhlIHN0cmVhbVRhcmdldCBhdHRyaWJ1dGUgaXMgcHJlc2VudCwgdGhlIE1uUyBwcm9kdWNlcgogICAgICAgIHNoYWxsIHN0cmVhbSB0aGUgZGF0YSB0byB0aGUgbG9jYXRpb24gc3BlY2lmaWVkIGJ5IHN0cmVhbVRhcmdldC4KCiAgICAgICAgRm9yIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2RzIHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGF0dHJpYnV0ZQogICAgICAgIHNwZWNpZmllcyB0aGUgdGltZSB3aW5kb3cgZHVyaW5nIHdoaWNoIGNvbGxlY3RlZCBtZWFzdXJlbWVudHMgYXJlCiAgICAgICAgc3RvcmVkIGludG8gdGhlIHNhbWUgZmlsZSBiZWZvcmUgdGhlIGZpbGUgaXMgY2xvc2VkIGFuZCBhIG5ldyBmaWxlIGlzCiAgICAgICAgb3BlbmVkLiI7CgogICAgICBjYXNlIGZpbGUtYmFzZWQtcmVwb3J0aW5nIHsKICAgICAgICBsZWFmIGZpbGVSZXBvcnRpbmdQZXJpb2QgewogICAgICAgICAgdHlwZSB1aW50MzIgewogICAgICAgICAgICByYW5nZSAxLi5tYXg7CiAgICAgICAgICB9CiAgICAgICAgICB1bml0cyBtaW51dGVzOwogICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgICBkZXNjcmlwdGlvbiAiRm9yIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2QgdGhpcyBpcyB0aGUgdGltZQogICAgICAgICAgICB3aW5kb3cgZHVyaW5nIHdoaWNoIGNvbGxlY3RlZCBtZWFzdXJlbWVudHMgYXJlIHN0b3JlZCBpbnRvIHRoZSBzYW1lCiAgICAgICAgICAgIGZpbGUgYmVmb3JlIHRoZSBmaWxlIGlzIGNsb3NlZCBhbmQgYSBuZXcgZmlsZSBpcyBvcGVuZWQuCiAgICAgICAgICAgIFRoZSB0aW1lLXBlcmlvZCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgdGhlIGdyYW51bGFyaXR5UGVyaW9kLgoKICAgICAgICAgICAgQXBwbGljYWJsZSB3aGVuIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2QgaXMgc3VwcG9ydGVkLiI7CiAgICAgICAgfQogICAgICAgIGNob2ljZSByZXBvcnRpbmctdGFyZ2V0IHsKICAgICAgICAgIGNhc2UgZmlsZS10YXJnZXQgewogICAgICAgICAgICBsZWFmIGZpbGVMb2NhdGlvbiB7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nIDsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFwcGxpY2FibGUgYW5kIG11c3QgYmUgcHJlc2VudCB3aGVuIHRoZSBmaWxlLWJhc2VkCiAgICAgICAgICAgICAgcmVwb3J0aW5nIG1ldGhvZCBpcyBzdXBwb3J0ZWQsIGFuZCB0aGUgZmlsZXMgYXJlIHN0b3JlZCBvbiB0aGUgTW5TCiAgICAgICAgICAgICAgY29uc3VtZXIuIjsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgY2FzZSBub3RpZmljYXRpb24tdGFyZ2V0IHsKICAgICAgICAgICAgbGVhZiBub3RpZmljYXRpb25SZWNpcGllbnRBZGRyZXNzIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNdXN0IGJlIHByZXNlbnQgd2hlbiB0aGUgbm90aWZpY2F0aW9uLWJhc2VkIHJlcG9ydGluZwogICAgICAgICAgICAgIG1ldGhvZCBpcyBzdXBwb3J0ZWQsIGFuZCB0aGUgdGhlIGZpbGVzIGFyZSBhdmFpbGFibGUgYXMKICAgICAgICAgICAgICBub3RpZmljYXRpb25zIGZvciB0aGUgTW5TIGNvbnN1bWVyIHRvIHN1YnNjcmliZSB0by4iOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgZGVzY3JpcHRpb24gIldoZW4gbmV0aWhlciBmaWxlTG9jYXRpb24gb3Igbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcwogICAgICAgICAgYXJlIHByZXNlbnQsIHRoZSBmaWxlcyBhcmUgc3RvcmVkIGFuZCBhdmFpbGFibGUgdG8gdGhlIE1uUyBjb25zdW1lcgogICAgICAgICAgaWYgdGhlIE1uUyBzdWJzY3JpYmVzIHRvIHRoZSBub3RpZnlGaWxlUmVhZHkgbm90aWZpY2F0aW9uLiI7CiAgICAgICAgfQogICAgICB9CgogICAgICBjYXNlIHN0cmVhbS1iYXNlZC1yZXBvcnRpbmcgewogICAgICAgIGxlYWYgc3RyZWFtVGFyZ2V0IHsKICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgICBkZXNjcmlwdGlvbiAiQXBwbGljYWJsZSB3aGVuIHN0cmVhbS1iYXNlZCByZXBvcnRpbmcgbWV0aG9kIGlzCiAgICAgICAgICAgIHN1cHBvcnRlZC4iOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQo=
+ietf-geo-location      urn:ietf:params:xml:ns:yang:ietf-geo-location   \N      []      2022-02-11      bW9kdWxlIGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjppZXRmOnBhcmFtczp4bWw6bnM6eWFuZzppZXRmLWdlby1sb2NhdGlvbiI7CiAgICBwcmVmaXggZ2VvOwogICAgaW1wb3J0IGlldGYteWFuZy10eXBlcyB7CiAgICBwcmVmaXggeWFuZzsKICAgIHJlZmVyZW5jZSAiUkZDIDY5OTE6IENvbW1vbiBZQU5HIERhdGEgVHlwZXMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbgogICAgIklFVEYgTkVUTU9EIFdvcmtpbmcgR3JvdXAgKE5FVE1PRCkiOwogICAgY29udGFjdAogICAgIldHIFdlYjogICA8aHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy93Zy9uZXRtb2QvPgogICAgV0cgTGlzdDogIDxtYWlsdG86bmV0bW9kQGlldGYub3JnPgoKICAgIEVkaXRvcjogICBDaHJpc3RpYW4gSG9wcHMKICAgICAgICAgICAgICAgIDxtYWlsdG86Y2hvcHBzQGNob3Bwcy5vcmc+IjsKCiAgICBkZXNjcmlwdGlvbgogICAgIlRoaXMgbW9kdWxlIGRlZmluZXMgYSBncm91cGluZyBvZiBhIGNvbnRhaW5lciBvYmplY3QgZm9yCiAgICBzcGVjaWZ5aW5nIGEgbG9jYXRpb24gb24gb3IgYXJvdW5kIGFuIGFzdHJvbm9taWNhbCBvYmplY3QgKGUuZy4sCiAgICAnZWFydGgnKS4KCiAgICBUaGUga2V5IHdvcmRzICdNVVNUJywgJ01VU1QgTk9UJywgJ1JFUVVJUkVEJywgJ1NIQUxMJywgJ1NIQUxMCiAgICBOT1QnLCAnU0hPVUxEJywgJ1NIT1VMRCBOT1QnLCAnUkVDT01NRU5ERUQnLCAnTk9UIFJFQ09NTUVOREVEJywKICAgICdNQVknLCBhbmQgJ09QVElPTkFMJyBpbiB0aGlzIGRvY3VtZW50IGFyZSB0byBiZSBpbnRlcnByZXRlZCBhcwogICAgZGVzY3JpYmVkIGluIEJDUCAxNCAoUkZDIDIxMTkpIChSRkMgODE3NCkgd2hlbiwgYW5kIG9ubHkgd2hlbiwKICAgIHRoZXkgYXBwZWFyIGluIGFsbCBjYXBpdGFscywgYXMgc2hvd24gaGVyZS4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjIgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3JtcywKICAgIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywKICAgIGFuZCBzdWJqZWN0IHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlCiAgICBSZXZpc2VkIEJTRCBMaWNlbnNlIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUKICAgIElFVEYgVHJ1c3QncyBMZWdhbCBQcm92aXNpb25zIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cHM6Ly90cnVzdGVlLmlldGYub3JnL2xpY2Vuc2UtaW5mbykuCgogICAgVGhpcyB2ZXJzaW9uIG9mIHRoaXMgWUFORyBtb2R1bGUgaXMgcGFydCBvZiBSRkMgOTE3OQogICAgKGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL2luZm8vcmZjOTE3OSk7IHNlZSB0aGUgUkZDIGl0c2VsZgogICAgZm9yIGZ1bGwgbGVnYWwgbm90aWNlcy4iOwoKICAgIHJldmlzaW9uIDIwMjItMDItMTEgewogICAgZGVzY3JpcHRpb24KICAgICAgICAiSW5pdGlhbCBSZXZpc2lvbiI7CiAgICByZWZlcmVuY2UKICAgICAgICAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIGZlYXR1cmUgYWx0ZXJuYXRlLXN5c3RlbXMgewogICAgZGVzY3JpcHRpb24KICAgICAgICAiVGhpcyBmZWF0dXJlIG1lYW5zIHRoZSBkZXZpY2Ugc3VwcG9ydHMgc3BlY2lmeWluZyBsb2NhdGlvbnMKICAgICAgICB1c2luZyBhbHRlcm5hdGUgc3lzdGVtcyBmb3IgcmVmZXJlbmNlIGZyYW1lcy4iOwogICAgfQoKICAgIGdyb3VwaW5nIGdlby1sb2NhdGlvbiB7CiAgICBkZXNjcmlwdGlvbgogICAgICAgICJHcm91cGluZyB0byBpZGVudGlmeSBhIGxvY2F0aW9uIG9uIGFuIGFzdHJvbm9taWNhbCBvYmplY3QuIjsKCiAgICBjb250YWluZXIgZ2VvLWxvY2F0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICJBIGxvY2F0aW9uIG9uIGFuIGFzdHJvbm9taWNhbCBib2R5IChlLmcuLCAnZWFydGgnKQogICAgICAgIHNvbWV3aGVyZSBpbiBhIHVuaXZlcnNlLiI7CgogICAgICAgIGNvbnRhaW5lciByZWZlcmVuY2UtZnJhbWUgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgRnJhbWUgb2YgUmVmZXJlbmNlIGZvciB0aGUgbG9jYXRpb24gdmFsdWVzLiI7CgogICAgICAgIGxlYWYgYWx0ZXJuYXRlLXN5c3RlbSB7CiAgICAgICAgICAgIGlmLWZlYXR1cmUgImFsdGVybmF0ZS1zeXN0ZW1zIjsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgc3lzdGVtIGluIHdoaWNoIHRoZSBhc3Ryb25vbWljYWwgYm9keSBhbmQKICAgICAgICAgICAgZ2VvZGV0aWMtZGF0dW0gaXMgZGVmaW5lZC4gIE5vcm1hbGx5LCB0aGlzIHZhbHVlIGlzIG5vdAogICAgICAgICAgICBwcmVzZW50IGFuZCB0aGUgc3lzdGVtIGlzIHRoZSBuYXR1cmFsIHVuaXZlcnNlOyBob3dldmVyLAogICAgICAgICAgICB3aGVuIHByZXNlbnQsIHRoaXMgdmFsdWUgYWxsb3dzIGZvciBzcGVjaWZ5aW5nIGFsdGVybmF0ZQogICAgICAgICAgICBzeXN0ZW1zIChlLmcuLCB2aXJ0dWFsIHJlYWxpdGllcykuICBBbiBhbHRlcm5hdGUtc3lzdGVtCiAgICAgICAgICAgIG1vZGlmaWVzIHRoZSBkZWZpbml0aW9uIChidXQgbm90IHRoZSB0eXBlKSBvZiB0aGUgb3RoZXIKICAgICAgICAgICAgdmFsdWVzIGluIHRoZSByZWZlcmVuY2UgZnJhbWUuIjsKICAgICAgICB9CiAgICAgICAgbGVhZiBhc3Ryb25vbWljYWwtYm9keSB7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICAgICAgcGF0dGVybiAnWyAtQFxbLVxeXy1+XSonOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQgImVhcnRoIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIkFuIGFzdHJvbm9taWNhbCBib2R5IGFzIG5hbWVkIGJ5IHRoZSBJbnRlcm5hdGlvbmFsCiAgICAgICAgICAgIEFzdHJvbm9taWNhbCBVbmlvbiAoSUFVKSBvciBhY2NvcmRpbmcgdG8gdGhlIGFsdGVybmF0ZQogICAgICAgICAgICBzeXN0ZW0gaWYgc3BlY2lmaWVkLiAgRXhhbXBsZXMgaW5jbHVkZSAnc3VuJyAob3VyIHN0YXIpLAogICAgICAgICAgICAnZWFydGgnIChvdXIgcGxhbmV0KSwgJ21vb24nIChvdXIgbW9vbiksICdlbmNlbGFkdXMnIChhCiAgICAgICAgICAgIG1vb24gb2YgU2F0dXJuKSwgJ2NlcmVzJyAoYW4gYXN0ZXJvaWQpLCBhbmQKICAgICAgICAgICAgJzY3cC9jaHVyeXVtb3YtZ2VyYXNpbWVua28gKGEgY29tZXQpLiAgVGhlIEFTQ0lJIHZhbHVlCiAgICAgICAgICAgIFNIT1VMRCBoYXZlIHVwcGVyY2FzZSBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlIGFuZCBub3QKICAgICAgICAgICAgaW5jbHVkZSBjb250cm9sIGNoYXJhY3RlcnMgKGkuZS4sIHZhbHVlcyAzMi4uNjQsIGFuZAogICAgICAgICAgICA5MS4uMTI2KS4gIEFueSBwcmVjZWRpbmcgJ3RoZScgaW4gdGhlIG5hbWUgU0hPVUxEIE5PVCBiZQogICAgICAgICAgICBpbmNsdWRlZC4iOwogICAgICAgICAgICByZWZlcmVuY2UKICAgICAgICAgICAgImh0dHBzOi8vd3d3LmlhdS5vcmcvIjsKICAgICAgICB9CiAgICAgICAgY29udGFpbmVyIGdlb2RldGljLXN5c3RlbSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgZ2VvZGV0aWMgc3lzdGVtIG9mIHRoZSBsb2NhdGlvbiBkYXRhLiI7CiAgICAgICAgICAgIGxlYWYgZ2VvZGV0aWMtZGF0dW0gewogICAgICAgICAgICB0eXBlIHN0cmluZyB7CiAgICAgICAgICAgICAgICBwYXR0ZXJuICdbIC1AXFstXF5fLX5dKic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJBIGdlb2RldGljLWRhdHVtIGRlZmluaW5nIHRoZSBtZWFuaW5nIG9mIGxhdGl0dWRlLAogICAgICAgICAgICAgICAgbG9uZ2l0dWRlLCBhbmQgaGVpZ2h0LiAgVGhlIGRlZmF1bHQgd2hlbiB0aGUKICAgICAgICAgICAgICAgIGFzdHJvbm9taWNhbCBib2R5IGlzICdlYXJ0aCcgaXMgJ3dncy04NCcsIHdoaWNoIGlzCiAgICAgICAgICAgICAgICB1c2VkIGJ5IHRoZSBHbG9iYWwgUG9zaXRpb25pbmcgU3lzdGVtIChHUFMpLiAgVGhlCiAgICAgICAgICAgICAgICBBU0NJSSB2YWx1ZSBTSE9VTEQgaGF2ZSB1cHBlcmNhc2UgY29udmVydGVkIHRvCiAgICAgICAgICAgICAgICBsb3dlcmNhc2UgYW5kIG5vdCBpbmNsdWRlIGNvbnRyb2wgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgKGkuZS4sIHZhbHVlcyAzMi4uNjQsIGFuZCA5MS4uMTI2KS4gIFRoZSBJQU5BIHJlZ2lzdHJ5CiAgICAgICAgICAgICAgICBmdXJ0aGVyIHJlc3RyaWN0cyB0aGUgdmFsdWUgYnkgY29udmVydGluZyBhbGwgc3BhY2VzCiAgICAgICAgICAgICAgICAoJyAnKSB0byBkYXNoZXMgKCctJykuCiAgICAgICAgICAgICAgICBUaGUgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIGdlb2RldGljLWRhdHVtIGluZGljYXRlcwogICAgICAgICAgICAgICAgaG93IGFjY3VyYXRlbHkgaXQgbW9kZWxzIHRoZSBhc3Ryb25vbWljYWwgYm9keSBpbgogICAgICAgICAgICAgICAgcXVlc3Rpb24sIGJvdGggZm9yIHRoZSAnaG9yaXpvbnRhbCcKICAgICAgICAgICAgICAgIGxhdGl0dWRlL2xvbmdpdHVkZSBjb29yZGluYXRlcyBhbmQgZm9yIGhlaWdodAogICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMuIjsKICAgICAgICAgICAgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMsCiAgICAgICAgICAgICAgICBTZWN0aW9uIDYuMSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGVhZiBjb29yZC1hY2N1cmFjeSB7CiAgICAgICAgICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyA2OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGFjY3VyYWN5IG9mIHRoZSBsYXRpdHVkZS9sb25naXR1ZGUgcGFpciBmb3IKICAgICAgICAgICAgICAgIGVsbGlwc29pZGFsIGNvb3JkaW5hdGVzLCBvciB0aGUgWCwgWSwgYW5kIFogY29tcG9uZW50cwogICAgICAgICAgICAgICAgZm9yIENhcnRlc2lhbiBjb29yZGluYXRlcy4gIFdoZW4gY29vcmQtYWNjdXJhY3kgaXMKICAgICAgICAgICAgICAgIHNwZWNpZmllZCwgaXQgaW5kaWNhdGVzIGhvdyBwcmVjaXNlbHkgdGhlIGNvb3JkaW5hdGVzCiAgICAgICAgICAgICAgICBpbiB0aGUgYXNzb2NpYXRlZCBsaXN0IG9mIGxvY2F0aW9ucyBoYXZlIGJlZW4KICAgICAgICAgICAgICAgIGRldGVybWluZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBjb29yZGluYXRlIHN5c3RlbQogICAgICAgICAgICAgICAgZGVmaW5lZCBieSB0aGUgZ2VvZGV0aWMtZGF0dW0uICBGb3IgZXhhbXBsZSwgdGhlcmUKICAgICAgICAgICAgICAgIG1pZ2h0IGJlIHVuY2VydGFpbnR5IGR1ZSB0byBtZWFzdXJlbWVudCBlcnJvciBpZiBhbgogICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsIG1lYXN1cmVtZW50IHdhcyBtYWRlIHRvIGRldGVybWluZSBlYWNoCiAgICAgICAgICAgICAgICBsb2NhdGlvbi4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlYWYgaGVpZ2h0LWFjY3VyYWN5IHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGFjY3VyYWN5IG9mIHRoZSBoZWlnaHQgdmFsdWUgZm9yIGVsbGlwc29pZGFsCiAgICAgICAgICAgICAgICBjb29yZGluYXRlczsgdGhpcyB2YWx1ZSBpcyBub3QgdXNlZCB3aXRoIENhcnRlc2lhbgogICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMuICBXaGVuIGhlaWdodC1hY2N1cmFjeSBpcyBzcGVjaWZpZWQsIGl0CiAgICAgICAgICAgICAgICBpbmRpY2F0ZXMgaG93IHByZWNpc2VseSB0aGUgaGVpZ2h0cyBpbiB0aGUKICAgICAgICAgICAgICAgIGFzc29jaWF0ZWQgbGlzdCBvZiBsb2NhdGlvbnMgaGF2ZSBiZWVuIGRldGVybWluZWQKICAgICAgICAgICAgICAgIHdpdGggcmVzcGVjdCB0byB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0gZGVmaW5lZCBieSB0aGUKICAgICAgICAgICAgICAgIGdlb2RldGljLWRhdHVtLiAgRm9yIGV4YW1wbGUsIHRoZXJlIG1pZ2h0IGJlCiAgICAgICAgICAgICAgICB1bmNlcnRhaW50eSBkdWUgdG8gbWVhc3VyZW1lbnQgZXJyb3IgaWYgYW4KICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbCBtZWFzdXJlbWVudCB3YXMgbWFkZSB0byBkZXRlcm1pbmUgZWFjaAogICAgICAgICAgICAgICAgbG9jYXRpb24uIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2hvaWNlIGxvY2F0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhlIGxvY2F0aW9uIGRhdGEgZWl0aGVyIGluIGxhdGl0dWRlL2xvbmdpdHVkZSBvcgogICAgICAgICAgICBDYXJ0ZXNpYW4gdmFsdWVzIjsKICAgICAgICBjYXNlIGVsbGlwc29pZCB7CiAgICAgICAgICAgIGxlYWYgbGF0aXR1ZGUgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgImRlY2ltYWwgZGVncmVlcyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGxhdGl0dWRlIHZhbHVlIG9uIHRoZSBhc3Ryb25vbWljYWwgYm9keS4gIFRoZQogICAgICAgICAgICAgICAgZGVmaW5pdGlvbiBhbmQgcHJlY2lzaW9uIG9mIHRoaXMgbWVhc3VyZW1lbnQgaXMKICAgICAgICAgICAgICAgIGluZGljYXRlZCBieSB0aGUgcmVmZXJlbmNlLWZyYW1lLiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGVhZiBsb25naXR1ZGUgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgImRlY2ltYWwgZGVncmVlcyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGxvbmdpdHVkZSB2YWx1ZSBvbiB0aGUgYXN0cm9ub21pY2FsIGJvZHkuICBUaGUKICAgICAgICAgICAgICAgIGRlZmluaXRpb24gYW5kIHByZWNpc2lvbiBvZiB0aGlzIG1lYXN1cmVtZW50IGlzCiAgICAgICAgICAgICAgICBpbmRpY2F0ZWQgYnkgdGhlIHJlZmVyZW5jZS1mcmFtZS4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlYWYgaGVpZ2h0IHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiSGVpZ2h0IGZyb20gYSByZWZlcmVuY2UgMCB2YWx1ZS4gIFRoZSBwcmVjaXNpb24gYW5kCiAgICAgICAgICAgICAgICAnMCcgdmFsdWUgaXMgZGVmaW5lZCBieSB0aGUgcmVmZXJlbmNlLWZyYW1lLiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2FzZSBjYXJ0ZXNpYW4gewogICAgICAgICAgICBsZWFmIHggewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWCB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWFmIHkgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWSB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWFmIHogewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWiB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29udGFpbmVyIHZlbG9jaXR5IHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiSWYgdGhlIG9iamVjdCBpcyBpbiBtb3Rpb24sIHRoZSB2ZWxvY2l0eSB2ZWN0b3IgZGVzY3JpYmVzCiAgICAgICAgICAgIHRoaXMgbW90aW9uIGF0IHRoZSB0aW1lIGdpdmVuIGJ5IHRoZSB0aW1lc3RhbXAuICBGb3IgYQogICAgICAgICAgICBmb3JtdWxhIHRvIGNvbnZlcnQgdGhlc2UgdmFsdWVzIHRvIHNwZWVkIGFuZCBoZWFkaW5nLCBzZWUKICAgICAgICAgICAgUkZDIDkxNzkuIjsKICAgICAgICByZWZlcmVuY2UKICAgICAgICAgICAgIlJGQyA5MTc5OiBBIFlBTkcgR3JvdXBpbmcgZm9yIEdlb2dyYXBoaWMgTG9jYXRpb25zIjsKCiAgICAgICAgbGVhZiB2LW5vcnRoIHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyBwZXIgc2Vjb25kIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgInYtbm9ydGggaXMgdGhlIHJhdGUgb2YgY2hhbmdlIChpLmUuLCBzcGVlZCkgdG93YXJkcwogICAgICAgICAgICB0cnVlIG5vcnRoIGFzIGRlZmluZWQgYnkgdGhlIGdlb2RldGljLXN5c3RlbS4iOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB2LWVhc3QgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyAxMjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIHBlciBzZWNvbmQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAidi1lYXN0IGlzIHRoZSByYXRlIG9mIGNoYW5nZSAoaS5lLiwgc3BlZWQpIHBlcnBlbmRpY3VsYXIKICAgICAgICAgICAgdG8gdGhlIHJpZ2h0IG9mIHRydWUgbm9ydGggYXMgZGVmaW5lZCBieQogICAgICAgICAgICB0aGUgZ2VvZGV0aWMtc3lzdGVtLiI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHYtdXAgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyAxMjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIHBlciBzZWNvbmQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAidi11cCBpcyB0aGUgcmF0ZSBvZiBjaGFuZ2UgKGkuZS4sIHNwZWVkKSBhd2F5IGZyb20gdGhlCiAgICAgICAgICAgIGNlbnRlciBvZiBtYXNzLiI7CiAgICAgICAgfQogICAgICAgIH0KICAgICAgICBsZWFmIHRpbWVzdGFtcCB7CiAgICAgICAgdHlwZSB5YW5nOmRhdGUtYW5kLXRpbWU7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIlJlZmVyZW5jZSB0aW1lIHdoZW4gbG9jYXRpb24gd2FzIHJlY29yZGVkLiI7CiAgICAgICAgfQogICAgICAgIGxlYWYgdmFsaWQtdW50aWwgewogICAgICAgIHR5cGUgeWFuZzpkYXRlLWFuZC10aW1lOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgdGltZXN0YW1wIGZvciB3aGljaCB0aGlzIGdlby1sb2NhdGlvbiBpcyB2YWxpZCB1bnRpbC4KICAgICAgICAgICAgSWYgdW5zcGVjaWZpZWQsIHRoZSBnZW8tbG9jYXRpb24gaGFzIG5vIHNwZWNpZmljCiAgICAgICAgICAgIGV4cGlyYXRpb24gdGltZS4iOwogICAgICAgIH0KICAgIH0KICAgIH0KfQo=
+ietf-inet-types        urn:ietf:params:xml:ns:yang:ietf-inet-types     \N      []      2013-07-15      bW9kdWxlIGlldGYtaW5ldC10eXBlcyB7CgogIG5hbWVzcGFjZSAidXJuOmlldGY6cGFyYW1zOnhtbDpuczp5YW5nOmlldGYtaW5ldC10eXBlcyI7CiAgcHJlZml4ICJpbmV0IjsKCiAgb3JnYW5pemF0aW9uCiAgICJJRVRGIE5FVE1PRCAoTkVUQ09ORiBEYXRhIE1vZGVsaW5nIExhbmd1YWdlKSBXb3JraW5nIEdyb3VwIjsKCiAgY29udGFjdAogICAiV0cgV2ViOiAgIDxodHRwOi8vdG9vbHMuaWV0Zi5vcmcvd2cvbmV0bW9kLz4KICAgIFdHIExpc3Q6ICA8bWFpbHRvOm5ldG1vZEBpZXRmLm9yZz4KCiAgICBXRyBDaGFpcjogRGF2aWQgS2Vzc2VucwogICAgICAgICAgICAgIDxtYWlsdG86ZGF2aWQua2Vzc2Vuc0Buc24uY29tPgoKICAgIFdHIENoYWlyOiBKdWVyZ2VuIFNjaG9lbndhZWxkZXIKICAgICAgICAgICAgICA8bWFpbHRvOmouc2Nob2Vud2FlbGRlckBqYWNvYnMtdW5pdmVyc2l0eS5kZT4KCiAgICBFZGl0b3I6ICAgSnVlcmdlbiBTY2hvZW53YWVsZGVyCiAgICAgICAgICAgICAgPG1haWx0bzpqLnNjaG9lbndhZWxkZXJAamFjb2JzLXVuaXZlcnNpdHkuZGU+IjsKCiAgZGVzY3JpcHRpb24KICAgIlRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgY29sbGVjdGlvbiBvZiBnZW5lcmFsbHkgdXNlZnVsIGRlcml2ZWQKICAgIFlBTkcgZGF0YSB0eXBlcyBmb3IgSW50ZXJuZXQgYWRkcmVzc2VzIGFuZCByZWxhdGVkIHRoaW5ncy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTMgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvcgogICAgd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywgYW5kIHN1YmplY3QKICAgIHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlIFNpbXBsaWZpZWQgQlNEIExpY2Vuc2UKICAgIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUgSUVURiBUcnVzdCdzIExlZ2FsIFByb3Zpc2lvbnMKICAgIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cDovL3RydXN0ZWUuaWV0Zi5vcmcvbGljZW5zZS1pbmZvKS4KCiAgICBUaGlzIHZlcnNpb24gb2YgdGhpcyBZQU5HIG1vZHVsZSBpcyBwYXJ0IG9mIFJGQyA2OTkxOyBzZWUKICAgIHRoZSBSRkMgaXRzZWxmIGZvciBmdWxsIGxlZ2FsIG5vdGljZXMuIjsKCiAgcmV2aXNpb24gMjAxMy0wNy0xNSB7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHJldmlzaW9uIGFkZHMgdGhlIGZvbGxvd2luZyBuZXcgZGF0YSB0eXBlczoKICAgICAgLSBpcC1hZGRyZXNzLW5vLXpvbmUKICAgICAgLSBpcHY0LWFkZHJlc3Mtbm8tem9uZQogICAgICAtIGlwdjYtYWRkcmVzcy1uby16b25lIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjk5MTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICByZXZpc2lvbiAyMDEwLTA5LTI0IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgIkluaXRpYWwgcmV2aXNpb24uIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjAyMTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgdHlwZXMgcmVsYXRlZCB0byBwcm90b2NvbCBmaWVsZHMgKioqLwoKICB0eXBlZGVmIGlwLXZlcnNpb24gewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gdW5rbm93biB7CiAgICAgICAgdmFsdWUgIjAiOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICJBbiB1bmtub3duIG9yIHVuc3BlY2lmaWVkIHZlcnNpb24gb2YgdGhlIEludGVybmV0CiAgICAgICAgICBwcm90b2NvbC4iOwogICAgICB9CiAgICAgIGVudW0gaXB2NCB7CiAgICAgICAgdmFsdWUgIjEiOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICJUaGUgSVB2NCBwcm90b2NvbCBhcyBkZWZpbmVkIGluIFJGQyA3OTEuIjsKICAgICAgfQogICAgICBlbnVtIGlwdjYgewogICAgICAgIHZhbHVlICIyIjsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAiVGhlIElQdjYgcHJvdG9jb2wgYXMgZGVmaW5lZCBpbiBSRkMgMjQ2MC4iOwogICAgICB9CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHZhbHVlIHJlcHJlc2VudHMgdGhlIHZlcnNpb24gb2YgdGhlIElQIHByb3RvY29sLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIEluZXRWZXJzaW9uIHRleHR1YWwgY29udmVudGlvbiBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgIDc5MTogSW50ZXJuZXQgUHJvdG9jb2wKICAgICAgUkZDIDI0NjA6IEludGVybmV0IFByb3RvY29sLCBWZXJzaW9uIDYgKElQdjYpIFNwZWNpZmljYXRpb24KICAgICAgUkZDIDQwMDE6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIEludGVybmV0IE5ldHdvcmsgQWRkcmVzc2VzIjsKICB9CgogIHR5cGVkZWYgZHNjcCB7CiAgICB0eXBlIHVpbnQ4IHsKICAgICAgcmFuZ2UgIjAuLjYzIjsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBkc2NwIHR5cGUgcmVwcmVzZW50cyBhIERpZmZlcmVudGlhdGVkIFNlcnZpY2VzIENvZGUgUG9pbnQKICAgICAgdGhhdCBtYXkgYmUgdXNlZCBmb3IgbWFya2luZyBwYWNrZXRzIGluIGEgdHJhZmZpYyBzdHJlYW0uCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBEc2NwIHRleHR1YWwgY29udmVudGlvbiBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzI4OTogTWFuYWdlbWVudCBJbmZvcm1hdGlvbiBCYXNlIGZvciB0aGUgRGlmZmVyZW50aWF0ZWQKICAgICAgICAgICAgICAgIFNlcnZpY2VzIEFyY2hpdGVjdHVyZQogICAgICBSRkMgMjQ3NDogRGVmaW5pdGlvbiBvZiB0aGUgRGlmZmVyZW50aWF0ZWQgU2VydmljZXMgRmllbGQKICAgICAgICAgICAgICAgIChEUyBGaWVsZCkgaW4gdGhlIElQdjQgYW5kIElQdjYgSGVhZGVycwogICAgICBSRkMgMjc4MDogSUFOQSBBbGxvY2F0aW9uIEd1aWRlbGluZXMgRm9yIFZhbHVlcyBJbgogICAgICAgICAgICAgICAgdGhlIEludGVybmV0IFByb3RvY29sIGFuZCBSZWxhdGVkIEhlYWRlcnMiOwogIH0KCiAgdHlwZWRlZiBpcHY2LWZsb3ctbGFiZWwgewogICAgdHlwZSB1aW50MzIgewogICAgICByYW5nZSAiMC4uMTA0ODU3NSI7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXB2Ni1mbG93LWxhYmVsIHR5cGUgcmVwcmVzZW50cyB0aGUgZmxvdyBpZGVudGlmaWVyIG9yIEZsb3cKICAgICAgTGFiZWwgaW4gYW4gSVB2NiBwYWNrZXQgaGVhZGVyIHRoYXQgbWF5IGJlIHVzZWQgdG8KICAgICAgZGlzY3JpbWluYXRlIHRyYWZmaWMgZmxvd3MuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgSVB2NkZsb3dMYWJlbCB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDM1OTU6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIElQdjYgRmxvdyBMYWJlbAogICAgICBSRkMgMjQ2MDogSW50ZXJuZXQgUHJvdG9jb2wsIFZlcnNpb24gNiAoSVB2NikgU3BlY2lmaWNhdGlvbiI7CiAgfQoKICB0eXBlZGVmIHBvcnQtbnVtYmVyIHsKICAgIHR5cGUgdWludDE2IHsKICAgICAgcmFuZ2UgIjAuLjY1NTM1IjsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBwb3J0LW51bWJlciB0eXBlIHJlcHJlc2VudHMgYSAxNi1iaXQgcG9ydCBudW1iZXIgb2YgYW4KICAgICAgSW50ZXJuZXQgdHJhbnNwb3J0LWxheWVyIHByb3RvY29sIHN1Y2ggYXMgVURQLCBUQ1AsIERDQ1AsIG9yCiAgICAgIFNDVFAuICBQb3J0IG51bWJlcnMgYXJlIGFzc2lnbmVkIGJ5IElBTkEuICBBIGN1cnJlbnQgbGlzdCBvZgogICAgICBhbGwgYXNzaWdubWVudHMgaXMgYXZhaWxhYmxlIGZyb20gPGh0dHA6Ly93d3cuaWFuYS5vcmcvPi4KCiAgICAgIE5vdGUgdGhhdCB0aGUgcG9ydCBudW1iZXIgdmFsdWUgemVybyBpcyByZXNlcnZlZCBieSBJQU5BLiAgSW4KICAgICAgc2l0dWF0aW9ucyB3aGVyZSB0aGUgdmFsdWUgemVybyBkb2VzIG5vdCBtYWtlIHNlbnNlLCBpdCBjYW4KICAgICAgYmUgZXhjbHVkZWQgYnkgc3VidHlwaW5nIHRoZSBwb3J0LW51bWJlciB0eXBlLgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgSW5ldFBvcnROdW1iZXIgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAgNzY4OiBVc2VyIERhdGFncmFtIFByb3RvY29sCiAgICAgIFJGQyAgNzkzOiBUcmFuc21pc3Npb24gQ29udHJvbCBQcm90b2NvbAogICAgICBSRkMgNDk2MDogU3RyZWFtIENvbnRyb2wgVHJhbnNtaXNzaW9uIFByb3RvY29sCiAgICAgIFJGQyA0MzQwOiBEYXRhZ3JhbSBDb25nZXN0aW9uIENvbnRyb2wgUHJvdG9jb2wgKERDQ1ApCiAgICAgIFJGQyA0MDAxOiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBJbnRlcm5ldCBOZXR3b3JrIEFkZHJlc3NlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgdHlwZXMgcmVsYXRlZCB0byBhdXRvbm9tb3VzIHN5c3RlbXMgKioqLwoKICB0eXBlZGVmIGFzLW51bWJlciB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBhcy1udW1iZXIgdHlwZSByZXByZXNlbnRzIGF1dG9ub21vdXMgc3lzdGVtIG51bWJlcnMKICAgICAgd2hpY2ggaWRlbnRpZnkgYW4gQXV0b25vbW91cyBTeXN0ZW0gKEFTKS4gIEFuIEFTIGlzIGEgc2V0CiAgICAgIG9mIHJvdXRlcnMgdW5kZXIgYSBzaW5nbGUgdGVjaG5pY2FsIGFkbWluaXN0cmF0aW9uLCB1c2luZwogICAgICBhbiBpbnRlcmlvciBnYXRld2F5IHByb3RvY29sIGFuZCBjb21tb24gbWV0cmljcyB0byByb3V0ZQogICAgICBwYWNrZXRzIHdpdGhpbiB0aGUgQVMsIGFuZCB1c2luZyBhbiBleHRlcmlvciBnYXRld2F5CiAgICAgIHByb3RvY29sIHRvIHJvdXRlIHBhY2tldHMgdG8gb3RoZXIgQVNlcy4gIElBTkEgbWFpbnRhaW5zCiAgICAgIHRoZSBBUyBudW1iZXIgc3BhY2UgYW5kIGhhcyBkZWxlZ2F0ZWQgbGFyZ2UgcGFydHMgdG8gdGhlCiAgICAgIHJlZ2lvbmFsIHJlZ2lzdHJpZXMuCgogICAgICBBdXRvbm9tb3VzIHN5c3RlbSBudW1iZXJzIHdlcmUgb3JpZ2luYWxseSBsaW1pdGVkIHRvIDE2CiAgICAgIGJpdHMuICBCR1AgZXh0ZW5zaW9ucyBoYXZlIGVubGFyZ2VkIHRoZSBhdXRvbm9tb3VzIHN5c3RlbQogICAgICBudW1iZXIgc3BhY2UgdG8gMzIgYml0cy4gIFRoaXMgdHlwZSB0aGVyZWZvcmUgdXNlcyBhbiB1aW50MzIKICAgICAgYmFzZSB0eXBlIHdpdGhvdXQgYSByYW5nZSByZXN0cmljdGlvbiBpbiBvcmRlciB0byBzdXBwb3J0CiAgICAgIGEgbGFyZ2VyIGF1dG9ub21vdXMgc3lzdGVtIG51bWJlciBzcGFjZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBJbmV0QXV0b25vbW91c1N5c3RlbU51bWJlciB0ZXh0dWFsIGNvbnZlbnRpb24gb2YKICAgICAgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDE5MzA6IEd1aWRlbGluZXMgZm9yIGNyZWF0aW9uLCBzZWxlY3Rpb24sIGFuZCByZWdpc3RyYXRpb24KICAgICAgICAgICAgICAgIG9mIGFuIEF1dG9ub21vdXMgU3lzdGVtIChBUykKICAgICAgUkZDIDQyNzE6IEEgQm9yZGVyIEdhdGV3YXkgUHJvdG9jb2wgNCAoQkdQLTQpCiAgICAgIFJGQyA0MDAxOiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBJbnRlcm5ldCBOZXR3b3JrIEFkZHJlc3NlcwogICAgICBSRkMgNjc5MzogQkdQIFN1cHBvcnQgZm9yIEZvdXItT2N0ZXQgQXV0b25vbW91cyBTeXN0ZW0gKEFTKQogICAgICAgICAgICAgICAgTnVtYmVyIFNwYWNlIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiB0eXBlcyByZWxhdGVkIHRvIElQIGFkZHJlc3NlcyBhbmQgaG9zdG5hbWVzICoqKi8KCiAgdHlwZWRlZiBpcC1hZGRyZXNzIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzOwogICAgICB0eXBlIGluZXQ6aXB2Ni1hZGRyZXNzOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGlwLWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQIGFkZHJlc3MgYW5kIGlzIElQCiAgICAgIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24KICAgICAgaW1wbGllcyB0aGUgSVAgdmVyc2lvbi4gIFRoaXMgdHlwZSBzdXBwb3J0cyBzY29wZWQgYWRkcmVzc2VzCiAgICAgIGJ5IGFsbG93aW5nIHpvbmUgaWRlbnRpZmllcnMgaW4gdGhlIGFkZHJlc3MgZm9ybWF0LiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDQwMDc6IElQdjYgU2NvcGVkIEFkZHJlc3MgQXJjaGl0ZWN0dXJlIjsKICB9CgogIHR5cGVkZWYgaXB2NC1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybgogICAgICAgICcoKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcLil7M30nCiAgICAgICsgICcoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKScKICAgICAgKyAnKCVbXHB7Tn1ccHtMfV0rKT8nOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIlRoZSBpcHY0LWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQdjQgYWRkcmVzcyBpbgogICAgICAgZG90dGVkLXF1YWQgbm90YXRpb24uICBUaGUgSVB2NCBhZGRyZXNzIG1heSBpbmNsdWRlIGEgem9uZQogICAgICAgaW5kZXgsIHNlcGFyYXRlZCBieSBhICUgc2lnbi4KCiAgICAgICBUaGUgem9uZSBpbmRleCBpcyB1c2VkIHRvIGRpc2FtYmlndWF0ZSBpZGVudGljYWwgYWRkcmVzcwogICAgICAgdmFsdWVzLiAgRm9yIGxpbmstbG9jYWwgYWRkcmVzc2VzLCB0aGUgem9uZSBpbmRleCB3aWxsCiAgICAgICB0eXBpY2FsbHkgYmUgdGhlIGludGVyZmFjZSBpbmRleCBudW1iZXIgb3IgdGhlIG5hbWUgb2YgYW4KICAgICAgIGludGVyZmFjZS4gIElmIHRoZSB6b25lIGluZGV4IGlzIG5vdCBwcmVzZW50LCB0aGUgZGVmYXVsdAogICAgICAgem9uZSBvZiB0aGUgZGV2aWNlIHdpbGwgYmUgdXNlZC4KCiAgICAgICBUaGUgY2Fub25pY2FsIGZvcm1hdCBmb3IgdGhlIHpvbmUgaW5kZXggaXMgdGhlIG51bWVyaWNhbAogICAgICAgZm9ybWF0IjsKICB9CgogIHR5cGVkZWYgaXB2Ni1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKCg6fFswLTlhLWZBLUZdezAsNH0pOikoWzAtOWEtZkEtRl17MCw0fTopezAsNX0nCiAgICAgICAgICAgICsgJygoKFswLTlhLWZBLUZdezAsNH06KT8oOnxbMC05YS1mQS1GXXswLDR9KSl8JwogICAgICAgICAgICArICcoKCgyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV0/WzAtOV0pXC4pezN9JwogICAgICAgICAgICArICcoMjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldP1swLTldKSkpJwogICAgICAgICAgICArICcoJVtccHtOfVxwe0x9XSspPyc7CiAgICAgIHBhdHRlcm4gJygoW146XSs6KXs2fSgoW146XSs6W146XSspfCguKlwuLiopKSl8JwogICAgICAgICAgICArICcoKChbXjpdKzopKlteOl0rKT86OigoW146XSs6KSpbXjpdKyk/KScKICAgICAgICAgICAgKyAnKCUuKyk/JzsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBpcHY2LWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQdjYgYWRkcmVzcyBpbiBmdWxsLAogICAgICBtaXhlZCwgc2hvcnRlbmVkLCBhbmQgc2hvcnRlbmVkLW1peGVkIG5vdGF0aW9uLiAgVGhlIElQdjYKICAgICAgYWRkcmVzcyBtYXkgaW5jbHVkZSBhIHpvbmUgaW5kZXgsIHNlcGFyYXRlZCBieSBhICUgc2lnbi4KCiAgICAgIFRoZSB6b25lIGluZGV4IGlzIHVzZWQgdG8gZGlzYW1iaWd1YXRlIGlkZW50aWNhbCBhZGRyZXNzCiAgICAgIHZhbHVlcy4gIEZvciBsaW5rLWxvY2FsIGFkZHJlc3NlcywgdGhlIHpvbmUgaW5kZXggd2lsbAogICAgICB0eXBpY2FsbHkgYmUgdGhlIGludGVyZmFjZSBpbmRleCBudW1iZXIgb3IgdGhlIG5hbWUgb2YgYW4KICAgICAgaW50ZXJmYWNlLiAgSWYgdGhlIHpvbmUgaW5kZXggaXMgbm90IHByZXNlbnQsIHRoZSBkZWZhdWx0CiAgICAgIHpvbmUgb2YgdGhlIGRldmljZSB3aWxsIGJlIHVzZWQuCgogICAgICBUaGUgY2Fub25pY2FsIGZvcm1hdCBvZiBJUHY2IGFkZHJlc3NlcyB1c2VzIHRoZSB0ZXh0dWFsCiAgICAgIHJlcHJlc2VudGF0aW9uIGRlZmluZWQgaW4gU2VjdGlvbiA0IG9mIFJGQyA1OTUyLiAgVGhlCiAgICAgIGNhbm9uaWNhbCBmb3JtYXQgZm9yIHRoZSB6b25lIGluZGV4IGlzIHRoZSBudW1lcmljYWwKICAgICAgZm9ybWF0IGFzIGRlc2NyaWJlZCBpbiBTZWN0aW9uIDExLjIgb2YgUkZDIDQwMDcuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDI5MTogSVAgVmVyc2lvbiA2IEFkZHJlc3NpbmcgQXJjaGl0ZWN0dXJlCiAgICAgIFJGQyA0MDA3OiBJUHY2IFNjb3BlZCBBZGRyZXNzIEFyY2hpdGVjdHVyZQogICAgICBSRkMgNTk1MjogQSBSZWNvbW1lbmRhdGlvbiBmb3IgSVB2NiBBZGRyZXNzIFRleHQKICAgICAgICAgICAgICAgIFJlcHJlc2VudGF0aW9uIjsKICB9CgogIHR5cGVkZWYgaXAtYWRkcmVzcy1uby16b25lIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzLW5vLXpvbmU7CiAgICAgIHR5cGUgaW5ldDppcHY2LWFkZHJlc3Mtbm8tem9uZTsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBpcC1hZGRyZXNzLW5vLXpvbmUgdHlwZSByZXByZXNlbnRzIGFuIElQIGFkZHJlc3MgYW5kIGlzCiAgICAgIElQIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24KICAgICAgaW1wbGllcyB0aGUgSVAgdmVyc2lvbi4gIFRoaXMgdHlwZSBkb2VzIG5vdCBzdXBwb3J0IHNjb3BlZAogICAgICBhZGRyZXNzZXMgc2luY2UgaXQgZG9lcyBub3QgYWxsb3cgem9uZSBpZGVudGlmaWVycyBpbiB0aGUKICAgICAgYWRkcmVzcyBmb3JtYXQuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDAwNzogSVB2NiBTY29wZWQgQWRkcmVzcyBBcmNoaXRlY3R1cmUiOwogIH0KCiAgdHlwZWRlZiBpcHY0LWFkZHJlc3Mtbm8tem9uZSB7CiAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzIHsKICAgICAgcGF0dGVybiAnWzAtOVwuXSonOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIkFuIElQdjQgYWRkcmVzcyB3aXRob3V0IGEgem9uZSBpbmRleC4gIFRoaXMgdHlwZSwgZGVyaXZlZCBmcm9tCiAgICAgICBpcHY0LWFkZHJlc3MsIG1heSBiZSB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgdGhlIHpvbmUgaXMKICAgICAgIGtub3duIGZyb20gdGhlIGNvbnRleHQgYW5kIGhlbmNlIG5vIHpvbmUgaW5kZXggaXMgbmVlZGVkLiI7CiAgfQoKICB0eXBlZGVmIGlwdjYtYWRkcmVzcy1uby16b25lIHsKICAgIHR5cGUgaW5ldDppcHY2LWFkZHJlc3MgewogICAgICBwYXR0ZXJuICdbMC05YS1mQS1GOlwuXSonOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIkFuIElQdjYgYWRkcmVzcyB3aXRob3V0IGEgem9uZSBpbmRleC4gIFRoaXMgdHlwZSwgZGVyaXZlZCBmcm9tCiAgICAgICBpcHY2LWFkZHJlc3MsIG1heSBiZSB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgdGhlIHpvbmUgaXMKICAgICAgIGtub3duIGZyb20gdGhlIGNvbnRleHQgYW5kIGhlbmNlIG5vIHpvbmUgaW5kZXggaXMgbmVlZGVkLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDQyOTE6IElQIFZlcnNpb24gNiBBZGRyZXNzaW5nIEFyY2hpdGVjdHVyZQogICAgICBSRkMgNDAwNzogSVB2NiBTY29wZWQgQWRkcmVzcyBBcmNoaXRlY3R1cmUKICAgICAgUkZDIDU5NTI6IEEgUmVjb21tZW5kYXRpb24gZm9yIElQdjYgQWRkcmVzcyBUZXh0CiAgICAgICAgICAgICAgICBSZXByZXNlbnRhdGlvbiI7CiAgfQoKICB0eXBlZGVmIGlwLXByZWZpeCB7CiAgICB0eXBlIHVuaW9uIHsKICAgICAgdHlwZSBpbmV0OmlwdjQtcHJlZml4OwogICAgICB0eXBlIGluZXQ6aXB2Ni1wcmVmaXg7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXAtcHJlZml4IHR5cGUgcmVwcmVzZW50cyBhbiBJUCBwcmVmaXggYW5kIGlzIElQCiAgICAgIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb25zCiAgICAgIGltcGxpZXMgdGhlIElQIHZlcnNpb24uIjsKICB9CgogIHR5cGVkZWYgaXB2NC1wcmVmaXggewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuCiAgICAgICAgICcoKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcLil7M30nCiAgICAgICArICAnKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSknCiAgICAgICArICcvKChbMC05XSl8KFsxLTJdWzAtOV0pfCgzWzAtMl0pKSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXB2NC1wcmVmaXggdHlwZSByZXByZXNlbnRzIGFuIElQdjQgYWRkcmVzcyBwcmVmaXguCiAgICAgIFRoZSBwcmVmaXggbGVuZ3RoIGlzIGdpdmVuIGJ5IHRoZSBudW1iZXIgZm9sbG93aW5nIHRoZQogICAgICBzbGFzaCBjaGFyYWN0ZXIgYW5kIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDMyLgoKICAgICAgQSBwcmVmaXggbGVuZ3RoIHZhbHVlIG9mIG4gY29ycmVzcG9uZHMgdG8gYW4gSVAgYWRkcmVzcwogICAgICBtYXNrIHRoYXQgaGFzIG4gY29udGlndW91cyAxLWJpdHMgZnJvbSB0aGUgbW9zdAogICAgICBzaWduaWZpY2FudCBiaXQgKE1TQikgYW5kIGFsbCBvdGhlciBiaXRzIHNldCB0byAwLgoKICAgICAgVGhlIGNhbm9uaWNhbCBmb3JtYXQgb2YgYW4gSVB2NCBwcmVmaXggaGFzIGFsbCBiaXRzIG9mCiAgICAgIHRoZSBJUHY0IGFkZHJlc3Mgc2V0IHRvIHplcm8gdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlCiAgICAgIElQdjQgcHJlZml4LiI7CiAgfQoKICB0eXBlZGVmIGlwdjYtcHJlZml4IHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKCg6fFswLTlhLWZBLUZdezAsNH0pOikoWzAtOWEtZkEtRl17MCw0fTopezAsNX0nCiAgICAgICAgICAgICsgJygoKFswLTlhLWZBLUZdezAsNH06KT8oOnxbMC05YS1mQS1GXXswLDR9KSl8JwogICAgICAgICAgICArICcoKCgyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV0/WzAtOV0pXC4pezN9JwogICAgICAgICAgICArICcoMjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldP1swLTldKSkpJwogICAgICAgICAgICArICcoLygoWzAtOV0pfChbMC05XXsyfSl8KDFbMC0xXVswLTldKXwoMTJbMC04XSkpKSc7CiAgICAgIHBhdHRlcm4gJygoW146XSs6KXs2fSgoW146XSs6W146XSspfCguKlwuLiopKSl8JwogICAgICAgICAgICArICcoKChbXjpdKzopKlteOl0rKT86OigoW146XSs6KSpbXjpdKyk/KScKICAgICAgICAgICAgKyAnKC8uKyknOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGlwdjYtcHJlZml4IHR5cGUgcmVwcmVzZW50cyBhbiBJUHY2IGFkZHJlc3MgcHJlZml4LgogICAgICBUaGUgcHJlZml4IGxlbmd0aCBpcyBnaXZlbiBieSB0aGUgbnVtYmVyIGZvbGxvd2luZyB0aGUKICAgICAgc2xhc2ggY2hhcmFjdGVyIGFuZCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAxMjguCgogICAgICBBIHByZWZpeCBsZW5ndGggdmFsdWUgb2YgbiBjb3JyZXNwb25kcyB0byBhbiBJUCBhZGRyZXNzCiAgICAgIG1hc2sgdGhhdCBoYXMgbiBjb250aWd1b3VzIDEtYml0cyBmcm9tIHRoZSBtb3N0CiAgICAgIHNpZ25pZmljYW50IGJpdCAoTVNCKSBhbmQgYWxsIG90aGVyIGJpdHMgc2V0IHRvIDAuCgogICAgICBUaGUgSVB2NiBhZGRyZXNzIHNob3VsZCBoYXZlIGFsbCBiaXRzIHRoYXQgZG8gbm90IGJlbG9uZwogICAgICB0byB0aGUgcHJlZml4IHNldCB0byB6ZXJvLgoKICAgICAgVGhlIGNhbm9uaWNhbCBmb3JtYXQgb2YgYW4gSVB2NiBwcmVmaXggaGFzIGFsbCBiaXRzIG9mCiAgICAgIHRoZSBJUHY2IGFkZHJlc3Mgc2V0IHRvIHplcm8gdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlCiAgICAgIElQdjYgcHJlZml4LiAgRnVydGhlcm1vcmUsIHRoZSBJUHY2IGFkZHJlc3MgaXMgcmVwcmVzZW50ZWQKICAgICAgYXMgZGVmaW5lZCBpbiBTZWN0aW9uIDQgb2YgUkZDIDU5NTIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNTk1MjogQSBSZWNvbW1lbmRhdGlvbiBmb3IgSVB2NiBBZGRyZXNzIFRleHQKICAgICAgICAgICAgICAgIFJlcHJlc2VudGF0aW9uIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBkb21haW4gbmFtZSBhbmQgVVJJIHR5cGVzICoqKi8KCiAgdHlwZWRlZiBkb21haW4tbmFtZSB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIGxlbmd0aCAiMS4uMjUzIjsKICAgICAgcGF0dGVybgogICAgICAgICcoKChbYS16QS1aMC05X10oW2EtekEtWjAtOVwtX10pezAsNjF9KT9bYS16QS1aMC05XVwuKSonCiAgICAgICsgJyhbYS16QS1aMC05X10oW2EtekEtWjAtOVwtX10pezAsNjF9KT9bYS16QS1aMC05XVwuPyknCiAgICAgICsgJ3xcLic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgZG9tYWluLW5hbWUgdHlwZSByZXByZXNlbnRzIGEgRE5TIGRvbWFpbiBuYW1lLiAgVGhlCiAgICAgIG5hbWUgU0hPVUxEIGJlIGZ1bGx5IHF1YWxpZmllZCB3aGVuZXZlciBwb3NzaWJsZS4KCiAgICAgIEludGVybmV0IGRvbWFpbiBuYW1lcyBhcmUgb25seSBsb29zZWx5IHNwZWNpZmllZC4gIFNlY3Rpb24KICAgICAgMy41IG9mIFJGQyAxMDM0IHJlY29tbWVuZHMgYSBzeW50YXggKG1vZGlmaWVkIGluIFNlY3Rpb24KICAgICAgMi4xIG9mIFJGQyAxMTIzKS4gIFRoZSBwYXR0ZXJuIGFib3ZlIGlzIGludGVuZGVkIHRvIGFsbG93CiAgICAgIGZvciBjdXJyZW50IHByYWN0aWNlIGluIGRvbWFpbiBuYW1lIHVzZSwgYW5kIHNvbWUgcG9zc2libGUKICAgICAgZnV0dXJlIGV4cGFuc2lvbi4gIEl0IGlzIGRlc2lnbmVkIHRvIGhvbGQgdmFyaW91cyB0eXBlcyBvZgogICAgICBkb21haW4gbmFtZXMsIGluY2x1ZGluZyBuYW1lcyB1c2VkIGZvciBBIG9yIEFBQUEgcmVjb3JkcwogICAgICAoaG9zdCBuYW1lcykgYW5kIG90aGVyIHJlY29yZHMsIHN1Y2ggYXMgU1JWIHJlY29yZHMuICBOb3RlCiAgICAgIHRoYXQgSW50ZXJuZXQgaG9zdCBuYW1lcyBoYXZlIGEgc3RyaWN0ZXIgc3ludGF4IChkZXNjcmliZWQKICAgICAgaW4gUkZDIDk1MikgdGhhbiB0aGUgRE5TIHJlY29tbWVuZGF0aW9ucyBpbiBSRkNzIDEwMzQgYW5kCiAgICAgIDExMjMsIGFuZCB0aGF0IHN5c3RlbXMgdGhhdCB3YW50IHRvIHN0b3JlIGhvc3QgbmFtZXMgaW4KICAgICAgc2NoZW1hIG5vZGVzIHVzaW5nIHRoZSBkb21haW4tbmFtZSB0eXBlIGFyZSByZWNvbW1lbmRlZCB0bwogICAgICBhZGhlcmUgdG8gdGhpcyBzdHJpY3RlciBzdGFuZGFyZCB0byBlbnN1cmUgaW50ZXJvcGVyYWJpbGl0eS4KCiAgICAgIFRoZSBlbmNvZGluZyBvZiBETlMgbmFtZXMgaW4gdGhlIEROUyBwcm90b2NvbCBpcyBsaW1pdGVkCiAgICAgIHRvIDI1NSBjaGFyYWN0ZXJzLiAgU2luY2UgdGhlIGVuY29kaW5nIGNvbnNpc3RzIG9mIGxhYmVscwogICAgICBwcmVmaXhlZCBieSBhIGxlbmd0aCBieXRlcyBhbmQgdGhlcmUgaXMgYSB0cmFpbGluZyBOVUxMCiAgICAgIGJ5dGUsIG9ubHkgMjUzIGNoYXJhY3RlcnMgY2FuIGFwcGVhciBpbiB0aGUgdGV4dHVhbCBkb3R0ZWQKICAgICAgbm90YXRpb24uCgogICAgICBUaGUgZGVzY3JpcHRpb24gY2xhdXNlIG9mIHNjaGVtYSBub2RlcyB1c2luZyB0aGUgZG9tYWluLW5hbWUKICAgICAgdHlwZSBNVVNUIGRlc2NyaWJlIHdoZW4gYW5kIGhvdyB0aGVzZSBuYW1lcyBhcmUgcmVzb2x2ZWQgdG8KICAgICAgSVAgYWRkcmVzc2VzLiAgTm90ZSB0aGF0IHRoZSByZXNvbHV0aW9uIG9mIGEgZG9tYWluLW5hbWUgdmFsdWUKICAgICAgbWF5IHJlcXVpcmUgdG8gcXVlcnkgbXVsdGlwbGUgRE5TIHJlY29yZHMgKGUuZy4sIEEgZm9yIElQdjQKICAgICAgYW5kIEFBQUEgZm9yIElQdjYpLiAgVGhlIG9yZGVyIG9mIHRoZSByZXNvbHV0aW9uIHByb2Nlc3MgYW5kCiAgICAgIHdoaWNoIEROUyByZWNvcmQgdGFrZXMgcHJlY2VkZW5jZSBjYW4gZWl0aGVyIGJlIGRlZmluZWQKICAgICAgZXhwbGljaXRseSBvciBtYXkgZGVwZW5kIG9uIHRoZSBjb25maWd1cmF0aW9uIG9mIHRoZQogICAgICByZXNvbHZlci4KCiAgICAgIERvbWFpbi1uYW1lIHZhbHVlcyB1c2UgdGhlIFVTLUFTQ0lJIGVuY29kaW5nLiAgVGhlaXIgY2Fub25pY2FsCiAgICAgIGZvcm1hdCB1c2VzIGxvd2VyY2FzZSBVUy1BU0NJSSBjaGFyYWN0ZXJzLiAgSW50ZXJuYXRpb25hbGl6ZWQKICAgICAgZG9tYWluIG5hbWVzIE1VU1QgYmUgQS1sYWJlbHMgYXMgcGVyIFJGQyA1ODkwLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDICA5NTI6IERvRCBJbnRlcm5ldCBIb3N0IFRhYmxlIFNwZWNpZmljYXRpb24KICAgICAgUkZDIDEwMzQ6IERvbWFpbiBOYW1lcyAtIENvbmNlcHRzIGFuZCBGYWNpbGl0aWVzCiAgICAgIFJGQyAxMTIzOiBSZXF1aXJlbWVudHMgZm9yIEludGVybmV0IEhvc3RzIC0tIEFwcGxpY2F0aW9uCiAgICAgICAgICAgICAgICBhbmQgU3VwcG9ydAogICAgICBSRkMgMjc4MjogQSBETlMgUlIgZm9yIHNwZWNpZnlpbmcgdGhlIGxvY2F0aW9uIG9mIHNlcnZpY2VzCiAgICAgICAgICAgICAgICAoRE5TIFNSVikKICAgICAgUkZDIDU4OTA6IEludGVybmF0aW9uYWxpemVkIERvbWFpbiBOYW1lcyBpbiBBcHBsaWNhdGlvbnMKICAgICAgICAgICAgICAgIChJRE5BKTogRGVmaW5pdGlvbnMgYW5kIERvY3VtZW50IEZyYW1ld29yayI7CiAgfQoKICB0eXBlZGVmIGhvc3QgewogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgaW5ldDppcC1hZGRyZXNzOwogICAgICB0eXBlIGluZXQ6ZG9tYWluLW5hbWU7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaG9zdCB0eXBlIHJlcHJlc2VudHMgZWl0aGVyIGFuIElQIGFkZHJlc3Mgb3IgYSBETlMKICAgICAgZG9tYWluIG5hbWUuIjsKICB9CgogIHR5cGVkZWYgdXJpIHsKICAgIHR5cGUgc3RyaW5nOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIHVyaSB0eXBlIHJlcHJlc2VudHMgYSBVbmlmb3JtIFJlc291cmNlIElkZW50aWZpZXIKICAgICAgKFVSSSkgYXMgZGVmaW5lZCBieSBTVEQgNjYuCgogICAgICBPYmplY3RzIHVzaW5nIHRoZSB1cmkgdHlwZSBNVVNUIGJlIGluIFVTLUFTQ0lJIGVuY29kaW5nLAogICAgICBhbmQgTVVTVCBiZSBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBieSBSRkMgMzk4NiBTZWN0aW9ucwogICAgICA2LjIuMSwgNi4yLjIuMSwgYW5kIDYuMi4yLjIuICBBbGwgdW5uZWNlc3NhcnkKICAgICAgcGVyY2VudC1lbmNvZGluZyBpcyByZW1vdmVkLCBhbmQgYWxsIGNhc2UtaW5zZW5zaXRpdmUKICAgICAgY2hhcmFjdGVycyBhcmUgc2V0IHRvIGxvd2VyY2FzZSBleGNlcHQgZm9yIGhleGFkZWNpbWFsCiAgICAgIGRpZ2l0cywgd2hpY2ggYXJlIG5vcm1hbGl6ZWQgdG8gdXBwZXJjYXNlIGFzIGRlc2NyaWJlZCBpbgogICAgICBTZWN0aW9uIDYuMi4yLjEuCgogICAgICBUaGUgcHVycG9zZSBvZiB0aGlzIG5vcm1hbGl6YXRpb24gaXMgdG8gaGVscCBwcm92aWRlCiAgICAgIHVuaXF1ZSBVUklzLiAgTm90ZSB0aGF0IHRoaXMgbm9ybWFsaXphdGlvbiBpcyBub3QKICAgICAgc3VmZmljaWVudCB0byBwcm92aWRlIHVuaXF1ZW5lc3MuICBUd28gVVJJcyB0aGF0IGFyZQogICAgICB0ZXh0dWFsbHkgZGlzdGluY3QgYWZ0ZXIgdGhpcyBub3JtYWxpemF0aW9uIG1heSBzdGlsbCBiZQogICAgICBlcXVpdmFsZW50LgoKICAgICAgT2JqZWN0cyB1c2luZyB0aGUgdXJpIHR5cGUgbWF5IHJlc3RyaWN0IHRoZSBzY2hlbWVzIHRoYXQKICAgICAgdGhleSBwZXJtaXQuICBGb3IgZXhhbXBsZSwgJ2RhdGE6JyBhbmQgJ3VybjonIHNjaGVtZXMKICAgICAgbWlnaHQgbm90IGJlIGFwcHJvcHJpYXRlLgoKICAgICAgQSB6ZXJvLWxlbmd0aCBVUkkgaXMgbm90IGEgdmFsaWQgVVJJLiAgVGhpcyBjYW4gYmUgdXNlZCB0bwogICAgICBleHByZXNzICdVUkkgYWJzZW50JyB3aGVyZSByZXF1aXJlZC4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBVcmkgU01JdjIgdGV4dHVhbCBjb252ZW50aW9uIGRlZmluZWQgaW4gUkZDIDUwMTcuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzk4NjogVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyIChVUkkpOiBHZW5lcmljIFN5bnRheAogICAgICBSRkMgMzMwNTogUmVwb3J0IGZyb20gdGhlIEpvaW50IFczQy9JRVRGIFVSSSBQbGFubmluZyBJbnRlcmVzdAogICAgICAgICAgICAgICAgR3JvdXA6IFVuaWZvcm0gUmVzb3VyY2UgSWRlbnRpZmllcnMgKFVSSXMpLCBVUkxzLAogICAgICAgICAgICAgICAgYW5kIFVuaWZvcm0gUmVzb3VyY2UgTmFtZXMgKFVSTnMpOiBDbGFyaWZpY2F0aW9ucwogICAgICAgICAgICAgICAgYW5kIFJlY29tbWVuZGF0aW9ucwogICAgICBSRkMgNTAxNzogTUlCIFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFVuaWZvcm0gUmVzb3VyY2UKICAgICAgICAgICAgICAgIElkZW50aWZpZXJzIChVUklzKSI7CiAgfQoKfQ==
+ietf-yang-types        urn:ietf:params:xml:ns:yang:ietf-yang-types     \N      []      2013-07-15      bW9kdWxlIGlldGYteWFuZy10eXBlcyB7CgogIG5hbWVzcGFjZSAidXJuOmlldGY6cGFyYW1zOnhtbDpuczp5YW5nOmlldGYteWFuZy10eXBlcyI7CiAgcHJlZml4ICJ5YW5nIjsKCiAgb3JnYW5pemF0aW9uCiAgICJJRVRGIE5FVE1PRCAoTkVUQ09ORiBEYXRhIE1vZGVsaW5nIExhbmd1YWdlKSBXb3JraW5nIEdyb3VwIjsKCiAgY29udGFjdAogICAiV0cgV2ViOiAgIDxodHRwOi8vdG9vbHMuaWV0Zi5vcmcvd2cvbmV0bW9kLz4KICAgIFdHIExpc3Q6ICA8bWFpbHRvOm5ldG1vZEBpZXRmLm9yZz4KCiAgICBXRyBDaGFpcjogRGF2aWQgS2Vzc2VucwogICAgICAgICAgICAgIDxtYWlsdG86ZGF2aWQua2Vzc2Vuc0Buc24uY29tPgoKICAgIFdHIENoYWlyOiBKdWVyZ2VuIFNjaG9lbndhZWxkZXIKICAgICAgICAgICAgICA8bWFpbHRvOmouc2Nob2Vud2FlbGRlckBqYWNvYnMtdW5pdmVyc2l0eS5kZT4KCiAgICBFZGl0b3I6ICAgSnVlcmdlbiBTY2hvZW53YWVsZGVyCiAgICAgICAgICAgICAgPG1haWx0bzpqLnNjaG9lbndhZWxkZXJAamFjb2JzLXVuaXZlcnNpdHkuZGU+IjsKCiAgZGVzY3JpcHRpb24KICAgIlRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgY29sbGVjdGlvbiBvZiBnZW5lcmFsbHkgdXNlZnVsIGRlcml2ZWQKICAgIFlBTkcgZGF0YSB0eXBlcy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTMgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvcgogICAgd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywgYW5kIHN1YmplY3QKICAgIHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlIFNpbXBsaWZpZWQgQlNEIExpY2Vuc2UKICAgIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUgSUVURiBUcnVzdCdzIExlZ2FsIFByb3Zpc2lvbnMKICAgIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cDovL3RydXN0ZWUuaWV0Zi5vcmcvbGljZW5zZS1pbmZvKS4KCiAgICBUaGlzIHZlcnNpb24gb2YgdGhpcyBZQU5HIG1vZHVsZSBpcyBwYXJ0IG9mIFJGQyA2OTkxOyBzZWUKICAgIHRoZSBSRkMgaXRzZWxmIGZvciBmdWxsIGxlZ2FsIG5vdGljZXMuIjsKCiAgcmV2aXNpb24gMjAxMy0wNy0xNSB7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHJldmlzaW9uIGFkZHMgdGhlIGZvbGxvd2luZyBuZXcgZGF0YSB0eXBlczoKICAgICAgLSB5YW5nLWlkZW50aWZpZXIKICAgICAgLSBoZXgtc3RyaW5nCiAgICAgIC0gdXVpZAogICAgICAtIGRvdHRlZC1xdWFkIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjk5MTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICByZXZpc2lvbiAyMDEwLTA5LTI0IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgIkluaXRpYWwgcmV2aXNpb24uIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjAyMTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgY291bnRlciBhbmQgZ2F1Z2UgdHlwZXMgKioqLwoKICB0eXBlZGVmIGNvdW50ZXIzMiB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBjb3VudGVyMzIgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIKICAgICAgdGhhdCBtb25vdG9uaWNhbGx5IGluY3JlYXNlcyB1bnRpbCBpdCByZWFjaGVzIGEKICAgICAgbWF4aW11bSB2YWx1ZSBvZiAyXjMyLTEgKDQyOTQ5NjcyOTUgZGVjaW1hbCksIHdoZW4gaXQKICAgICAgd3JhcHMgYXJvdW5kIGFuZCBzdGFydHMgaW5jcmVhc2luZyBhZ2FpbiBmcm9tIHplcm8uCgogICAgICBDb3VudGVycyBoYXZlIG5vIGRlZmluZWQgJ2luaXRpYWwnIHZhbHVlLCBhbmQgdGh1cywgYQogICAgICBzaW5nbGUgdmFsdWUgb2YgYSBjb3VudGVyIGhhcyAoaW4gZ2VuZXJhbCkgbm8gaW5mb3JtYXRpb24KICAgICAgY29udGVudC4gIERpc2NvbnRpbnVpdGllcyBpbiB0aGUgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nCiAgICAgIHZhbHVlIG5vcm1hbGx5IG9jY3VyIGF0IHJlLWluaXRpYWxpemF0aW9uIG9mIHRoZQogICAgICBtYW5hZ2VtZW50IHN5c3RlbSwgYW5kIGF0IG90aGVyIHRpbWVzIGFzIHNwZWNpZmllZCBpbiB0aGUKICAgICAgZGVzY3JpcHRpb24gb2YgYSBzY2hlbWEgbm9kZSB1c2luZyB0aGlzIHR5cGUuICBJZiBzdWNoCiAgICAgIG90aGVyIHRpbWVzIGNhbiBvY2N1ciwgZm9yIGV4YW1wbGUsIHRoZSBjcmVhdGlvbiBvZgogICAgICBhIHNjaGVtYSBub2RlIG9mIHR5cGUgY291bnRlcjMyIGF0IHRpbWVzIG90aGVyIHRoYW4KICAgICAgcmUtaW5pdGlhbGl6YXRpb24sIHRoZW4gYSBjb3JyZXNwb25kaW5nIHNjaGVtYSBub2RlCiAgICAgIHNob3VsZCBiZSBkZWZpbmVkLCB3aXRoIGFuIGFwcHJvcHJpYXRlIHR5cGUsIHRvIGluZGljYXRlCiAgICAgIHRoZSBsYXN0IGRpc2NvbnRpbnVpdHkuCgogICAgICBUaGUgY291bnRlcjMyIHR5cGUgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBjb25maWd1cmF0aW9uCiAgICAgIHNjaGVtYSBub2Rlcy4gIEEgZGVmYXVsdCBzdGF0ZW1lbnQgU0hPVUxEIE5PVCBiZSB1c2VkIGluCiAgICAgIGNvbWJpbmF0aW9uIHdpdGggdGhlIHR5cGUgY291bnRlcjMyLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIENvdW50ZXIzMiB0eXBlIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyNTc4OiBTdHJ1Y3R1cmUgb2YgTWFuYWdlbWVudCBJbmZvcm1hdGlvbiBWZXJzaW9uIDIKICAgICAgICAgICAgICAgIChTTUl2MikiOwogIH0KCiAgdHlwZWRlZiB6ZXJvLWJhc2VkLWNvdW50ZXIzMiB7CiAgICB0eXBlIHlhbmc6Y291bnRlcjMyOwogICAgZGVmYXVsdCAiMCI7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgemVyby1iYXNlZC1jb3VudGVyMzIgdHlwZSByZXByZXNlbnRzIGEgY291bnRlcjMyCiAgICAgIHRoYXQgaGFzIHRoZSBkZWZpbmVkICdpbml0aWFsJyB2YWx1ZSB6ZXJvLgoKICAgICAgQSBzY2hlbWEgbm9kZSBvZiB0aGlzIHR5cGUgd2lsbCBiZSBzZXQgdG8gemVybyAoMCkgb24gY3JlYXRpb24KICAgICAgYW5kIHdpbGwgdGhlcmVhZnRlciBpbmNyZWFzZSBtb25vdG9uaWNhbGx5IHVudGlsIGl0IHJlYWNoZXMKICAgICAgYSBtYXhpbXVtIHZhbHVlIG9mIDJeMzItMSAoNDI5NDk2NzI5NSBkZWNpbWFsKSwgd2hlbiBpdAogICAgICB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIFByb3ZpZGVkIHRoYXQgYW4gYXBwbGljYXRpb24gZGlzY292ZXJzIGEgbmV3IHNjaGVtYSBub2RlCiAgICAgIG9mIHRoaXMgdHlwZSB3aXRoaW4gdGhlIG1pbmltdW0gdGltZSB0byB3cmFwLCBpdCBjYW4gdXNlIHRoZQogICAgICAnaW5pdGlhbCcgdmFsdWUgYXMgYSBkZWx0YS4gIEl0IGlzIGltcG9ydGFudCBmb3IgYSBtYW5hZ2VtZW50CiAgICAgIHN0YXRpb24gdG8gYmUgYXdhcmUgb2YgdGhpcyBtaW5pbXVtIHRpbWUgYW5kIHRoZSBhY3R1YWwgdGltZQogICAgICBiZXR3ZWVuIHBvbGxzLCBhbmQgdG8gZGlzY2FyZCBkYXRhIGlmIHRoZSBhY3R1YWwgdGltZSBpcyB0b28KICAgICAgbG9uZyBvciB0aGVyZSBpcyBubyBkZWZpbmVkIG1pbmltdW0gdGltZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBaZXJvQmFzZWRDb3VudGVyMzIgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgICJSRkMgNDUwMjogUmVtb3RlIE5ldHdvcmsgTW9uaXRvcmluZyBNYW5hZ2VtZW50IEluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgQmFzZSBWZXJzaW9uIDIiOwogIH0KCiAgdHlwZWRlZiBjb3VudGVyNjQgewogICAgdHlwZSB1aW50NjQ7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgY291bnRlcjY0IHR5cGUgcmVwcmVzZW50cyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyCiAgICAgIHRoYXQgbW9ub3RvbmljYWxseSBpbmNyZWFzZXMgdW50aWwgaXQgcmVhY2hlcyBhCiAgICAgIG1heGltdW0gdmFsdWUgb2YgMl42NC0xICgxODQ0Njc0NDA3MzcwOTU1MTYxNSBkZWNpbWFsKSwKICAgICAgd2hlbiBpdCB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIENvdW50ZXJzIGhhdmUgbm8gZGVmaW5lZCAnaW5pdGlhbCcgdmFsdWUsIGFuZCB0aHVzLCBhCiAgICAgIHNpbmdsZSB2YWx1ZSBvZiBhIGNvdW50ZXIgaGFzIChpbiBnZW5lcmFsKSBubyBpbmZvcm1hdGlvbgogICAgICBjb250ZW50LiAgRGlzY29udGludWl0aWVzIGluIHRoZSBtb25vdG9uaWNhbGx5IGluY3JlYXNpbmcKICAgICAgdmFsdWUgbm9ybWFsbHkgb2NjdXIgYXQgcmUtaW5pdGlhbGl6YXRpb24gb2YgdGhlCiAgICAgIG1hbmFnZW1lbnQgc3lzdGVtLCBhbmQgYXQgb3RoZXIgdGltZXMgYXMgc3BlY2lmaWVkIGluIHRoZQogICAgICBkZXNjcmlwdGlvbiBvZiBhIHNjaGVtYSBub2RlIHVzaW5nIHRoaXMgdHlwZS4gIElmIHN1Y2gKICAgICAgb3RoZXIgdGltZXMgY2FuIG9jY3VyLCBmb3IgZXhhbXBsZSwgdGhlIGNyZWF0aW9uIG9mCiAgICAgIGEgc2NoZW1hIG5vZGUgb2YgdHlwZSBjb3VudGVyNjQgYXQgdGltZXMgb3RoZXIgdGhhbgogICAgICByZS1pbml0aWFsaXphdGlvbiwgdGhlbiBhIGNvcnJlc3BvbmRpbmcgc2NoZW1hIG5vZGUKICAgICAgc2hvdWxkIGJlIGRlZmluZWQsIHdpdGggYW4gYXBwcm9wcmlhdGUgdHlwZSwgdG8gaW5kaWNhdGUKICAgICAgdGhlIGxhc3QgZGlzY29udGludWl0eS4KCiAgICAgIFRoZSBjb3VudGVyNjQgdHlwZSBzaG91bGQgbm90IGJlIHVzZWQgZm9yIGNvbmZpZ3VyYXRpb24KICAgICAgc2NoZW1hIG5vZGVzLiAgQSBkZWZhdWx0IHN0YXRlbWVudCBTSE9VTEQgTk9UIGJlIHVzZWQgaW4KICAgICAgY29tYmluYXRpb24gd2l0aCB0aGUgdHlwZSBjb3VudGVyNjQuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgQ291bnRlcjY0IHR5cGUgb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDI1Nzg6IFN0cnVjdHVyZSBvZiBNYW5hZ2VtZW50IEluZm9ybWF0aW9uIFZlcnNpb24gMgogICAgICAgICAgICAgICAgKFNNSXYyKSI7CiAgfQoKICB0eXBlZGVmIHplcm8tYmFzZWQtY291bnRlcjY0IHsKICAgIHR5cGUgeWFuZzpjb3VudGVyNjQ7CiAgICBkZWZhdWx0ICIwIjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSB6ZXJvLWJhc2VkLWNvdW50ZXI2NCB0eXBlIHJlcHJlc2VudHMgYSBjb3VudGVyNjQgdGhhdAogICAgICBoYXMgdGhlIGRlZmluZWQgJ2luaXRpYWwnIHZhbHVlIHplcm8uCgoKCgogICAgICBBIHNjaGVtYSBub2RlIG9mIHRoaXMgdHlwZSB3aWxsIGJlIHNldCB0byB6ZXJvICgwKSBvbiBjcmVhdGlvbgogICAgICBhbmQgd2lsbCB0aGVyZWFmdGVyIGluY3JlYXNlIG1vbm90b25pY2FsbHkgdW50aWwgaXQgcmVhY2hlcwogICAgICBhIG1heGltdW0gdmFsdWUgb2YgMl42NC0xICgxODQ0Njc0NDA3MzcwOTU1MTYxNSBkZWNpbWFsKSwKICAgICAgd2hlbiBpdCB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIFByb3ZpZGVkIHRoYXQgYW4gYXBwbGljYXRpb24gZGlzY292ZXJzIGEgbmV3IHNjaGVtYSBub2RlCiAgICAgIG9mIHRoaXMgdHlwZSB3aXRoaW4gdGhlIG1pbmltdW0gdGltZSB0byB3cmFwLCBpdCBjYW4gdXNlIHRoZQogICAgICAnaW5pdGlhbCcgdmFsdWUgYXMgYSBkZWx0YS4gIEl0IGlzIGltcG9ydGFudCBmb3IgYSBtYW5hZ2VtZW50CiAgICAgIHN0YXRpb24gdG8gYmUgYXdhcmUgb2YgdGhpcyBtaW5pbXVtIHRpbWUgYW5kIHRoZSBhY3R1YWwgdGltZQogICAgICBiZXR3ZWVuIHBvbGxzLCBhbmQgdG8gZGlzY2FyZCBkYXRhIGlmIHRoZSBhY3R1YWwgdGltZSBpcyB0b28KICAgICAgbG9uZyBvciB0aGVyZSBpcyBubyBkZWZpbmVkIG1pbmltdW0gdGltZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBaZXJvQmFzZWRDb3VudGVyNjQgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyODU2OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBBZGRpdGlvbmFsIEhpZ2ggQ2FwYWNpdHkKICAgICAgICAgICAgICAgIERhdGEgVHlwZXMiOwogIH0KCiAgdHlwZWRlZiBnYXVnZTMyIHsKICAgIHR5cGUgdWludDMyOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGdhdWdlMzIgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIsIHdoaWNoCiAgICAgIG1heSBpbmNyZWFzZSBvciBkZWNyZWFzZSwgYnV0IHNoYWxsIG5ldmVyIGV4Y2VlZCBhIG1heGltdW0KICAgICAgdmFsdWUsIG5vciBmYWxsIGJlbG93IGEgbWluaW11bSB2YWx1ZS4gIFRoZSBtYXhpbXVtIHZhbHVlCiAgICAgIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gMl4zMi0xICg0Mjk0OTY3Mjk1IGRlY2ltYWwpLCBhbmQKICAgICAgdGhlIG1pbmltdW0gdmFsdWUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiAwLiAgVGhlIHZhbHVlIG9mCiAgICAgIGEgZ2F1Z2UzMiBoYXMgaXRzIG1heGltdW0gdmFsdWUgd2hlbmV2ZXIgdGhlIGluZm9ybWF0aW9uCiAgICAgIGJlaW5nIG1vZGVsZWQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGl0cyBtYXhpbXVtCiAgICAgIHZhbHVlLCBhbmQgaGFzIGl0cyBtaW5pbXVtIHZhbHVlIHdoZW5ldmVyIHRoZSBpbmZvcm1hdGlvbgogICAgICBiZWluZyBtb2RlbGVkIGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0byBpdHMgbWluaW11bSB2YWx1ZS4KICAgICAgSWYgdGhlIGluZm9ybWF0aW9uIGJlaW5nIG1vZGVsZWQgc3Vic2VxdWVudGx5IGRlY3JlYXNlcwogICAgICBiZWxvdyAoaW5jcmVhc2VzIGFib3ZlKSB0aGUgbWF4aW11bSAobWluaW11bSkgdmFsdWUsIHRoZQogICAgICBnYXVnZTMyIGFsc28gZGVjcmVhc2VzIChpbmNyZWFzZXMpLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIEdhdWdlMzIgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgZ2F1Z2U2NCB7CiAgICB0eXBlIHVpbnQ2NDsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBnYXVnZTY0IHR5cGUgcmVwcmVzZW50cyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLCB3aGljaAogICAgICBtYXkgaW5jcmVhc2Ugb3IgZGVjcmVhc2UsIGJ1dCBzaGFsbCBuZXZlciBleGNlZWQgYSBtYXhpbXVtCiAgICAgIHZhbHVlLCBub3IgZmFsbCBiZWxvdyBhIG1pbmltdW0gdmFsdWUuICBUaGUgbWF4aW11bSB2YWx1ZQogICAgICBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIDJeNjQtMSAoMTg0NDY3NDQwNzM3MDk1NTE2MTUpLCBhbmQKICAgICAgdGhlIG1pbmltdW0gdmFsdWUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiAwLiAgVGhlIHZhbHVlIG9mCiAgICAgIGEgZ2F1Z2U2NCBoYXMgaXRzIG1heGltdW0gdmFsdWUgd2hlbmV2ZXIgdGhlIGluZm9ybWF0aW9uCiAgICAgIGJlaW5nIG1vZGVsZWQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGl0cyBtYXhpbXVtCiAgICAgIHZhbHVlLCBhbmQgaGFzIGl0cyBtaW5pbXVtIHZhbHVlIHdoZW5ldmVyIHRoZSBpbmZvcm1hdGlvbgogICAgICBiZWluZyBtb2RlbGVkIGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0byBpdHMgbWluaW11bSB2YWx1ZS4KICAgICAgSWYgdGhlIGluZm9ybWF0aW9uIGJlaW5nIG1vZGVsZWQgc3Vic2VxdWVudGx5IGRlY3JlYXNlcwogICAgICBiZWxvdyAoaW5jcmVhc2VzIGFib3ZlKSB0aGUgbWF4aW11bSAobWluaW11bSkgdmFsdWUsIHRoZQogICAgICBnYXVnZTY0IGFsc28gZGVjcmVhc2VzIChpbmNyZWFzZXMpLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIENvdW50ZXJCYXNlZEdhdWdlNjQgU01JdjIgdGV4dHVhbCBjb252ZW50aW9uIGRlZmluZWQKICAgICAgaW4gUkZDIDI4NTYiOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyODU2OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBBZGRpdGlvbmFsIEhpZ2ggQ2FwYWNpdHkKICAgICAgICAgICAgICAgIERhdGEgVHlwZXMiOwogIH0KCiAgLyoqKiBjb2xsZWN0aW9uIG9mIGlkZW50aWZpZXItcmVsYXRlZCB0eXBlcyAqKiovCgogIHR5cGVkZWYgb2JqZWN0LWlkZW50aWZpZXIgewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICcoKFswLTFdKFwuWzEtM10/WzAtOV0pKXwoMlwuKDB8KFsxLTldXGQqKSkpKScKICAgICAgICAgICAgKyAnKFwuKDB8KFsxLTldXGQqKSkpKic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgb2JqZWN0LWlkZW50aWZpZXIgdHlwZSByZXByZXNlbnRzIGFkbWluaXN0cmF0aXZlbHkKICAgICAgYXNzaWduZWQgbmFtZXMgaW4gYSByZWdpc3RyYXRpb24taGllcmFyY2hpY2FsLW5hbWUgdHJlZS4KCiAgICAgIFZhbHVlcyBvZiB0aGlzIHR5cGUgYXJlIGRlbm90ZWQgYXMgYSBzZXF1ZW5jZSBvZiBudW1lcmljYWwKICAgICAgbm9uLW5lZ2F0aXZlIHN1Yi1pZGVudGlmaWVyIHZhbHVlcy4gIEVhY2ggc3ViLWlkZW50aWZpZXIKICAgICAgdmFsdWUgTVVTVCBOT1QgZXhjZWVkIDJeMzItMSAoNDI5NDk2NzI5NSkuICBTdWItaWRlbnRpZmllcnMKICAgICAgYXJlIHNlcGFyYXRlZCBieSBzaW5nbGUgZG90cyBhbmQgd2l0aG91dCBhbnkgaW50ZXJtZWRpYXRlCiAgICAgIHdoaXRlc3BhY2UuCgogICAgICBUaGUgQVNOLjEgc3RhbmRhcmQgcmVzdHJpY3RzIHRoZSB2YWx1ZSBzcGFjZSBvZiB0aGUgZmlyc3QKICAgICAgc3ViLWlkZW50aWZpZXIgdG8gMCwgMSwgb3IgMi4gIEZ1cnRoZXJtb3JlLCB0aGUgdmFsdWUgc3BhY2UKICAgICAgb2YgdGhlIHNlY29uZCBzdWItaWRlbnRpZmllciBpcyByZXN0cmljdGVkIHRvIHRoZSByYW5nZQogICAgICAwIHRvIDM5IGlmIHRoZSBmaXJzdCBzdWItaWRlbnRpZmllciBpcyAwIG9yIDEuICBGaW5hbGx5LAogICAgICB0aGUgQVNOLjEgc3RhbmRhcmQgcmVxdWlyZXMgdGhhdCBhbiBvYmplY3QgaWRlbnRpZmllcgogICAgICBoYXMgYWx3YXlzIGF0IGxlYXN0IHR3byBzdWItaWRlbnRpZmllcnMuICBUaGUgcGF0dGVybgogICAgICBjYXB0dXJlcyB0aGVzZSByZXN0cmljdGlvbnMuCgogICAgICBBbHRob3VnaCB0aGUgbnVtYmVyIG9mIHN1Yi1pZGVudGlmaWVycyBpcyBub3QgbGltaXRlZCwKICAgICAgbW9kdWxlIGRlc2lnbmVycyBzaG91bGQgcmVhbGl6ZSB0aGF0IHRoZXJlIG1heSBiZQogICAgICBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdGljayB3aXRoIHRoZSBTTUl2MiBsaW1pdCBvZiAxMjgKICAgICAgc3ViLWlkZW50aWZpZXJzLgoKICAgICAgVGhpcyB0eXBlIGlzIGEgc3VwZXJzZXQgb2YgdGhlIFNNSXYyIE9CSkVDVCBJREVOVElGSUVSIHR5cGUKICAgICAgc2luY2UgaXQgaXMgbm90IHJlc3RyaWN0ZWQgdG8gMTI4IHN1Yi1pZGVudGlmaWVycy4gIEhlbmNlLAogICAgICB0aGlzIHR5cGUgU0hPVUxEIE5PVCBiZSB1c2VkIHRvIHJlcHJlc2VudCB0aGUgU01JdjIgT0JKRUNUCiAgICAgIElERU5USUZJRVIgdHlwZTsgdGhlIG9iamVjdC1pZGVudGlmaWVyLTEyOCB0eXBlIFNIT1VMRCBiZQogICAgICB1c2VkIGluc3RlYWQuIjsKICAgIHJlZmVyZW5jZQogICAgICJJU085ODM0LTE6IEluZm9ybWF0aW9uIHRlY2hub2xvZ3kgLS0gT3BlbiBTeXN0ZW1zCiAgICAgIEludGVyY29ubmVjdGlvbiAtLSBQcm9jZWR1cmVzIGZvciB0aGUgb3BlcmF0aW9uIG9mIE9TSQogICAgICBSZWdpc3RyYXRpb24gQXV0aG9yaXRpZXM6IEdlbmVyYWwgcHJvY2VkdXJlcyBhbmQgdG9wCiAgICAgIGFyY3Mgb2YgdGhlIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHRyZWUiOwogIH0KCiAgdHlwZWRlZiBvYmplY3QtaWRlbnRpZmllci0xMjggewogICAgdHlwZSBvYmplY3QtaWRlbnRpZmllciB7CiAgICAgIHBhdHRlcm4gJ1xkKihcLlxkKil7MSwxMjd9JzsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoaXMgdHlwZSByZXByZXNlbnRzIG9iamVjdC1pZGVudGlmaWVycyByZXN0cmljdGVkIHRvIDEyOAogICAgICBzdWItaWRlbnRpZmllcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgT0JKRUNUIElERU5USUZJRVIgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgeWFuZy1pZGVudGlmaWVyIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgbGVuZ3RoICIxLi5tYXgiOwogICAgICBwYXR0ZXJuICdbYS16QS1aX11bYS16QS1aMC05XC1fLl0qJzsKICAgICAgcGF0dGVybiAnLnwuLnxbXnhYXS4qfC5bXm1NXS4qfC4uW15sTF0uKic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICAiQSBZQU5HIGlkZW50aWZpZXIgc3RyaW5nIGFzIGRlZmluZWQgYnkgdGhlICdpZGVudGlmaWVyJwogICAgICAgcnVsZSBpbiBTZWN0aW9uIDEyIG9mIFJGQyA2MDIwLiAgQW4gaWRlbnRpZmllciBtdXN0CiAgICAgICBzdGFydCB3aXRoIGFuIGFscGhhYmV0aWMgY2hhcmFjdGVyIG9yIGFuIHVuZGVyc2NvcmUKICAgICAgIGZvbGxvd2VkIGJ5IGFuIGFyYml0cmFyeSBzZXF1ZW5jZSBvZiBhbHBoYWJldGljIG9yCiAgICAgICBudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmVzLCBoeXBoZW5zLCBvciBkb3RzLgoKICAgICAgIEEgWUFORyBpZGVudGlmaWVyIE1VU1QgTk9UIHN0YXJ0IHdpdGggYW55IHBvc3NpYmxlCiAgICAgICBjb21iaW5hdGlvbiBvZiB0aGUgbG93ZXJjYXNlIG9yIHVwcGVyY2FzZSBjaGFyYWN0ZXIKICAgICAgIHNlcXVlbmNlICd4bWwnLiI7CiAgICByZWZlcmVuY2UKICAgICAgIlJGQyA2MDIwOiBZQU5HIC0gQSBEYXRhIE1vZGVsaW5nIExhbmd1YWdlIGZvciB0aGUgTmV0d29yawogICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gUHJvdG9jb2wgKE5FVENPTkYpIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiB0eXBlcyByZWxhdGVkIHRvIGRhdGUgYW5kIHRpbWUqKiovCgogIHR5cGVkZWYgZGF0ZS1hbmQtdGltZSB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4gJ1xkezR9LVxkezJ9LVxkezJ9VFxkezJ9OlxkezJ9OlxkezJ9KFwuXGQrKT8nCiAgICAgICAgICAgICsgJyhafFtcK1wtXVxkezJ9OlxkezJ9KSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgZGF0ZS1hbmQtdGltZSB0eXBlIGlzIGEgcHJvZmlsZSBvZiB0aGUgSVNPIDg2MDEKICAgICAgc3RhbmRhcmQgZm9yIHJlcHJlc2VudGF0aW9uIG9mIGRhdGVzIGFuZCB0aW1lcyB1c2luZyB0aGUKICAgICAgR3JlZ29yaWFuIGNhbGVuZGFyLiAgVGhlIHByb2ZpbGUgaXMgZGVmaW5lZCBieSB0aGUKICAgICAgZGF0ZS10aW1lIHByb2R1Y3Rpb24gaW4gU2VjdGlvbiA1LjYgb2YgUkZDIDMzMzkuCgogICAgICBUaGUgZGF0ZS1hbmQtdGltZSB0eXBlIGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgZGF0ZVRpbWUgWE1MCiAgICAgIHNjaGVtYSB0eXBlIHdpdGggdGhlIGZvbGxvd2luZyBub3RhYmxlIGV4Y2VwdGlvbnM6CgogICAgICAoYSkgVGhlIGRhdGUtYW5kLXRpbWUgdHlwZSBkb2VzIG5vdCBhbGxvdyBuZWdhdGl2ZSB5ZWFycy4KCiAgICAgIChiKSBUaGUgZGF0ZS1hbmQtdGltZSB0aW1lLW9mZnNldCAtMDA6MDAgaW5kaWNhdGVzIGFuIHVua25vd24KICAgICAgICAgIHRpbWUgem9uZSAoc2VlIFJGQyAzMzM5KSB3aGlsZSAtMDA6MDAgYW5kICswMDowMCBhbmQgWgogICAgICAgICAgYWxsIHJlcHJlc2VudCB0aGUgc2FtZSB0aW1lIHpvbmUgaW4gZGF0ZVRpbWUuCgogICAgICAoYykgVGhlIGNhbm9uaWNhbCBmb3JtYXQgKHNlZSBiZWxvdykgb2YgZGF0YS1hbmQtdGltZSB2YWx1ZXMKICAgICAgICAgIGRpZmZlcnMgZnJvbSB0aGUgY2Fub25pY2FsIGZvcm1hdCB1c2VkIGJ5IHRoZSBkYXRlVGltZSBYTUwKICAgICAgICAgIHNjaGVtYSB0eXBlLCB3aGljaCByZXF1aXJlcyBhbGwgdGltZXMgdG8gYmUgaW4gVVRDIHVzaW5nCiAgICAgICAgICB0aGUgdGltZS1vZmZzZXQgJ1onLgoKICAgICAgVGhpcyB0eXBlIGlzIG5vdCBlcXVpdmFsZW50IHRvIHRoZSBEYXRlQW5kVGltZSB0ZXh0dWFsCiAgICAgIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyIHNpbmNlIFJGQyAzMzM5IHVzZXMgYSBkaWZmZXJlbnQKICAgICAgc2VwYXJhdG9yIGJldHdlZW4gZnVsbC1kYXRlIGFuZCBmdWxsLXRpbWUgYW5kIHByb3ZpZGVzCiAgICAgIGhpZ2hlciByZXNvbHV0aW9uIG9mIHRpbWUtc2VjZnJhYy4KCiAgICAgIFRoZSBjYW5vbmljYWwgZm9ybWF0IGZvciBkYXRlLWFuZC10aW1lIHZhbHVlcyB3aXRoIGEga25vd24gdGltZQogICAgICB6b25lIHVzZXMgYSBudW1lcmljIHRpbWUgem9uZSBvZmZzZXQgdGhhdCBpcyBjYWxjdWxhdGVkIHVzaW5nCiAgICAgIHRoZSBkZXZpY2UncyBjb25maWd1cmVkIGtub3duIG9mZnNldCB0byBVVEMgdGltZS4gIEEgY2hhbmdlIG9mCiAgICAgIHRoZSBkZXZpY2UncyBvZmZzZXQgdG8gVVRDIHRpbWUgd2lsbCBjYXVzZSBkYXRlLWFuZC10aW1lIHZhbHVlcwogICAgICB0byBjaGFuZ2UgYWNjb3JkaW5nbHkuICBTdWNoIGNoYW5nZXMgbWlnaHQgaGFwcGVuIHBlcmlvZGljYWxseQogICAgICBpbiBjYXNlIGEgc2VydmVyIGZvbGxvd3MgYXV0b21hdGljYWxseSBkYXlsaWdodCBzYXZpbmcgdGltZQogICAgICAoRFNUKSB0aW1lIHpvbmUgb2Zmc2V0IGNoYW5nZXMuICBUaGUgY2Fub25pY2FsIGZvcm1hdCBmb3IKICAgICAgZGF0ZS1hbmQtdGltZSB2YWx1ZXMgd2l0aCBhbiB1bmtub3duIHRpbWUgem9uZSAodXN1YWxseQogICAgICByZWZlcnJpbmcgdG8gdGhlIG5vdGlvbiBvZiBsb2NhbCB0aW1lKSB1c2VzIHRoZSB0aW1lLW9mZnNldAogICAgICAtMDA6MDAuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzMzOTogRGF0ZSBhbmQgVGltZSBvbiB0aGUgSW50ZXJuZXQ6IFRpbWVzdGFtcHMKICAgICAgUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyCiAgICAgIFhTRC1UWVBFUzogWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlcyBTZWNvbmQgRWRpdGlvbiI7CiAgfQoKICB0eXBlZGVmIHRpbWV0aWNrcyB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSB0aW1ldGlja3MgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgdGhhdAogICAgICByZXByZXNlbnRzIHRoZSB0aW1lLCBtb2R1bG8gMl4zMiAoNDI5NDk2NzI5NiBkZWNpbWFsKSwgaW4KICAgICAgaHVuZHJlZHRocyBvZiBhIHNlY29uZCBiZXR3ZWVuIHR3byBlcG9jaHMuICBXaGVuIGEgc2NoZW1hCiAgICAgIG5vZGUgaXMgZGVmaW5lZCB0aGF0IHVzZXMgdGhpcyB0eXBlLCB0aGUgZGVzY3JpcHRpb24gb2YKICAgICAgdGhlIHNjaGVtYSBub2RlIGlkZW50aWZpZXMgYm90aCBvZiB0aGUgcmVmZXJlbmNlIGVwb2Nocy4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBUaW1lVGlja3MgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgdGltZXN0YW1wIHsKICAgIHR5cGUgeWFuZzp0aW1ldGlja3M7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgdGltZXN0YW1wIHR5cGUgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2YgYW4gYXNzb2NpYXRlZAogICAgICB0aW1ldGlja3Mgc2NoZW1hIG5vZGUgYXQgd2hpY2ggYSBzcGVjaWZpYyBvY2N1cnJlbmNlCiAgICAgIGhhcHBlbmVkLiAgVGhlIHNwZWNpZmljIG9jY3VycmVuY2UgbXVzdCBiZSBkZWZpbmVkIGluIHRoZQogICAgICBkZXNjcmlwdGlvbiBvZiBhbnkgc2NoZW1hIG5vZGUgZGVmaW5lZCB1c2luZyB0aGlzIHR5cGUuICBXaGVuCiAgICAgIHRoZSBzcGVjaWZpYyBvY2N1cnJlbmNlIG9jY3VycmVkIHByaW9yIHRvIHRoZSBsYXN0IHRpbWUgdGhlCiAgICAgIGFzc29jaWF0ZWQgdGltZXRpY2tzIGF0dHJpYnV0ZSB3YXMgemVybywgdGhlbiB0aGUgdGltZXN0YW1wCiAgICAgIHZhbHVlIGlzIHplcm8uICBOb3RlIHRoYXQgdGhpcyByZXF1aXJlcyBhbGwgdGltZXN0YW1wIHZhbHVlcwogICAgICB0byBiZSByZXNldCB0byB6ZXJvIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBhc3NvY2lhdGVkIHRpbWV0aWNrcwogICAgICBhdHRyaWJ1dGUgcmVhY2hlcyA0OTcrIGRheXMgYW5kIHdyYXBzIGFyb3VuZCB0byB6ZXJvLgoKICAgICAgVGhlIGFzc29jaWF0ZWQgdGltZXRpY2tzIHNjaGVtYSBub2RlIG11c3QgYmUgc3BlY2lmaWVkCiAgICAgIGluIHRoZSBkZXNjcmlwdGlvbiBvZiBhbnkgc2NoZW1hIG5vZGUgdXNpbmcgdGhpcyB0eXBlLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIFRpbWVTdGFtcCB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBnZW5lcmljIGFkZHJlc3MgdHlwZXMgKioqLwoKICB0eXBlZGVmIHBoeXMtYWRkcmVzcyB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4gJyhbMC05YS1mQS1GXXsyfSg6WzAtOWEtZkEtRl17Mn0pKik/JzsKICAgIH0KCgoKCiAgICBkZXNjcmlwdGlvbgogICAgICJSZXByZXNlbnRzIG1lZGlhLSBvciBwaHlzaWNhbC1sZXZlbCBhZGRyZXNzZXMgcmVwcmVzZW50ZWQKICAgICAgYXMgYSBzZXF1ZW5jZSBvY3RldHMsIGVhY2ggb2N0ZXQgcmVwcmVzZW50ZWQgYnkgdHdvIGhleGFkZWNpbWFsCiAgICAgIG51bWJlcnMuICBPY3RldHMgYXJlIHNlcGFyYXRlZCBieSBjb2xvbnMuICBUaGUgY2Fub25pY2FsCiAgICAgIHJlcHJlc2VudGF0aW9uIHVzZXMgbG93ZXJjYXNlIGNoYXJhY3RlcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgUGh5c0FkZHJlc3MgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyNTc5OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBTTUl2MiI7CiAgfQoKICB0eXBlZGVmIG1hYy1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnWzAtOWEtZkEtRl17Mn0oOlswLTlhLWZBLUZdezJ9KXs1fSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgbWFjLWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElFRUUgODAyIE1BQyBhZGRyZXNzLgogICAgICBUaGUgY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uIHVzZXMgbG93ZXJjYXNlIGNoYXJhY3RlcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgTWFjQWRkcmVzcyB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiSUVFRSA4MDI6IElFRUUgU3RhbmRhcmQgZm9yIExvY2FsIGFuZCBNZXRyb3BvbGl0YW4gQXJlYQogICAgICAgICAgICAgICAgTmV0d29ya3M6IE92ZXJ2aWV3IGFuZCBBcmNoaXRlY3R1cmUKICAgICAgUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBYTUwtc3BlY2lmaWMgdHlwZXMgKioqLwoKICB0eXBlZGVmIHhwYXRoMS4wIHsKICAgIHR5cGUgc3RyaW5nOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhpcyB0eXBlIHJlcHJlc2VudHMgYW4gWFBBVEggMS4wIGV4cHJlc3Npb24uCgogICAgICBXaGVuIGEgc2NoZW1hIG5vZGUgaXMgZGVmaW5lZCB0aGF0IHVzZXMgdGhpcyB0eXBlLCB0aGUKICAgICAgZGVzY3JpcHRpb24gb2YgdGhlIHNjaGVtYSBub2RlIE1VU1Qgc3BlY2lmeSB0aGUgWFBhdGgKICAgICAgY29udGV4dCBpbiB3aGljaCB0aGUgWFBhdGggZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQuIjsKICAgIHJlZmVyZW5jZQogICAgICJYUEFUSDogWE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMCI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2Ygc3RyaW5nIHR5cGVzICoqKi8KCiAgdHlwZWRlZiBoZXgtc3RyaW5nIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKFswLTlhLWZBLUZdezJ9KDpbMC05YS1mQS1GXXsyfSkqKT8nOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiQSBoZXhhZGVjaW1hbCBzdHJpbmcgd2l0aCBvY3RldHMgcmVwcmVzZW50ZWQgYXMgaGV4IGRpZ2l0cwogICAgICBzZXBhcmF0ZWQgYnkgY29sb25zLiAgVGhlIGNhbm9uaWNhbCByZXByZXNlbnRhdGlvbiB1c2VzCiAgICAgIGxvd2VyY2FzZSBjaGFyYWN0ZXJzLiI7CiAgfQoKICB0eXBlZGVmIHV1aWQgewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS0nCiAgICAgICAgICAgICsgJ1swLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJBIFVuaXZlcnNhbGx5IFVuaXF1ZSBJRGVudGlmaWVyIGluIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgICAgZGVmaW5lZCBpbiBSRkMgNDEyMi4gIFRoZSBjYW5vbmljYWwgcmVwcmVzZW50YXRpb24gdXNlcwogICAgICBsb3dlcmNhc2UgY2hhcmFjdGVycy4KCiAgICAgIFRoZSBmb2xsb3dpbmcgaXMgYW4gZXhhbXBsZSBvZiBhIFVVSUQgaW4gc3RyaW5nIHJlcHJlc2VudGF0aW9uOgogICAgICBmODFkNGZhZS03ZGVjLTExZDAtYTc2NS0wMGEwYzkxZTZiZjYKICAgICAgIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDEyMjogQSBVbml2ZXJzYWxseSBVbmlxdWUgSURlbnRpZmllciAoVVVJRCkgVVJOCiAgICAgICAgICAgICAgICBOYW1lc3BhY2UiOwogIH0KCiAgdHlwZWRlZiBkb3R0ZWQtcXVhZCB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4KICAgICAgICAnKChbMC05XXxbMS05XVswLTldfDFbMC05XVswLTldfDJbMC00XVswLTldfDI1WzAtNV0pXC4pezN9JwogICAgICArICcoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICAiQW4gdW5zaWduZWQgMzItYml0IG51bWJlciBleHByZXNzZWQgaW4gdGhlIGRvdHRlZC1xdWFkCiAgICAgICBub3RhdGlvbiwgaS5lLiwgZm91ciBvY3RldHMgd3JpdHRlbiBhcyBkZWNpbWFsIG51bWJlcnMKICAgICAgIGFuZCBzZXBhcmF0ZWQgd2l0aCB0aGUgJy4nIChmdWxsIHN0b3ApIGNoYXJhY3Rlci4iOwogIH0KfQ==
+o-ran-smo-teiv-common-yang-extensions  urn:o-ran:smo-teiv-common-yang-extensions       \N      []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOm8tcmFuOnNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMiOwogICAgcHJlZml4IG9yLXRlaXYteWV4dDsKCiAgICBvcmdhbml6YXRpb24gIkVyaWNzc29uIEFCIjsKICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOwogICAgZGVzY3JpcHRpb24KICAgICJUb3BvbG9neSBhbmQgSW52ZW50b3J5IFlBTkcgZXh0ZW5zaW9ucyBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyBleHRlbnNpb25zIHRvIHRoZSBZQU5HIGxhbmd1YWdlIHRoYXQgdG9wb2xvZ3kgYW5kCiAgICBpbnZlbnRvcnkgbW9kZWxzIHdpbGwgdXNlIHRvIGRlZmluZSBhbmQgYW5ub3RhdGUgdHlwZXMgYW5kIHJlbGF0aW9uc2hpcHMuIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0yNCIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIGV4dGVuc2lvbiBiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJEZWZpbmVzIGEgYmktZGlyZWN0aW9uYWwgcmVsYXRpb25zaGlwIGluIHRoZSB0b3BvbG9neS4KCiAgICAgICAgICAgIEEgYmktZGlyZWN0aW9uYWwtYXNzb2NpYXRpb24gKEJEQSkgaXMgYSByZWxhdGlvbnNoaXAgY29tcHJpc2luZyBvZgogICAgICAgICAgICBhbiBBLXNpZGUgYW5kIGEgQi1zaWRlLiBUaGUgQS1zaWRlIGlzIGNvbnNpZGVyZWQgdGhlIG9yaWdpbmF0aW5nCiAgICAgICAgICAgIHNpZGUgb2YgdGhlIHJlbGF0aW9uc2hpcDsgdGhlIEItc2lkZSBpcyBjb25zaWRlcmVkIHRoZSB0ZXJtaW5hdGluZwogICAgICAgICAgICBzaWRlIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSBvcmRlciBvZiBBLXNpZGUgYW5kIEItc2lkZSBpcyBvZgogICAgICAgICAgICBpbXBvcnRhbmNlIGFuZCBNVVNUIE5PVCBiZSBjaGFuZ2VkIG9uY2UgZGVmaW5lZC4KCiAgICAgICAgICAgIEJvdGggQS1zaWRlIGFuZCBCLXNpZGUgYXJlIGRlZmluZWQgb24gYSB0eXBlLCBhbmQgYXJlIGdpdmVuIGEgcm9sZS4KICAgICAgICAgICAgQSB0eXBlIG1heSBoYXZlIG11bHRpcGxlIG9yaWdpbmF0aW5nIGFuZC9vciB0ZXJtaW5hdGluZyBzaWRlcyBvZiBhCiAgICAgICAgICAgIHJlbGF0aW9uc2hpcCwgYWxsIGRpc3Rpbmd1aXNoZWQgYnkgcm9sZSBuYW1lLgoKICAgICAgICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIG9ubHkgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlICdtb2R1bGUnIHN0YXRlbWVudC4KICAgICAgICAgICAgTXVsdGlwbGUgJ2JpLWRpcmVjdGlvbmFsLXRvcG9sb2d5LXJlbGF0aW9uc2hpcCcgc3RhdGVtZW50cyBhcmUKICAgICAgICAgICAgYWxsb3dlZCBwZXIgcGFyZW50IHN0YXRlbWVudC4KCiAgICAgICAgICAgIFN1YnN0YXRlbWVudHMgdG8gdGhlICdiaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIGRlZmluZQogICAgICAgICAgICB0aGUgQS1zaWRlIGFuZCB0aGUgQi1zaWRlLCByZXNwZWN0aXZlbHksIGFuZCBvcHRpb25hbGx5IHByb3BlcnRpZXMKICAgICAgICAgICAgb2YgdGhlIHJlbGF0aW9uc2hpcC4gRGF0YSBub2RlcyBvZiB0eXBlcyAnbGVhZicgYW5kICdsZWFmLWxpc3QnIGFyZQogICAgICAgICAgICB1c2VkIGZvciB0aGlzIHB1cnBvc2UuIE9uZSBvZiB0aGUgZGF0YSBub2RlcyBNVVNUIGJlIGFubm90YXRlZCB3aXRoCiAgICAgICAgICAgIHRoZSAnYS1zaWRlJyBleHRlbnNpb247IGFub3RoZXIgZGF0YSBub2RlIE1VU1QgYmUgYW5ub3RhdGVkIHdpdGggdGhlCiAgICAgICAgICAgICdiLXNpZGUnIGV4dGVuc2lvbi4gT3RoZXIgZGF0YSBub2RlcyBkZWZpbmUgcHJvcGVydGllcyBvZiB0aGUKICAgICAgICAgICAgcmVsYXRpb25zaGlwLgoKICAgICAgICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSByZWxhdGlvbnNoaXAgbmFtZQogICAgICAgICAgICBpcyBzY29wZWQgdG8gdGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyaW5nIG1vZHVsZSBhbmQgTVVTVCBiZQogICAgICAgICAgICB1bmlxdWUgd2l0aGluIHRoZSBzY29wZS4iOwoKICAgICAgICBhcmd1bWVudCByZWxhdGlvbnNoaXBOYW1lOwogICAgfQoKICAgIGV4dGVuc2lvbiBhU2lkZSB7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIkRlZmluZXMgdGhlIEEtc2lkZSBvZiBhIHJlbGF0aW9uc2hpcC4KCiAgICAgICAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgJ2xlYWYnIG9yICdsZWFmLWxpc3QnCiAgICAgICAgICAgIHN0YXRlbWVudCwgd2hpY2ggaXRzZWxmIG11c3QgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlCiAgICAgICAgICAgICd1bmktZGlyZWN0aW9uYWwtdG9wb2xvZ3ktcmVsYXRpb25zaGlwJyBzdGF0ZW1lbnQuCgogICAgICAgICAgICBUaGUgZGF0YSB0eXBlIG9mIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIE1VU1QgYmUKICAgICAgICAgICAgJ2luc3RhbmNlLWlkZW50aWZpZXInLiBDb25zdHJhaW50cyBNQVkgYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwYXJlbnQKICAgICAgICAgICAgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIHRvIGVuZm9yY2UgY2FyZGluYWxpdHkuCgogICAgICAgICAgICBUaGUgaWRlbnRpZmllciBvZiB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBpcyB1c2VkIGFzIG5hbWUKICAgICAgICAgICAgb2YgdGhlIHJvbGUgb2YgdGhlIEEtc2lkZSBvZiB0aGUgcmVsYXRpb25zaGlwLiBUaGUgbmFtZSBvZiB0aGUgcm9sZQogICAgICAgICAgICBpcyBzY29wZWQgdG8gdGhlIHR5cGUgb24gd2hpY2ggdGhlIEEtc2lkZSBpcyBkZWZpbmVkIGFuZCBNVVNUIGJlCiAgICAgICAgICAgIHVuaXF1ZSB3aXRoaW4gdGhlIHNjb3BlLgoKICAgICAgICAgICAgV2hpbGUgdGhlIHBhcmVudCAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgZG9lcyBub3QgcmVzdWx0IGluIGEgcHJvcGVydHkKICAgICAgICAgICAgb2YgdGhlIHJlbGF0aW9uc2hpcCwgaXQgaXMgUkVDT01NRU5ERUQgdG8gYXZvaWQgdXNpbmcgdGhlIG5hbWUgb2YgYW4KICAgICAgICAgICAgZXhpc3RpbmcgdHlwZSBwcm9wZXJ0eSBhcyByb2xlIG5hbWUgdG8gYXZvaWQgcG90ZW50aWFsIGFtYmlndWl0aWVzCiAgICAgICAgICAgIGJldHdlZW4gcHJvcGVydGllcyBvZiBhIHR5cGUsIGFuZCByb2xlcyBvZiBhIHJlbGF0aW9uc2hpcCBvbiB0aGUKICAgICAgICAgICAgdHlwZS4KCiAgICAgICAgICAgIFRoZSBhcmd1bWVudCBpcyB0aGUgbmFtZSBvZiB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQS1zaWRlIHJlc2lkZXMuCiAgICAgICAgICAgIElmIHRoZSB0eXBlIGlzIGRlY2xhcmVkIGluIGFub3RoZXIgbW9kdWxlLCB0aGUgdHlwZSBtdXN0IGJlCiAgICAgICAgICAgIHByZWZpeGVkLCBhbmQgYSBjb3JyZXNwb25kaW5nICdpbXBvcnQnIHN0YXRlbWVudCBiZSB1c2VkIHRvIGRlY2xhcmUKICAgICAgICAgICAgdGhlIHByZWZpeC4iOwoKICAgICAgICBhcmd1bWVudCBhU2lkZVR5cGU7CiAgICB9CgogICAgZXh0ZW5zaW9uIGJTaWRlIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiRGVmaW5lcyB0aGUgQi1zaWRlIG9mIGEgcmVsYXRpb25zaGlwLgoKICAgICAgICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIG9ubHkgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgYSAnbGVhZicgb3IgJ2xlYWYtbGlzdCcKICAgICAgICAgICAgc3RhdGVtZW50LCB3aGljaCBpdHNlbGYgbXVzdCBiZSBhIHN1YnN0YXRlbWVudCBvZiB0aGUKICAgICAgICAgICAgJ3VuaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIHN0YXRlbWVudC4KCiAgICAgICAgICAgIFRoZSBkYXRhIHR5cGUgb2YgdGhlIHBhcmVudCAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgTVVTVCBiZQogICAgICAgICAgICAnaW5zdGFuY2UtaWRlbnRpZmllcicuIENvbnN0cmFpbnRzIE1BWSBiZSB1c2VkIGFzIHBhcnQgb2YgdGhlIHBhcmVudAogICAgICAgICAgICAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgdG8gZW5mb3JjZSBjYXJkaW5hbGl0eS4KCiAgICAgICAgICAgIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIGlzIHVzZWQgYXMgbmFtZQogICAgICAgICAgICBvZiB0aGUgcm9sZSBvZiB0aGUgQi1zaWRlIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSBuYW1lIG9mIHRoZSByb2xlCiAgICAgICAgICAgIGlzIHNjb3BlZCB0byB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQi1zaWRlIGlzIGRlZmluZWQgYW5kIE1VU1QgYmUKICAgICAgICAgICAgdW5pcXVlIHdpdGhpbiB0aGUgc2NvcGUuCgogICAgICAgICAgICBXaGlsZSB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBkb2VzIG5vdCByZXN1bHQgaW4gYSBwcm9wZXJ0eQogICAgICAgICAgICBvZiB0aGUgcmVsYXRpb25zaGlwLCBpdCBpcyBSRUNPTU1FTkRFRCB0byBhdm9pZCB1c2luZyB0aGUgbmFtZSBvZiBhbgogICAgICAgICAgICBleGlzdGluZyB0eXBlIHByb3BlcnR5IGFzIHJvbGUgbmFtZSB0byBhdm9pZCBwb3RlbnRpYWwgYW1iaWd1aXRpZXMKICAgICAgICAgICAgYmV0d2VlbiBwcm9wZXJ0aWVzIG9mIGEgdHlwZSwgYW5kIHJvbGVzIG9mIGEgcmVsYXRpb25zaGlwIG9uIHRoZQogICAgICAgICAgICB0eXBlLgoKICAgICAgICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSB0eXBlIG9uIHdoaWNoIHRoZSBCLXNpZGUgcmVzaWRlcy4KICAgICAgICAgICAgSWYgdGhlIHR5cGUgaXMgZGVjbGFyZWQgaW4gYW5vdGhlciBtb2R1bGUsIHRoZSB0eXBlIG11c3QgYmUKICAgICAgICAgICAgcHJlZml4ZWQsIGFuZCBhIGNvcnJlc3BvbmRpbmcgJ2ltcG9ydCcgc3RhdGVtZW50IGJlIHVzZWQgdG8gZGVjbGFyZQogICAgICAgICAgICB0aGUgcHJlZml4LiI7CgogICAgICAgIGFyZ3VtZW50IGJTaWRlVHlwZTsKICAgIH0KCiAgICBleHRlbnNpb24gZG9tYWluIHsKICAgICAgICBkZXNjcmlwdGlvbiAiS2V5d29yZCB1c2VkIHRvIGNhcnJ5IGRvbWFpbiBpbmZvcm1hdGlvbi4iOwogICAgICAgIGFyZ3VtZW50IGRvbWFpbk5hbWU7CiAgICB9CgogICAgZXh0ZW5zaW9uIGxhYmVsIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhlIGxhYmVsIGNhbiBiZSB1c2VkIHRvIGdpdmUgbW9kdWxlcyBhbmQgc3VibW9kdWxlcyBhIHNlbWFudGljCiAgICAgICAgICAgIHZlcnNpb24sIGluIGFkZGl0aW9uIHRvIHRoZWlyIHJldmlzaW9uLgoKICAgICAgICAgICAgVGhlIGZvcm1hdCBvZiB0aGUgbGFiZWwgaXMg4oCYeC55LnrigJkg4oCTIGV4cHJlc3NlZCBhcyBwYXR0ZXJuLCBpdCBpcwogICAgICAgICAgICBbMC05XStcXC5bMC05XStcXC5bMC05XSsKCiAgICAgICAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIHRoZSByZXZpc2lvbiBzdGF0ZW1lbnQuCiAgICAgICAgICAgIFplcm8gb3Igb25lIHJldmlzaW9uIGxhYmVsIHN0YXRlbWVudHMgcGVyIHBhcmVudCBzdGF0ZW1lbnQgYXJlCiAgICAgICAgICAgIGFsbG93ZWQuCgogICAgICAgICAgICBSZXZpc2lvbiBsYWJlbHMgTVVTVCBiZSB1bmlxdWUgYW1vbmdzdCBhbGwgcmV2aXNpb25zIG9mIGEgbW9kdWxlIG9yCiAgICAgICAgICAgIHN1Ym1vZHVsZS4iOwoKICAgICAgICBhcmd1bWVudCBzZW12ZXJzaW9uOwogICAgfQp9
+o-ran-smo-teiv-common-yang-types       urn:o-ran:smo-teiv-common-yang-types    \N      []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyI7CiAgICBwcmVmaXggb3ItdGVpdi10eXBlczsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7IHByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgXzNncHAtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggdHlwZXMzZ3BwOyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiVG9wb2xvZ3kgYW5kIEludmVudG9yeSBjb21tb24gdHlwZXMgbW9kZWwuCgogICAgQ29weXJpZ2h0IChjKSAyMDI0IEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKICAgIFRoaXMgbW9kZWwgY29udGFpbnMgcmUtdXNhYmxlIGRhdGEgdHlwZXMgdGhhdCB0b3BvbG9neSBhbmQgaW52ZW50b3J5IG1vZGVscwogICAgd2lsbCBmcmVxdWVudGx5IHVzZSBhcyBwYXJ0IG9mIHR5cGVzIGFuZCByZWxhdGlvbnNoaXBzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBncm91cGluZyBUb3BfR3JwX1R5cGUgewogICAgICAgIGRlc2NyaXB0aW9uICJHcm91cGluZyBjb250YWluaW5nIHRoZSBrZXkgYXR0cmlidXRlIGNvbW1vbiB0byBhbGwgdHlwZXMuCiAgICAgICAgICAgIEFsbCB0eXBlcyBNVVNUIHVzZSB0aGlzIGdyb3VwaW5nLiI7CgogICAgICAgIGxlYWYgaWQgewogICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVuaXF1ZSBpZGVudGlmaWVyIG9mIHRvcG9sb2d5IGVudGl0aWVzLiBSZXByZXNlbnRzIHRoZQogICAgICAgICAgICAgICAgRW50aXR5IEluc3RhbmNlIElkZW50aWZpZXIuIjsKICAgICAgICB9CiAgICB9CgogICAgY29udGFpbmVyIGRlY29yYXRvcnMgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGlzIGNvbnRhaW5lciBzZXJ2ZXMgYXMgZXh0ZW5zaW9uIHBvaW50IGZvciBhcHBsaWNhdGlvbnMgd2lzaGluZwogICAgICAgICAgICB0byBkZWZpbmUgdGhlaXIgb3duIGRlY29yYXRvcnMuIFRoaXMgaXMgZG9uZSB2aWEgYXVnbWVudGF0aW9ucy4gVGhleQogICAgICAgICAgICBjYW4gb25seSBiZSBkZWZpbmVkIGluIG5hbWUgdmFsdWUgcGFpci4KCiAgICAgICAgICAgIFRoaXMgaXMgYSBjb25zdW1lciBkYXRhIGFuZCBjYW4gYmUgYXR0YWNoZWQgdG8gVG9wb2xvZ3kgRW50aXR5IG9yCiAgICAgICAgICAgIFRvcG9sb2d5IFJlbGF0aW9uIGluc3RhbmNlLCBvdXRzaWRlIG9mIHRoZSBkZWNsYXJlZCBUb3BvbG9neSBFbnRpdHkKICAgICAgICAgICAgb3IgVG9wb2xvZ3kgUmVsYXRpb25zaGlwJ3MgYXR0cmlidXRlcy4gVGhpcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLAogICAgICAgICAgICBhbmQgaXQgTVVTVCBOT1QgYmUgYXVnbWVudGVkIG9yIGRldmlhdGVkIGluIGFueSB3YXksIHVubGVzcyBzdGF0ZWQKICAgICAgICAgICAgb3RoZXJ3aXNlLiI7CiAgICB9CgogICAgbGVhZi1saXN0IGNsYXNzaWZpZXJzIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiQ29uc3VtZXIgZGVmaW5lZCB0YWdzIHRvIHRvcG9sb2d5IGVudGl0aWVzIGFuZCByZWxhdGlvbnNoaXBzLgoKICAgICAgICAgICAgVGhpcyBpcyBhIGNvbnN1bWVyIGRhdGEgYW5kIGNhbiBiZSBhdHRhY2hlZCB0byBUb3BvbG9neSBFbnRpdHkgb3IKICAgICAgICAgICAgVG9wb2xvZ3kgUmVsYXRpb24gaW5zdGFuY2UsIG91dHNpZGUgb2YgdGhlIGRlY2xhcmVkIFRvcG9sb2d5IEVudGl0eQogICAgICAgICAgICBvciBUb3BvbG9neSBSZWxhdGlvbnNoaXAncyBhdHRyaWJ1dGVzLiBUaGlzIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQsCiAgICAgICAgICAgIGFuZCBpdCBNVVNUIE5PVCBiZSBhdWdtZW50ZWQgb3IgZGV2aWF0ZWQgaW4gYW55IHdheSwgdW5sZXNzIHN0YXRlZAogICAgICAgICAgICBvdGhlcndpc2UuIjsKCiAgICAgICAgdHlwZSBpZGVudGl0eXJlZiB7IGJhc2UgY2xhc3NpZmllcjsgfQogICAgfQoKICAgIGxlYWYtbGlzdCBzb3VyY2VJZHMgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJBbiBvcmRlcmVkIGxpc3Qgb2YgaWRlbnRpdGllcyB0aGF0IHJlcHJlc2VudCB0aGUgc2V0IG9mIG5hdGl2ZQogICAgICAgICAgICBzb3VyY2UgaWRlbnRpZmllcnMgZm9yIHBhcnRpY2lwYXRpbmcgZW50aXRpZXMuCgogICAgICAgICAgICBUaGlzIGlzIGEgY29uc3VtZXIgZGF0YSBhbmQgY2FuIGJlIGF0dGFjaGVkIHRvIFRvcG9sb2d5IEVudGl0eSBvcgogICAgICAgICAgICBUb3BvbG9neSBSZWxhdGlvbiBpbnN0YW5jZSwgb3V0c2lkZSBvZiB0aGUgZGVjbGFyZWQgVG9wb2xvZ3kgRW50aXR5CiAgICAgICAgICAgIG9yIFRvcG9sb2d5IFJlbGF0aW9uc2hpcCdzIGF0dHJpYnV0ZXMuIFRoaXMgY2Fubm90IGJlIGluc3RhbnRpYXRlZCwKICAgICAgICAgICAgYW5kIGl0IE1VU1QgTk9UIGJlIGF1Z21lbnRlZCBvciBkZXZpYXRlZCBpbiBhbnkgd2F5LCB1bmxlc3Mgc3RhdGVkCiAgICAgICAgICAgIG90aGVyd2lzZS4iOwoKICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICBvcmRlcmVkLWJ5IHVzZXI7CiAgICB9CgogICAgY29udGFpbmVyIG1ldGFkYXRhIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhpcyBjb250YWluZXIgc2VydmVzIGFzIGV4dGVuc2lvbiBwb2ludCB0byBkZWZpbmUgbWV0YWRhdGEuIFRoZXkKICAgICAgICAgICAgY2FuIG9ubHkgYmUgZGVmaW5lZCBpbiBuYW1lIHZhbHVlIHBhaXIuCgogICAgICAgICAgICBUaGlzIGlzIGEgY29uc3VtZXIgZGF0YSBhbmQgY2FuIGJlIGF0dGFjaGVkIHRvIFRvcG9sb2d5IEVudGl0eSBvcgogICAgICAgICAgICBUb3BvbG9neSBSZWxhdGlvbiBpbnN0YW5jZSwgb3V0c2lkZSBvZiB0aGUgZGVjbGFyZWQgVG9wb2xvZ3kgRW50aXR5CiAgICAgICAgICAgIG9yIFRvcG9sb2d5IFJlbGF0aW9uc2hpcCdzIGF0dHJpYnV0ZXMuIFRoaXMgY2Fubm90IGJlIGluc3RhbnRpYXRlZCwKICAgICAgICAgICAgYW5kIGl0IE1VU1QgTk9UIGJlIGF1Z21lbnRlZCBvciBkZXZpYXRlZCBpbiBhbnkgd2F5LCB1bmxlc3Mgc3RhdGVkCiAgICAgICAgICAgIG90aGVyd2lzZS4iOwogICAgfQoKICAgIGlkZW50aXR5IGNsYXNzaWZpZXJ7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjbGFzc2lmaWVyIGlzIHVzZWQgYXMgYSBiYXNlIHRvIHByb3ZpZGUgYWxsIGNsYXNzaWZpZXJzCiAgICAgICAgICAgIHdpdGggaWRlbnRpdHkuICI7CiAgICB9Cn0=
+o-ran-smo-teiv-equipment       urn:o-ran:smo-teiv-equipment    EQUIPMENT       []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWVxdWlwbWVudCB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtZXF1aXBtZW50IjsKICAgIHByZWZpeCBvci10ZWl2LWVxdWlwOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgeyBwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgICAgICBwcmVmaXggZ2VvOwogICAgICAgIHJlZmVyZW5jZSAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIkVxdWlwbWVudCB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgRXF1aXBtZW50CiAgICBkb21haW4sIHdoaWNoIGlzIG1vZGVsbGVkIHRvIHVuZGVyc3RhbmQgdGhlIHBoeXNpY2FsIGxvY2F0aW9uIG9mIGVxdWlwbWVudAogICAgc3VjaCBhcyBhbnRlbm5hcyBhc3NvY2lhdGVkIHdpdGggYSBjZWxsL2NhcnJpZXIgYW5kIHRoZWlyIHJlbGV2YW50CiAgICBwcm9wZXJ0aWVzIGUuZy4gdGlsdCwgbWF4IHBvd2VyIGV0Yy4iOwoKICAgIHJldmlzaW9uICIyMDI0LTA1LTI0IiB7CiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmRvbWFpbiBFUVVJUE1FTlQ7CgogICAgbGlzdCBBbnRlbm5hTW9kdWxlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gQW50ZW5uYSBNb2R1bGUgcmVwcmVzZW50cyB0aGUgcGh5c2ljYWwgYXNwZWN0IG9mIGFuCiAgICAgICAgICAgIGFudGVubmEuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBhbnRlbm5hTW9kZWxOdW1iZXIgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlZlbmRvci1zcGVjaWZpYyBhbnRlbm5hIG1vZGVsIGlkZW50aWZpZXIuIFRoaXMKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgaXMgcGFydCBvZiBBSVNHIHYzIEFEQiBTdGFuZGFyZCBhbmQgaGFzIG5vCiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uYWwgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBtZWNoYW5pY2FsQW50ZW5uYUJlYXJpbmcgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgYmVhcmluZyBvbiBhbnRlbm5hIHN1YnVuaXQgd2hlcmUgYW50ZW5uYQogICAgICAgICAgICAgICAgICAgIHVuaXQgaXMgaW5zdGFsbGVkLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG1lY2hhbmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGZpeGVkIGFudGVubmEgdGlsdCBvZiB0aGUgaW5zdGFsbGF0aW9uLCBkZWZpbmVkCiAgICAgICAgICAgICAgICAgICAgYXMgdGhlIGluY2xpbmF0aW9uIG9mIHRoZSBhbnRlbm5hIGVsZW1lbnQgcmVzcGVjdCB0byB0aGUKICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbCBwbGFuZS4gSXQgaXMgYSBzaWduZWQgdmFsdWUuIFBvc2l0aXZlIGluZGljYXRlcwogICAgICAgICAgICAgICAgICAgIGRvd250aWx0LCBhbmQgbmVnYXRpdmUgaW5kaWNhdGVzIHVwdGlsdC4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBwb3NpdGlvbldpdGhpblNlY3RvciB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSB1bml0IHBvc2l0aW9uIHdpdGhpbiBzZWN0b3IuIFRoaXMgYXR0cmlidXRlCiAgICAgICAgICAgICAgICAgICAgaXMgcGFydCBvZiBBSVNHIHYzIEFEQiBTdGFuZGFyZCBhbmQgaGFzIG5vIG9wZXJhdGlvbmFsCiAgICAgICAgICAgICAgICAgICAgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiB0b3RhbFRpbHQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRvdGFsIGFudGVubmEgZWxldmF0aW9uIGluY2x1ZGluZyB0aGUgaW5zdGFsbGVkCiAgICAgICAgICAgICAgICAgICAgdGlsdCBhbmQgdGhlIHRpbHQgYXBwbGllZCBieSB0aGUgUmVtb3RlIEVsZWN0cmljYWwKICAgICAgICAgICAgICAgICAgICBUaWx0IChSRVQpLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVsZWN0cmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiRWxlY3RyaWNhbGx5LWNvbnRyb2xsZWQgdGlsdCBvZiBtYWluIGJlYW0gbWF4aW11bQogICAgICAgICAgICAgICAgICAgIHdpdGggcmVzcGVjdCB0byBkaXJlY3Rpb24gb3J0aG9nb25hbCB0byBhbnRlbm5hIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICBheGlzIChzZWUgM0dQUCBUUyAyNS40NjYpLiBWYWx1ZSBpcyBzaWduZWQ7IHRpbHQgZG93biBpcwogICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlLCB0aWx0IHVwIGlzIG5lZ2F0aXZlLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgYW50ZW5uYUJlYW1XaWR0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGFuZ3VsYXIgc3BhbiBvZiB0aGUgbWFpbiBsb2JlIG9mIHRoZSBhbnRlbm5hCiAgICAgICAgICAgICAgICAgICAgcmFkaWF0aW9uIHBhdHRlcm4gaW4gdGhlIGhvcml6b250YWwgcGxhbmUuIE1lYXN1cmVkIGluCiAgICAgICAgICAgICAgICAgICAgZGVncmVlcy4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzZXMgZ2VvOmdlby1sb2NhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgbGlzdCBTaXRlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBzaXRlIGlzIGEgcGh5c2ljYWwgbG9jYXRpb24gd2hlcmUgYW4gZXF1aXBtZW50IGNhbiBiZQogICAgICAgICAgICBpbnN0YWxsZWQuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBuYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIFNpdGUiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzZXMgZ2VvOmdlby1sb2NhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBBTlRFTk5BTU9EVUxFX0lOU1RBTExFRF9BVF9TSVRFIHsgLy8gMC4ubiB0byAwLi4xCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmIGluc3RhbGxlZC1hdC1zaXRlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIGluc3RhbGxlZCBhdCBTaXRlLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgaW5zdGFsbGVkLWFudGVubmFNb2R1bGUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2l0ZSB3aGVyZSBBbnRlbm5hIE1vZHVsZSBpcyBpbnN0YWxsZWQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIFNpdGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9Cn0=
+o-ran-smo-teiv-oam     urn:o-ran:smo-teiv-oam  OAM     []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LW9hbSB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtb2FtIjsKICAgIHByZWZpeCBvci10ZWl2LW9hbTsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggb3ItdGVpdi10eXBlczsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHsgcHJlZml4IG9yLXRlaXYteWV4dDsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIk8mTSB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgTyZNIGRvbWFpbiwKICAgIHdoaWNoIGFyZSBpbnRlbmRlZCB0byByZXByZXNlbnQgbWFuYWdlbWVudCBzeXN0ZW1zIGFuZCBtYW5hZ2VtZW50CiAgICBpbnRlcmZhY2VzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIE9BTTsKCiAgICBsaXN0IE1hbmFnZWRFbGVtZW50IHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBNYW5hZ2VkIEVsZW1lbnQgKE1FKSBpcyBhIG5vZGUgaW50byBhIHRlbGVjb21tdW5pY2F0aW9uCiAgICAgICAgICAgIG5ldHdvcmsgcHJvdmlkaW5nIHN1cHBvcnQgYW5kL29yIHNlcnZpY2UgdG8gc3Vic2NyaWJlcnMuIEFuIE1FCiAgICAgICAgICAgIGNvbW11bmljYXRlcyB3aXRoIGEgbWFuYWdlciBhcHBsaWNhdGlvbiAoZGlyZWN0bHkgb3IgaW5kaXJlY3RseSkKICAgICAgICAgICAgb3ZlciBvbmUgb3IgbW9yZSBpbnRlcmZhY2VzIGZvciB0aGUgcHVycG9zZSBvZiBiZWluZyBtb25pdG9yZWQKICAgICAgICAgICAgYW5kL29yIGNvbnRyb2xsZWQuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CiAgICB9Cn0=
+o-ran-smo-teiv-ran     urn:o-ran:smo-teiv-ran  RAN     []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJhbiB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtcmFuIjsKICAgIHByZWZpeCBvci10ZWl2LXJhbjsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgXzNncHAtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggdHlwZXMzZ3BwOyB9CgogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgICAgICBwcmVmaXggZ2VvOwogICAgICAgIHJlZmVyZW5jZSAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgUkFOIGRvbWFpbiwKICAgIHdoaWNoIHJlcHJlc2VudHMgdGhlIGZ1bmN0aW9uYWwgY2FwYWJpbGl0eSBvZiB0aGUgZGVwbG95ZWQgUkFOIHRoYXQgYXJlCiAgICByZWxldmFudCB0byByQXBwcyB1c2UgY2FzZXMuIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0yNCIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIG9yLXRlaXYteWV4dDpkb21haW4gUkFOOwoKICAgIGxpc3QgR05CRFVGdW5jdGlvbiB7CiAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQiBEaXN0cmlidXRlZCBVbml0IChnTkItRFUpLgoKICAgICAgICAgICAgQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ2VudHJhbGl6ZWQgVW5pdCAoZ05CLUNVKSBhbmQgYSBnTkItRFUuCiAgICAgICAgICAgIFRoZSBDVSBwcm9jZXNzZXMgbm9uLXJlYWwgdGltZSBwcm90b2NvbHMgYW5kIHNlcnZpY2VzLCBhbmQgdGhlIERVCiAgICAgICAgICAgIHByb2Nlc3NlcyBQSFkgbGV2ZWwgcHJvdG9jb2wgYW5kIHJlYWwgdGltZSBzZXJ2aWNlcy4gVGhlIGdOQi1DVSBhbmQKICAgICAgICAgICAgdGhlIGdOQi1EVSB1bml0cyBhcmUgY29ubmVjdGVkIHZpYSBGMSBsb2dpY2FsIGludGVyZmFjZS4KCiAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgaXMgdHJ1ZSBmb3IgYSBnTkItRFU6CiAgICAgICAgICAgIElzIGNvbm5lY3RlZCB0byB0aGUgZ05CLUNVLUNQIHRocm91Z2ggdGhlIEYxLUMgaW50ZXJmYWNlLiBJcwogICAgICAgICAgICBjb25uZWN0ZWQgdG8gdGhlIGdOQi1DVS1VUCB0aHJvdWdoIHRoZSBGMS1VIGludGVyZmFjZS4gT25lIGdOQi1EVSBpcwogICAgICAgICAgICBjb25uZWN0ZWQgdG8gb25seSBvbmUgZ05CLUNVLUNQLiBPbmUgZ05CLURVIGNhbiBiZSBjb25uZWN0ZWQgdG8KICAgICAgICAgICAgbXVsdGlwbGUgZ05CLUNVLVVQcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUgc2FtZSBnTkItQ1UtQ1AuCgogICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUgZ05CLUNVLVVQcyBhbmQKICAgICAgICAgICAgbXVsdGlwbGUgZ05CLURVcy4gZ05CLURVIGlzIGEgY29uY3JldGUgY2xhc3MgdGhhdCBleHRlbmRzIHRoZSBORy1SQU4KICAgICAgICAgICAgbm9kZSBvYmplY3QuIEluIFRvcG9sb2d5LCB5b3UgY2FuIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQgZGVsZXRlCiAgICAgICAgICAgIHRoZSBnTkItRFUgb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGNvbnRhaW5lciBkVXBMTU5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBpZGVudGlmaWVyIHVzZWQgYXMgcGFydCBvZiBQTSBFdmVudHMgZGF0YSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZ05CRFVJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBEVSB3aXRoaW4gYSBnTm9kZUIiOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEdOQkNVQ1BGdW5jdGlvbiB7CiAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQiBDZW50cmFsaXplZCBVbml0IENvbnRyb2wgUGxhbmUgKGdOQi1DVS1DUCkKCiAgICAgICAgICAgIFRoaXMgaXMgYSBsb2dpY2FsIG5vZGUgaG9zdGluZyB0aGUgUmFkaW8gUmVzb3VyY2UgQ29udHJvbCAoUlJDKSBhbmQKICAgICAgICAgICAgdGhlIGNvbnRyb2wgcGxhbmUgcGFydCBvZiB0aGUgUGFja2V0IERhdGEgQ29udmVyZ2VuY2UgUHJvdG9jb2wKICAgICAgICAgICAgKFBEQ1ApIG9mIHRoZSBnTm9kZUIgQ2VudHJhbGl6ZWQgVW5pdCAoZ05CLUNVKSBmb3IgYW4gRS1VVFJBTiBnTm9kZUIKICAgICAgICAgICAgKGVuLWdOQikgb3IgYSBnTm9kZUIgKGdOQikuIFRoZSBnTkItQ1UtQ1AgdGVybWluYXRlcyB0aGUgRTEKICAgICAgICAgICAgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTkItQ1UtVVAgYW5kIHRoZSBGMS1DIGludGVyZmFjZQogICAgICAgICAgICBjb25uZWN0ZWQgd2l0aCB0aGUgZ05vZGVCIERpc3RyaWJ1dGVkIFVuaXQgKGdOQi1EVSkuCgogICAgICAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIGEgZ05CLUNVLUNQOgogICAgICAgICAgICBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1EVSB0aHJvdWdoIHRoZSBGMS1DIGludGVyZmFjZS4gSXMgY29ubmVjdGVkCiAgICAgICAgICAgIHRvIHRoZSBnTkItQ1UtVVAgdGhyb3VnaCB0aGUgRTEgaW50ZXJmYWNlLiBPbmx5IG9uZSBnTkItQ1UtQ1AgaXMKICAgICAgICAgICAgY29ubmVjdGVkIHRvIG9uZSBnTkItRFUuIE9ubHkgb25lIGdOQi1DVS1DUCBpcyBjb25uZWN0ZWQgdG8gb25lCiAgICAgICAgICAgIGdOQi1DVS1VUC4gT25lIGdOQi1EVSBjYW4gYmUgY29ubmVjdGVkIHRvIG11bHRpcGxlIGdOQi1DVS1VUHMgdW5kZXIKICAgICAgICAgICAgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLk9uZSBnTkItQ1UtVVAgY2FuIGJlIGNvbm5lY3RlZCB0bwogICAgICAgICAgICBtdWx0aXBsZSBEVXMgdW5kZXIgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLgoKICAgICAgICAgICAgTm90ZTogQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ1UtQ1AsIG11bHRpcGxlIGdOQi1DVS1VUHMgYW5kCiAgICAgICAgICAgIG11bHRpcGxlIGdOQi1EVXMuIEEgZ05CLUNVLUNQIGlzIGEgY29uY3JldGUgY2xhc3MgdGhhdCBleHRlbmRzIHRoZQogICAgICAgICAgICBORy1SQU4gbm9kZSBvYmplY3QuIEluIFRvcG9sb2d5LCB5b3UgY2FuIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQKICAgICAgICAgICAgZGVsZXRlIHRoZSBnTkItQ1UtQ1Agb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZ05CQ1VOYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIGdOb2RlQi1DVSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIHBMTU5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBpZGVudGlmaWVyIHRvIGJlIHVzZWQgYXMgcGFydCBvZiBnbG9iYWwgUkFOCiAgICAgICAgICAgICAgICAgICAgbm9kZSBpZGVudGl0eSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBHTkJDVVVQRnVuY3Rpb24gewogICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUIgQ2VudHJhbGl6ZWQgVW5pdCBVc2VyIFBsYW5lIChnTkItQ1UtVVApCgogICAgICAgICAgICBBIGdOQi1DVS1VUCBpcyBhIGxvZ2ljYWwgbm9kZSBob3N0aW5nIHRoZSBVc2VyIFBsYW5lIHBhcnQgb2YgdGhlCiAgICAgICAgICAgIFBhY2tldCBEYXRhIENvbnZlcmdlbmNlLCBQcm90b2NvbCAoUERDUCkgb2YgdGhlIGdOb2RlQiBDZW50cmFsaXplZAogICAgICAgICAgICBVbml0IChnTkItQ1UpIGZvciBhbiBFLVVUUkFOIGdOb2RlQiAoZW4tZ05CKSwgYW5kIHRoZSBVc2VyIFBsYW5lCiAgICAgICAgICAgIHBhcnQgb2YgdGhlIFBEQ1AgcHJvdG9jb2wgYW5kIHRoZSBTZXJ2aWNlIERhdGEgQWRhcHRhdGlvbiBQcm90b2NvbAogICAgICAgICAgICAoU0RBUCkgb2YgdGhlIGdOQi1DVSBmb3IgYSBnTm9kZUIgKGdOQikuIFRoZSBnTkItQ1UtVVAgdGVybWluYXRlcwogICAgICAgICAgICB0aGUgRTEgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTkItQ1UtQ1AgYW5kIHRoZSBGMS1VIGludGVyZmFjZQogICAgICAgICAgICBjb25uZWN0ZWQgd2l0aCB0aGUgZ05vZGVCIERpc3RyaWJ1dGVkIFVuaXQgKGdOQi1EVSkuCgogICAgICAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIGEgZ05CLUNVLVVQOgogICAgICAgICAgICBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1EVSB0aHJvdWdoIHRoZSBGMS1VIGludGVyZmFjZS4gSXMgY29ubmVjdGVkCiAgICAgICAgICAgIHRvIHRoZSBnTkItQ1UtQ1AgdGhyb3VnaCB0aGUgRTEgaW50ZXJmYWNlLiBPbmUgZ05CLUNVLVVQIGlzCiAgICAgICAgICAgIGNvbm5lY3RlZCB0byBvbmx5IG9uZSBnTkItQ1UtQ1AuIE9uZSBnTkItRFUgY2FuIGJlIGNvbm5lY3RlZCB0bwogICAgICAgICAgICBtdWx0aXBsZSBnTkItQ1UtVVBzIHVuZGVyIHRoZSBjb250cm9sIG9mIHRoZSBzYW1lIGdOQi1DVS1DUC4gT25lCiAgICAgICAgICAgIGdOQi1DVS1VUCBjYW4gYmUgY29ubmVjdGVkIHRvIG11bHRpcGxlIERVcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUKICAgICAgICAgICAgc2FtZSBnTkItQ1UtQ1AuCgogICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUgZ05CLUNVLVVQcyBhbmQKICAgICAgICAgICAgbXVsdGlwbGUgZ05CLURVcy4gQSBnTkItQ1UtVVAgaXMgYSBjb25jcmV0ZSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCiAgICAgICAgICAgIE5HLVJBTiBub2RlIG9iamVjdC4gSW4gVG9wb2xvZ3ksIHlvdSBjYW4gY3JlYXRlLCByZWFkLCB1cGRhdGUsIGFuZAogICAgICAgICAgICBkZWxldGUgdGhlIGdOQi1DVS1VUCBvYmplY3QuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IE5SQ2VsbENVIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyBhbiBOUiBDZWxsIGluIGdOb2RlQi1DVS4KCiAgICAgICAgICAgIDVHIE5SIGlzIGEgbmV3IHJhZGlvIGFjY2VzcyB0ZWNobm9sb2d5IChSQVQpIGRldmVsb3BlZCBieSAzR1BQIGZvcgogICAgICAgICAgICB0aGUgNUcgKGZpZnRoIGdlbmVyYXRpb24pIG1vYmlsZSBuZXR3b3JrLiBJdCBpcyBkZXNpZ25lZCB0byBiZSB0aGUKICAgICAgICAgICAgZ2xvYmFsIHN0YW5kYXJkIGZvciB0aGUgYWlyIGludGVyZmFjZSBvZiA1RyBuZXR3b3Jrcy4KCiAgICAgICAgICAgIDVHIE5SIGhhcyBzeW5jaHJvbml6YXRpb24gc2lnbmFsIHRoYXQgaXMga25vd24gYXMgUHJpbWFyeQogICAgICAgICAgICBTeW5jaHJvbml6YXRpb24gU2lnbmFsIChQU1MpIGFuZCBTZWNvbmRhcnkgU3luY2hyb25pemF0aW9uCiAgICAgICAgICAgIFNpZ25hbCAoU1NTKS4gVGhlc2Ugc2lnbmFscyBhcmUgc3BlY2lmaWMgdG8gTlIgcGh5c2ljYWwgbGF5ZXIgYW5kCiAgICAgICAgICAgIHByb3ZpZGUgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiByZXF1aXJlZCBieSBVRSBmb3IgZG93bmxpbmsKICAgICAgICAgICAgc3luY2hyb25pemF0aW9uOiBQU1MgcHJvdmlkZXMgUmFkaW8gRnJhbWUgQm91bmRhcnkgKFBvc2l0aW9uIG9mIDFzdAogICAgICAgICAgICBTeW1ib2wgaW4gYSBSYWRpbyBmcmFtZSkgU1NTIHByb3ZpZGVzIFN1YmZyYW1lIEJvdW5kYXJ5IChQb3NpdGlvbiBvZgogICAgICAgICAgICAxc3QgU3ltYm9sIGluIGEgU3ViZnJhbWUpIFBoeXNpY2FsIExheWVyIENlbGwgSUQgKFBDSSkgaW5mb3JtYXRpb24KICAgICAgICAgICAgdXNpbmcgYm90aCBQU1MgYW5kIFNTUy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGNlbGxMb2NhbElkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJVc2VkIHRvZ2V0aGVyIHdpdGggZ05vZGVCIGlkZW50aWZpZXIgdG8gaWRlbnRpZnkgTlIKICAgICAgICAgICAgICAgICAgICBjZWxsIGluIFBMTU4uIFVzZWQgdG9nZXRoZXIgd2l0aCBnTkJJZCB0byBmb3JtIE5DSS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIHBsbW5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBJRCBmb3IgTlIgQ0dJLiBJZiBlbXB0eSwKICAgICAgICAgICAgICAgICAgICBHTkJDVUNQRnVuY3Rpb246OnBMTU5JZCBpcyB1c2VkIGZvciBQTE1OIElEIGluIE5SIENHSSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgbkNJIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsIElkZW50aXR5IjsKICAgICAgICAgICAgICAgIHR5cGUgaW50NjQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgblJUQUMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKSI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTlJDZWxsRFUgewogICAgICAgIGRlc2NyaXB0aW9uICJSZXByZXNlbnRzIGFuIE5SIENlbGwgaW4gZ05vZGVCLURVLgoKICAgICAgICAgICAgNUcgTlIgaXMgYSBuZXcgcmFkaW8gYWNjZXNzIHRlY2hub2xvZ3kgKFJBVCkgZGV2ZWxvcGVkIGJ5IDNHUFAgZm9yCiAgICAgICAgICAgIHRoZSA1RyAoZmlmdGggZ2VuZXJhdGlvbikgbW9iaWxlIG5ldHdvcmsuIEl0IGlzIGRlc2lnbmVkIHRvIGJlIHRoZQogICAgICAgICAgICBnbG9iYWwgc3RhbmRhcmQgZm9yIHRoZSBhaXIgaW50ZXJmYWNlIG9mIDVHIG5ldHdvcmtzLgoKICAgICAgICAgICAgNUcgTlIgaGFzIHN5bmNocm9uaXphdGlvbiBzaWduYWwgdGhhdCBpcyBrbm93biBhcyBQcmltYXJ5CiAgICAgICAgICAgIFN5bmNocm9uaXphdGlvbiBzaWduYWwgKFBTUykgYW5kIFNlY29uZGFyeSBTeW5jaHJvbml6YXRpb24gc2lnbmFsCiAgICAgICAgICAgIChTU1MpLiBUaGVzZSBzaWduYWxzIGFyZSBzcGVjaWZpYyB0byBOUiBwaHlzaWNhbCBsYXllciBhbmQgcHJvdmlkZQogICAgICAgICAgICB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIHJlcXVpcmVkIGJ5IFVFIGZvciBkb3dubGluawogICAgICAgICAgICBzeW5jaHJvbml6YXRpb246IFBTUyBwcm92aWRlcyBSYWRpbyBGcmFtZSBCb3VuZGFyeSAoUG9zaXRpb24gb2YgMXN0CiAgICAgICAgICAgIFN5bWJvbCBpbiBhIFJhZGlvIGZyYW1lKSBTU1MgcHJvdmlkZXMgU3ViZnJhbWUgQm91bmRhcnkgKFBvc2l0aW9uIG9mCiAgICAgICAgICAgIDFzdCBTeW1ib2wgaW4gYSBTdWJmcmFtZSkgUGh5c2ljYWwgTGF5ZXIgQ2VsbCBJRCAoUENJKSBpbmZvcm1hdGlvbgogICAgICAgICAgICB1c2luZyBib3RoIFBTUyBhbmQgU1NTLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgY2VsbExvY2FsSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVzZWQgdG9nZXRoZXIgd2l0aCBnTm9kZUIgaWRlbnRpZmllciB0byBpZGVudGlmeSBOUgogICAgICAgICAgICAgICAgICAgIGNlbGwgaW4gUExNTi4gVXNlZCB0b2dldGhlciB3aXRoIGdOQklkIHRvIGZvcm0gTkNJLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG5DSSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbCBJZGVudGl0eS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBuUlBDSSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIFBoeXNpY2FsIENlbGwgSWRlbnRpdHkgKFBDSSkgb2YgdGhlIE5SIGNlbGwuIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgblJUQUMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEVOb2RlQkZ1bmN0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gRXZvbHZlZCBOb2RlIEIgKGVOb2RlQikgaXMgdGhlIG9ubHkgbWFuZGF0b3J5IG5vZGUgaW4KICAgICAgICAgICAgdGhlIHJhZGlvIGFjY2VzcyBuZXR3b3JrIChSQU4pIG9mIExvbmctVGVybSBFdm9sdXRpb24gKExURSkuIFRoZQogICAgICAgICAgICBlTm9kZUIgaXMgYSBjb21wbGV4IGJhc2Ugc3RhdGlvbiB0aGF0IGhhbmRsZXMgcmFkaW8gY29tbXVuaWNhdGlvbnMKICAgICAgICAgICAgaW4gdGhlIGNlbGwgYW5kIGNhcnJpZXMgb3V0IHJhZGlvIHJlc291cmNlIG1hbmFnZW1lbnQgYW5kIGhhbmRvdmVyCiAgICAgICAgICAgIGRlY2lzaW9ucy4gVW5saWtlIDIvM0cgd2lyZWxlc3MgUkFOLCB0aGVyZSBpcyBubyBjZW50cmFsaXplZCByYWRpbwogICAgICAgICAgICBuZXR3b3JrIGNvbnRyb2xsZXIgaW4gTFRFLiBJdCBpcyB0aGUgaGFyZHdhcmUgdGhhdCBpcyBjb25uZWN0ZWQgdG8KICAgICAgICAgICAgdGhlIG1vYmlsZSBwaG9uZSBuZXR3b3JrIHRoYXQgY29tbXVuaWNhdGVzIGRpcmVjdGx5IHdpdGggbW9iaWxlCiAgICAgICAgICAgIGhhbmRzZXRzIChVc2VyIEVxdWlwbWVudCksIGxpa2UgYSBiYXNlIHRyYW5zY2VpdmVyIHN0YXRpb24gKEJUUykgaW4KICAgICAgICAgICAgR1NNIG5ldHdvcmtzLiBUaGlzIHNpbXBsaWZpZXMgdGhlIGFyY2hpdGVjdHVyZSBhbmQgYWxsb3dzIGxvd2VyCiAgICAgICAgICAgIHJlc3BvbnNlIHRpbWVzLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZU5CSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgSUQgdGhhdCBmb3JtcyBwYXJ0IG9mIHRoZSBDZWxsIEdsb2JhbAogICAgICAgICAgICAgICAgICAgIElkZW50aXR5LCBhbmQgaXMgYWxzbyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIG92ZXIgdGhlIFMxCiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBlTm9kZUJQbG1uSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgUHVibGljIExhbmQgTW9iaWxlIE5ldHdvcmsgKFBMTU4pIElECiAgICAgICAgICAgICAgICAgICAgdGhhdCBmb3JtcyBwYXJ0IG9mIHRoZSBFTm9kZUIgR2xvYmFsIElEIHVzZWQgdG8gaWRlbnRpZnkgdGhlCiAgICAgICAgICAgICAgICAgICAgbm9kZSBvdmVyIHRoZSBTMSBpbnRlcmZhY2UuIE5vdGU6IFRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIChNQ0M9MDAxLCBNTkM9MDEpIGluZGljYXRlcyB0aGF0IHRoZSBQTE1OIGlzIG5vdCBpbml0aWF0ZWQuCiAgICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIGNhbiBub3QgYmUgdXNlZCBhcyBhIHZhbGlkIFBMTU4gSWRlbnRpdHkuIjsKCiAgICAgICAgICAgICAgICBsZWFmIG1jYyB7CiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBNQ0MgcGFydCBvZiBhIFBMTU4gaWRlbnRpdHkgdXNlZCBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgcmFkaW8gbmV0d29yay4iOwogICAgICAgICAgICAgICAgICAgIHR5cGUgaW50MzIgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZSAwLi45OTk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGVhZiBtbmMgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTU5DIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5IHVzZWQgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgIHJhZGlvIG5ldHdvcmsuIjsKICAgICAgICAgICAgICAgICAgICB0eXBlIGludDMyIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgMC4uOTk5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxlYWYgbW5jTGVuZ3RoIHsKICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGxlbmd0aCBvZiB0aGUgTU5DIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5CiAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgaW4gdGhlIHJhZGlvIG5ldHdvcmsuIjsKICAgICAgICAgICAgICAgICAgICB0eXBlIGludDMyIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgMi4uMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBFVXRyYW5DZWxsIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyBhbiBGREQgb3IgVEREIEVVdHJhbkNlbGwgYW5kCiAgICAgICAgICAgICAgICAgICAgY29udGFpbnMgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNlbGwuCiAgICAgICAgICAgICAgICAgICAgSXQgYWxzbyBjb250YWlucyBwYXJhbWV0ZXJzIGZvciB0aGUKICAgICAgICAgICAgICAgICAgICBtYW5kYXRvcnkgY29tbW9uIGNoYW5uZWxzLiBBbiBFVVRSQU4gc3RhbmRzCiAgICAgICAgICAgICAgICAgICAgZm9yIEV2b2x2ZWQgVW5pdmVyc2FsIE1vYmlsZSBUZWxlY29tbXVuaWNhdGlvbnMKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0gKFVNVFMpIFRlcnJlc3RyaWFsIFJhZGlvIEFjY2VzcyBOZXR3b3JrCiAgICAgICAgICAgICAgICAgICAgd2hpY2ggY29udGFpbnMgYW4gZU5vZGVCLiBUaGUgZU5vZGVCIGNvbmNyZXRlCiAgICAgICAgICAgICAgICAgICAgY2xhc3MgaXMgZXh0ZW5kZWQgZnJvbSB0aGUgRVVUUkFOIE5vZGUgYWJzdHJhY3QgY2xhc3MuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBjZWxsSWR7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUkJTIGludGVybmFsIElEIGF0dHJpYnV0ZSBmb3IgRVV0cmFuQ2VsbC4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIHVuaXF1ZSBpbiB0aGUgUkJTLiBUb2dldGhlciB3aXRoIHRoZSBOb2RlIElEIGFuZCBQdWJsaWMKICAgICAgICAgICAgICAgICAgICBMYW5kIE1vYmlsZSBOZXR3b3JrIChQTE1OKSB0aGlzIGlzIGEgdW5pdmVyc2FsbHkgdW5pcXVlCiAgICAgICAgICAgICAgICAgICAgY2VsbCBJRCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVhcmZjbmRsIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgY2hhbm5lbCBudW1iZXIgZm9yIHRoZSBjZW50cmFsIGRvd25saW5rCiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5LiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVhcmZjbnVsIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJDaGFubmVsIG51bWJlciBmb3IgdGhlIGNlbnRyYWwgdXBsaW5rIGZyZXF1ZW5jeSI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGRsQ2hhbm5lbEJhbmR3aWR0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGRvd25saW5rIGNoYW5uZWwgYmFuZHdpZHRoIGluIHRoZSBGREQgY2VsbC4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBlYXJmY24gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFLVVUUkEgQWJzb2x1dGUgUmFkaW8gRnJlcXVlbmN5IENoYW5uZWwgTnVtYmVyCiAgICAgICAgICAgICAgICAgICAgKEVBUkZDTikgZm9yIHRoZSBUREQgY2VsbCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGNoYW5uZWxCYW5kd2lkdGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjaGFubmVsIGJhbmR3aWR0aCBpbiB0aGUgVEREIGNlbGwuIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgdGFjIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUcmFja2luZyBBcmVhIENvZGUgZm9yIHRoZSBFVXRyYW4gQ2VsbCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGR1cGxleFR5cGUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkluZGljYXRvciBvZiBFVXRyYW5DZWxsIHR5cGUsIEZERCBvciBUREQiOwogICAgICAgICAgICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgZW51bSBmZGQgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiRkREIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSB0ZGQgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAxOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVEREIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBOUlNlY3RvckNhcnJpZXIgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTlIgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZSBhdHRyaWJ1dGVzIGZvcgogICAgICAgICAgICBkZWZpbmluZyB0aGUgbG9naWNhbCBjaGFyYWN0ZXJpc3RpY3Mgb2YgYSBjYXJyaWVyIChjZWxsKSBpbiBhCiAgICAgICAgICAgIHNlY3Rvci4gQSBzZWN0b3IgaXMgYSBjb3ZlcmFnZSBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbgogICAgICAgICAgICBoYXZpbmcgaXRzIG93biBhbnRlbm5hcywgcmFkaW8gcG9ydHMsIGFuZCBjb250cm9sIGNoYW5uZWxzLiBUaGUKICAgICAgICAgICAgY29uY2VwdCBvZiBzZWN0b3JzIHdhcyBkZXZlbG9wZWQgdG8gaW1wcm92ZSBjby1jaGFubmVsIGludGVyZmVyZW5jZQogICAgICAgICAgICBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zIHVzZSB0aHJlZSBzZWN0b3IKICAgICAgICAgICAgY2VsbHMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBhcmZjbkRMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBBYnNvbHV0ZSBSYWRpbyBGcmVxdWVuY3kgQ2hhbm5lbCBOdW1iZXIKICAgICAgICAgICAgICAgICAgICAoTlItQVJGQ04pIGZvciBkb3dubGluayI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGFyZmNuVUwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIEFic29sdXRlIFJhZGlvIGZyZXF1ZW5jeSBDaGFubmVsIE51bWJlcgogICAgICAgICAgICAgICAgICAgIChOUi1BUkZDTikgZm9yIHVwbGluay4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBmcmVxdWVuY3lETCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUkYgUmVmZXJlbmNlIEZyZXF1ZW5jeSBvZiBkb3dubGluayBjaGFubmVsIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZnJlcXVlbmN5VUwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlJGIFJlZmVyZW5jZSBGcmVxdWVuY3kgb2YgdXBsaW5rIGNoYW5uZWwiOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBiU0NoYW5uZWxCd0RMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJCUyBDaGFubmVsIGJhbmR3aWR0aCBpbiBNSHogZm9yIGRvd25saW5rLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTFRFU2VjdG9yQ2FycmllciB7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBMVEUgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZSBhdHRyaWJ1dGVzIGZvcgogICAgICAgICAgICBkZWZpbmluZyB0aGUgbG9naWNhbCBjaGFyYWN0ZXJpc3RpY3Mgb2YgYSBjYXJyaWVyIChjZWxsKSBpbiBhCiAgICAgICAgICAgIHNlY3Rvci4gQSBzZWN0b3IgaXMgYSBjb3ZlcmFnZSBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbgogICAgICAgICAgICBoYXZpbmcgaXRzIG93biBhbnRlbm5hcywgcmFkaW8gcG9ydHMsIGFuZCBjb250cm9sIGNoYW5uZWxzLiBUaGUKICAgICAgICAgICAgY29uY2VwdCBvZiBzZWN0b3JzIHdhcyBkZXZlbG9wZWQgdG8gaW1wcm92ZSBjby1jaGFubmVsIGludGVyZmVyZW5jZQogICAgICAgICAgICBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zIHVzZSB0aHJlZSBzZWN0b3IKICAgICAgICAgICAgY2VsbHMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBzZWN0b3JDYXJyaWVyVHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzZWN0b3IgY2FycmllcgogICAgICAgICAgICAgICAgICAgIG1vZGVsbGVkIGJ5IE1PIFNlY3RvckNhcnJpZXIgaXMgYSBkaWdpdGFsIHNlY3Rvci4iOwogICAgICAgICAgICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgZW51bSBub3JtYWxfc2VjdG9yIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgMDsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5vdCBhIGRpZ2l0YWwgc2VjdG9yIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBsZWZ0X2RpZ2l0YWxfc2VjdG9yIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgMTsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxlZnQgZGlnaXRhbCBzZWN0b3IgZm9yIDJEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gcmlnaHRfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAyOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUmlnaHQgZGlnaXRhbCBzZWN0b3IgZm9yIDJEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gbGVmdF9kaWdpdGFsX3NlY3Rvcl8zZHMgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAzOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVmdCBkaWdpdGFsIHNlY3RvciBmb3IgM0RTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSByaWdodF9kaWdpdGFsX3NlY3Rvcl8zZHMgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA0OwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUmlnaHQgZGlnaXRhbCBzZWN0b3IgZm9yIDNEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gbWlkZGxlX2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDU7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNaWRkbGUgZGlnaXRhbCBzZWN0b3IgZm9yIDNEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgQW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIE1PIHNlcnZlcyBhcyBhIG1hcHBpbmcgYmV0d2VlbiB0aGUgY2VsbCBhbmQgdGhlIFJCUwogICAgICAgICAgICBlcXVpcG1lbnQgdXNlZCB0byBwcm92aWRlIGNvdmVyYWdlIGluIGEgY2VydGFpbiBnZW9ncmFwaGljYWwgYXJlYS4KICAgICAgICAgICAgVGhlIE1PIGFsc28gY29udHJvbHMgdGhlIG1heGltdW0gb3V0cHV0IHBvd2VyIG9mIHRoZSBzZWN0b3IuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZi1saXN0IGVVdHJhbkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgTFRFIGZyZXF1ZW5jeSBiYW5kcyB0aGF0IGFzc29jaWF0ZWQKICAgICAgICAgICAgICAgICAgICBoYXJkd2FyZSBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZi1saXN0IGdlcmFuRnFCYW5kcyB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGlzdCBvZiBHRVJBTiBmcmVxdWVuY3kgYmFuZHMgdGhhdCBhc3NvY2lhdGVkCiAgICAgICAgICAgICAgICAgICAgaGFyZHdhcmUgc3VwcG9ydHMiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYtbGlzdCBuUkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgTlIgZnJlcXVlbmN5IGJhbmRzIGFzc29jaWF0ZWQgaGFyZHdhcmUKICAgICAgICAgICAgICAgICAgICBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IFNlY3RvciB7CiAgICAgICAgZGVzY3JpcHRpb24gIkEgZ3JvdXAgb2YgY28tbG9jYXRlZCBDZWxscyB0aGF0IGhhdmUgYSBzaGFyZWQKICAgICAgICAgICAgY292ZXJhZ2UgYXJlYS4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIHNlY3RvcklkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJVbml2ZXJzYWxseSB1bmlxdWUgSUQgZ2VuZXJhdGVkIGJ5IHRoZSBzZWN0b3IncwogICAgICAgICAgICAgICAgICAgIGRpc2NvdmVyeSBtZWNoYW5pc20uIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDY0OwogICAgICAgICAgICB9CgogICAgICAgICAgICB1c2VzIGdlbzpnZW8tbG9jYXRpb247CgogICAgICAgICAgICBsZWFmIGF6aW11dGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkF2ZXJhZ2UgdmFsdWUgb2YgdGhlIGF6aW11dGhzIG9mIHRoZSBjZWxscwogICAgICAgICAgICAgICAgICAgIGNvbXByaXNpbmcgdGhlIHNlY3RvciwgZGV0ZXJtaW5lZCBkdXJpbmcgc2VjdG9yIGRpc2NvdmVyeS4iOwogICAgICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjR7CiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1bml0cyAiZGVncmVlcyI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfRVVUUkFOQ0VMTCB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIEVVVFJBTiBDZWxsLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBFTm9kZUJGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBwcm92aWRlZC1ieS1lbm9kZWJGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCBwcm92aWRlZCBieSBlTm9kZUIgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEVVdHJhbkNlbGw7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHByb3ZpZGVkIGJ5IGVOb2RlQiBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTFRFU2VjdG9yQ2FycmllcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBHTkJEVUZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTERVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIENlbGwtRFUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIEdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZ25iZHVGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLURVIHByb3ZpZGVkIGJ5IGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CRFVGVU5DVElPTl9QUk9WSURFU19OUlNFQ1RPUkNBUlJJRVIgeyAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBwcm92aWRlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBHTkJEVUZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmR1RnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgU2VjdG9yIENhcnJpZXIgcHJvdmlkZWQgYnkgZ05vZGVCLURVIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUlNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CQ1VDUEZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTENVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsQ3UgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVQ1AgRnVuY3Rpb24gcHJvdmlkZXMgTlIgQ2VsbC1DVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgR05CQ1VDUEZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLUNVIHByb3ZpZGVkIGJ5IGdOb2RlQi1DVUNQIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUkNlbGxDVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBFVVRSQU5DRUxMX1VTRVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHVzZWQtbHRlU2VjdG9yQ2FycmllciB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCB1c2VzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRVV0cmFuQ2VsbDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgRVVUUkFOIENlbGwuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBMVEVTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMVEUgU2VjdG9yIENhcnJpZXIgdXNlcyBBbnRlbm5hIENhcGFiaWxpdHkuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYtbGlzdCB1c2VkLWJ5LWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTFRFIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBBbnRlbm5hQ2FwYWJpbGl0eTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5SQ0VMTERVX1VTRVNfTlJTRUNUT1JDQVJSSUVSIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSB1c2VzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBOUkNlbGxEVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LW5yQ2VsbER1IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgTlIgQ2VsbC1EVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTlJTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBTZWN0b3IgQ2FycmllciB1c2VzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1ieS1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTlIgU2VjdG9yIENhcnJpZXIuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgU0VDVE9SX0dST1VQU19OUkNFTExEVSB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IGdyb3VwZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBOUiBDZWxsLURVLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBTZWN0b3I7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgZ3JvdXBlZC1ieS1zZWN0b3IgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSBncm91cGVkIGJ5IFNlY3Rvci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBTRUNUT1JfR1JPVVBTX0VVVFJBTkNFTEwgeyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBFVVRSQU4gQ2VsbC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgU2VjdG9yOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGdyb3VwZWQtYnktc2VjdG9yIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkVVVFJBTiBDZWxsIGdyb3VwZWQgYnkgU2VjdG9yLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBFVXRyYW5DZWxsOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQp9
+o-ran-smo-teiv-rel-equipment-ran       urn:o-ran:smo-teiv-rel-equipment-ran    REL_EQUIPMENT_RAN       ["o-ran-smo-teiv-equipment", "o-ran-smo-teiv-ran"]      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJlbC1lcXVpcG1lbnQtcmFuIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1yZWwtZXF1aXBtZW50LXJhbiI7CiAgICBwcmVmaXggb3ItdGVpdi1yZWwtZXF1aXByYW47CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsgcHJlZml4IG9yLXRlaXYtdHlwZXM7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7IHByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtZXF1aXBtZW50IHsgcHJlZml4IG9yLXRlaXYtZXF1aXA7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtcmFuIHsgcHJlZml4IG9yLXRlaXYtcmFuOyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiRXF1aXBtZW50IGFuZCBSQU4gdG9wb2xvZ3kgcmVsYXRpb24gbW9kZWwuCgogICAgQ29weXJpZ2h0IChjKSAyMDI0IEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKICAgIFRoaXMgbW9kZWwgY29udGFpbnMgdGhlIHRvcG9sb2d5IHJlbGF0aW9ucyBiZXR3ZWVuIEVxdWlwbWVudCBhbmQgUkFOLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIFJFTF9FUVVJUE1FTlRfUkFOOwoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgQU5URU5OQU1PRFVMRV9TRVJWRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLm0KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBzZXJ2aWNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIENhcGFiaWxpdHkgc2VydmljZWQgYnkgdGhpcyBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1lcXVpcDpBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1hbnRlbm5hTW9kdWxlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIHNlcnZlcyB0aGlzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46QW50ZW5uYUNhcGFiaWxpdHk7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBTRUNUT1JfR1JPVVBTX0FOVEVOTkFNT0RVTEUgeyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWFudGVubmFNb2R1bGUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1yYW46U2VjdG9yOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGdyb3VwZWQtYnktc2VjdG9yIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIGdyb3VwZWQgYnkgU2VjdG9yLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LWVxdWlwOkFudGVubmFNb2R1bGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9Cn0=
+o-ran-smo-teiv-rel-oam-ran     urn:o-ran:smo-teiv-rel-oam-ran  REL_OAM_RAN     ["o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran"]    2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJlbC1vYW0tcmFuIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1yZWwtb2FtLXJhbiI7CiAgICBwcmVmaXggb3ItdGVpdi1yZWwtb2FtcmFuOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgeyBwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LW9hbSB7IHByZWZpeCBvci10ZWl2LW9hbTsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1yYW4geyBwcmVmaXggb3ItdGVpdi1yYW47IH0KCiAgICBvcmdhbml6YXRpb24gIk9SQU4iOwogICAgY29udGFjdCAiVGhlIEF1dGhvcnMiOwogICAgZGVzY3JpcHRpb24KICAgICJSQU4gTyZNIHRvIExvZ2ljYWwgdG9wb2xvZ3kgbW9kZWwuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIE8mTSB0byBMb2dpY2FsIHRvcG9sb2d5IHJlbGF0aW9ucwoKICAgIENvcHlyaWdodCAoQykgMjAyNCBFcmljc3NvbgogICAgTW9kaWZpY2F0aW9ucyBDb3B5cmlnaHQgKEMpIDIwMjQgT3BlbkluZnJhIEZvdW5kYXRpb24gRXVyb3BlCgogICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsKICAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUywKICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCgogICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAiOwoKICAgIHJldmlzaW9uICIyMDI0LTA1LTI0IiB7CiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmRvbWFpbiBSRUxfT0FNX1JBTjsKCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX01BTkFHRVNfRU5PREVCRlVOQ1RJT04geyAgIC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IG1hbmFnZXMgZU5vZGVCIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBvci10ZWl2LW9hbTpNYW5hZ2VkRWxlbWVudDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBtYW5hZ2VkLWJ5LW1hbmFnZWRFbGVtZW50IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImVOb2RlQiBGdW5jdGlvbiBtYW5hZ2VkIGJ5IE1hbmFnZWQgRWxlbWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46RU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJEVUZVTkNUSU9OIHsgICAgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgbWFuYWdlZC1nbmJkdUZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk1hbmFnZWQgRWxlbWVudCBtYW5hZ2VzIGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1vYW06TWFuYWdlZEVsZW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgbWFuYWdlZC1ieS1tYW5hZ2VkRWxlbWVudCB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItRFUgRnVuY3Rpb24gbWFuYWdlZCBieSBNYW5hZ2VkIEVsZW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVUNQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtQ1AgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLUNQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVUNQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVVVQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1dXBGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtVVAgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLVVQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVVVQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQp9
+\.
+
+COPY ties_model.entity_info("storedAt", "name", "moduleReferenceName") FROM stdin;
+o-ran-smo-teiv-equipment_AntennaModule AntennaModule   o-ran-smo-teiv-equipment
+o-ran-smo-teiv-equipment_Site  Site    o-ran-smo-teiv-equipment
+o-ran-smo-teiv-oam_ManagedElement      ManagedElement  o-ran-smo-teiv-oam
+o-ran-smo-teiv-ran_AntennaCapability   AntennaCapability       o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_ENodeBFunction      ENodeBFunction  o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_EUtranCell  EUtranCell      o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_GNBCUCPFunction     GNBCUCPFunction o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_GNBCUUPFunction     GNBCUUPFunction o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_GNBDUFunction       GNBDUFunction   o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_LTESectorCarrier    LTESectorCarrier        o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_NRCellCU    NRCellCU        o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_NRCellDU    NRCellDU        o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_NRSectorCarrier     NRSectorCarrier o-ran-smo-teiv-ran
+o-ran-smo-teiv-ran_Sector      Sector  o-ran-smo-teiv-ran
+\.
+
+COPY ties_model.relationship_info("name", "aSideAssociationName", "aSideMOType", "aSideModule", "aSideMinCardinality", "aSideMaxCardinality", "bSideAssociationName", "bSideMOType", "bSideModule", "bSideMinCardinality", "bSideMaxCardinality", "associationKind", "connectSameEntity", "relationshipDataLocation", "storedAt", "moduleReferenceName") FROM stdin;
+ANTENNAMODULE_INSTALLED_AT_SITE        installed-at-site       AntennaModule   o-ran-smo-teiv-equipment        0       9223372036854775807     installed-antennaModule Site    o-ran-smo-teiv-equipment        0       1       BI_DIRECTIONAL  false   A_SIDE  o-ran-smo-teiv-equipment_AntennaModule  o-ran-smo-teiv-equipment
+ANTENNAMODULE_SERVES_ANTENNACAPABILITY serviced-antennaCapability      AntennaModule   o-ran-smo-teiv-equipment        0       9223372036854775807     serving-antennaModule   AntennaCapability       o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   RELATION        o-ran-smo-teiv-rel-equipment-ran_ANTENNAMODULE_SERVES_ANTENNACAPABILITY o-ran-smo-teiv-rel-equipment-ran
+ENODEBFUNCTION_PROVIDES_EUTRANCELL     provided-euTranCell     ENodeBFunction  o-ran-smo-teiv-ran      1       1       provided-by-enodebFunction      EUtranCell      o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_EUtranCell   o-ran-smo-teiv-ran
+ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER       provided-lteSectorCarrier       ENodeBFunction  o-ran-smo-teiv-ran      1       1       provided-by-enodebFunction      LTESectorCarrier        o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_LTESectorCarrier     o-ran-smo-teiv-ran
+EUTRANCELL_USES_LTESECTORCARRIER       used-lteSectorCarrier   EUtranCell      o-ran-smo-teiv-ran      0       1       used-by-euTranCell      LTESectorCarrier        o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_LTESectorCarrier     o-ran-smo-teiv-ran
+GNBCUCPFUNCTION_PROVIDES_NRCELLCU      provided-nrCellCu       GNBCUCPFunction o-ran-smo-teiv-ran      1       1       provided-by-gnbcucpFunction     NRCellCU        o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_NRCellCU     o-ran-smo-teiv-ran
+GNBDUFUNCTION_PROVIDES_NRCELLDU        provided-nrCellDu       GNBDUFunction   o-ran-smo-teiv-ran      1       1       provided-by-gnbduFunction       NRCellDU        o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_NRCellDU     o-ran-smo-teiv-ran
+GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER provided-nrSectorCarrier        GNBDUFunction   o-ran-smo-teiv-ran      1       1       provided-by-gnbduFunction       NRSectorCarrier o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_NRSectorCarrier      o-ran-smo-teiv-ran
+LTESECTORCARRIER_USES_ANTENNACAPABILITY        used-antennaCapability  LTESectorCarrier        o-ran-smo-teiv-ran      0       9223372036854775807     used-by-lteSectorCarrier        AntennaCapability       o-ran-smo-teiv-ran      0       1       BI_DIRECTIONAL  false   A_SIDE  o-ran-smo-teiv-ran_LTESectorCarrier     o-ran-smo-teiv-ran
+MANAGEDELEMENT_MANAGES_ENODEBFUNCTION  managed-enodebFunction  ManagedElement  o-ran-smo-teiv-oam      1       1       managed-by-managedElement       ENodeBFunction  o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_ENodeBFunction       o-ran-smo-teiv-rel-oam-ran
+MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION managed-gnbcucpFunction ManagedElement  o-ran-smo-teiv-oam      1       1       managed-by-managedElement       GNBCUCPFunction o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_GNBCUCPFunction      o-ran-smo-teiv-rel-oam-ran
+MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION managed-gnbcuupFunction ManagedElement  o-ran-smo-teiv-oam      1       1       managed-by-managedElement       GNBCUUPFunction o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_GNBCUUPFunction      o-ran-smo-teiv-rel-oam-ran
+MANAGEDELEMENT_MANAGES_GNBDUFUNCTION   managed-gnbduFunction   ManagedElement  o-ran-smo-teiv-oam      1       1       managed-by-managedElement       GNBDUFunction   o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_GNBDUFunction        o-ran-smo-teiv-rel-oam-ran
+NRCELLDU_USES_NRSECTORCARRIER  used-nrSectorCarrier    NRCellDU        o-ran-smo-teiv-ran      0       1       used-by-nrCellDu        NRSectorCarrier o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_NRSectorCarrier      o-ran-smo-teiv-ran
+NRSECTORCARRIER_USES_ANTENNACAPABILITY used-antennaCapability  NRSectorCarrier o-ran-smo-teiv-ran      0       9223372036854775807     used-by-nrSectorCarrier AntennaCapability       o-ran-smo-teiv-ran      0       1       BI_DIRECTIONAL  false   A_SIDE  o-ran-smo-teiv-ran_NRSectorCarrier      o-ran-smo-teiv-ran
+SECTOR_GROUPS_ANTENNAMODULE    grouped-antennaModule   Sector  o-ran-smo-teiv-ran      0       1       grouped-by-sector       AntennaModule   o-ran-smo-teiv-equipment        0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-equipment_AntennaModule  o-ran-smo-teiv-rel-equipment-ran
+SECTOR_GROUPS_EUTRANCELL       grouped-euTranCell      Sector  o-ran-smo-teiv-ran      0       1       grouped-by-sector       EUtranCell      o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_EUtranCell   o-ran-smo-teiv-ran
+SECTOR_GROUPS_NRCELLDU grouped-nrCellDu        Sector  o-ran-smo-teiv-ran      0       1       grouped-by-sector       NRCellDU        o-ran-smo-teiv-ran      0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  o-ran-smo-teiv-ran_NRCellDU     o-ran-smo-teiv-ran
+\.
+
+;
+
+COMMIT;
\ No newline at end of file
index e919b22..91316ec 100644 (file)
 -- ============LICENSE_END=========================================================
 --
 
+BEGIN;
+
 DROP SCHEMA IF EXISTS ties_model cascade;
 CREATE SCHEMA IF NOT EXISTS ties_model;
-ALTER SCHEMA ties_model OWNER TO :pguser;
 SET default_tablespace = '';
 SET default_table_access_method = heap;
 
-SET ROLE :'pguser';
-
 CREATE TABLE IF NOT EXISTS ties_model.hash_info (
     "name"                 VARCHAR(511) PRIMARY KEY,
     "hashedValue"          VARCHAR(511),
@@ -39,44 +38,34 @@ CREATE TABLE IF NOT EXISTS ties_model.module_reference (
     "domain"             VARCHAR(511),
     "includedModules"        jsonb,
     "content"               TEXT,
-    "revision"            VARCHAR(511),
-    "ownerAppId"       VARCHAR(511),
-    "status"       VARCHAR(127)
+    "revision"            VARCHAR(511)
 );
 
 CREATE TABLE IF NOT EXISTS ties_model.entity_info (
-    "name"                   VARCHAR(511) PRIMARY KEY,
-    "moduleReferenceName"    VARCHAR(511),
-    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
-);
-
-CREATE TABLE IF NOT EXISTS ties_model.decorators (
-    "name"     VARCHAR(511) PRIMARY KEY,
-    "dataType"      VARCHAR(511),
-    "moduleReferenceName"    VARCHAR(511),
-    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
-);
-
-CREATE TABLE IF NOT EXISTS ties_model.classifiers (
-    "name"    VARCHAR(511) PRIMARY KEY,
+    "storedAt"               VARCHAR(511) PRIMARY KEY,
+    "name"                   VARCHAR(511),
     "moduleReferenceName"    VARCHAR(511),
     FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
 );
 
 CREATE TABLE IF NOT EXISTS ties_model.relationship_info (
-    "name"      VARCHAR(511) PRIMARY KEY,
-    "aSideAssociationName"    TEXT,
-    "aSideMOType"             TEXT,
-    "aSideMinCardinality"     BIGINT,
-    "aSideMaxCardinality"     BIGINT,
-    "bSideAssociationName"    TEXT,
-    "bSideMOType"             TEXT,
-    "bSideMinCardinality"     BIGINT,
-    "bSideMaxCardinality"     BIGINT,
-    "associationKind"    TEXT,
-    "relationshipDataLocation"          TEXT,
-    "connectSameEntity"       BOOLEAN,
-    "moduleReferenceName"     TEXT,
+    "name"                     VARCHAR(511) NOT NULL,
+    "aSideAssociationName"     TEXT NOT NULL,
+    "aSideMOType"              TEXT NOT NULL,
+    "aSideModule"              TEXT NOT NULL,
+    "aSideMinCardinality"      BIGINT NOT NULL,
+    "aSideMaxCardinality"      BIGINT NOT NULL,
+    "bSideAssociationName"     TEXT NOT NULL,
+    "bSideMOType"              TEXT NOT NULL,
+    "bSideModule"              TEXT NOT NULL,
+    "bSideMinCardinality"      BIGINT NOT NULL,
+    "bSideMaxCardinality"      BIGINT NOT NULL,
+    "associationKind"          TEXT NOT NULL,
+    "relationshipDataLocation" TEXT NOT NULL,
+    "connectSameEntity"        BOOLEAN NOT NULL,
+    "storedAt"                 VARCHAR(511) NOT NULL,
+    "moduleReferenceName"      TEXT NOT NULL,
+    PRIMARY KEY ("name", "moduleReferenceName"),
     FOREIGN KEY ("moduleReferenceName") REFERENCES ties_model.module_reference ("name") ON DELETE CASCADE
 );
 
@@ -319,6 +308,7 @@ UNIQUE_NRSectorCarrier_REL_ID_NRCELLDU_USES_NRSECTORCARRIER UNIQUE_NRSectorCarri
 bSide_TestEntityB      bSide_TestEntityB       COLUMN
 REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION  REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION   COLUMN
 totalTilt      totalTilt       COLUMN
+antennaBeamWidth       antennaBeamWidth        COLUMN
 FK_ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt_REL_FK_deployed-as-cloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm    FK_9C091709D40D51DEE4DC87A44695F6EBA2E965DE     CONSTRAINT
 gNBIdLength    gNBIdLength     COLUMN
 UNIQUE_ENodeBFunction_REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION     UNIQUE_F33037EE8037D0606D15FFB45EE8A27FD6DE30EE CONSTRAINT
@@ -345,6 +335,8 @@ PK_TestEntityA_id   PK_TestEntityA_id       CONSTRAINT
 FK_CloudNativeApplication_REL_FK_deployed-on-namespace FK_CloudNativeApplication_REL_FK_deployed-on-namespace  CONSTRAINT
 gNBDUId        gNBDUId COLUMN
 CD_sourceIds   CD_sourceIds    COLUMN
+CD_classifiers CD_classifiers  COLUMN
+CD_decorators  CD_decorators   COLUMN
 PK_TESTENTITYA_GROUPS_TESTENTITYB_id   PK_TESTENTITYA_GROUPS_TESTENTITYB_id    CONSTRAINT
 REL_ID_SECTOR_GROUPS_ANTENNAMODULE     REL_ID_SECTOR_GROUPS_ANTENNAMODULE      COLUMN
 AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee       B69D3E92CA22CE61B921AE61BD3CF031791CF714        TABLE
@@ -390,96 +382,212 @@ REL_CD_sourceIds_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE    REL_CD_sourceIds_C
 REL_CD_sourceIds_CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE      REL_CD_F7E43E0D0F76D6EFED9AB684B84A69E177F591D2 COLUMN
 REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION  REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION   COLUMN
 REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB  REL_CD_sourceIds_TESTENTITYA_USES_TESTENTITYB   COLUMN
+REL_CD_classifiers_MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM    REL_CD_BF4AAC1A1A910D1182505CABF55BAAE822B2BE59 COLUMN
+REL_CD_classifiers_MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN    REL_CD_7E9F11EFBF8974D7C7DAB02E181A0BE4148091C6 COLUMN
+REL_CD_classifiers_MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN    REL_CD_744530EF4EB1D281D23ADB3DB4CC926DFBE7A60D COLUMN
+REL_CD_classifiers_GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU    REL_CD_66AEF506899F14F936A2F48F9444E2202F5D43F9 COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE  COLUMN
+REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE     REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE      COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION      REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION       COLUMN
+REL_CD_classifiers_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE REL_CD_C6C6D295144A637110DA4E6121BE13F30EFDBEBF COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL    REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL     COLUMN
+REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL  REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL   COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION      REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION       COLUMN
+REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER    REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER     COLUMN
+REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY     REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY      COLUMN
+REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER    REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER     COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM        REL_CD_classifiers_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM COLUMN
+REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU   REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU    COLUMN
+REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU      REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU       COLUMN
+REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU     REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU      COLUMN
+REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER       REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER        COLUMN
+REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER      REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER       COLUMN
+REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY      REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY       COLUMN
+REL_CD_classifiers_NAMESPACE_DEPLOYED_ON_NODECLUSTER   REL_CD_classifiers_NAMESPACE_DEPLOYED_ON_NODECLUSTER    COLUMN
+REL_CD_classifiers_NODECLUSTER_LOCATED_AT_CLOUDSITE    REL_CD_classifiers_NODECLUSTER_LOCATED_AT_CLOUDSITE     COLUMN
+REL_CD_classifiers_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE  REL_CD_classifiers_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE   COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION       REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION        COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION   REL_CD_CCEBD4C63B90BD1764CB5A15C282D6CDBDF0B1F2 COLUMN
+REL_CD_classifiers_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION  REL_CD_026A1F92A7D93728916AF3DCC2C013FB79E29D07 COLUMN
+REL_CD_classifiers_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE        REL_CD_classifiers_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE COLUMN
+REL_CD_classifiers_CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE    REL_CD_C4349BB0F0292A3CE7E456E3A4C40C86DD6B15DF COLUMN
+REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION        REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION COLUMN
+REL_CD_classifiers_TESTENTITYA_USES_TESTENTITYB        REL_CD_classifiers_TESTENTITYA_USES_TESTENTITYB COLUMN
+REL_CD_decorators_MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM     REL_CD_AE82DD80D666B52D79A314F8B4EE9B046830D009 COLUMN
+REL_CD_decorators_MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN     REL_CD_FFF7E036187A7605BFC714483D2E60FD2FF6560B COLUMN
+REL_CD_decorators_MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN     REL_CD_4D1F8113C3096B383582A7A04E68974983B4259E COLUMN
+REL_CD_decorators_GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU     REL_CD_022F8280C0739C614C5F3293E7D8D349A8A10E30 COLUMN
+REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE  REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE   COLUMN
+REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE      REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE       COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION       REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION        COLUMN
+REL_CD_decorators_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE  REL_CD_B369805A0EB24F7C841B0E541A015F85AE2A23B1 COLUMN
+REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL     REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL      COLUMN
+REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL   REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL    COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION       REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION        COLUMN
+REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER     REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER      COLUMN
+REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY      REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY       COLUMN
+REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER     REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER      COLUMN
+REL_CD_decorators_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM REL_CD_decorators_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM  COLUMN
+REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU    REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU     COLUMN
+REL_CD_decorators_SECTOR_GROUPS_NRCELLDU       REL_CD_decorators_SECTOR_GROUPS_NRCELLDU        COLUMN
+REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU      REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU       COLUMN
+REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER        REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER COLUMN
+REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER       REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER        COLUMN
+REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY       REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY        COLUMN
+REL_CD_decorators_NAMESPACE_DEPLOYED_ON_NODECLUSTER    REL_CD_decorators_NAMESPACE_DEPLOYED_ON_NODECLUSTER     COLUMN
+REL_CD_decorators_NODECLUSTER_LOCATED_AT_CLOUDSITE     REL_CD_decorators_NODECLUSTER_LOCATED_AT_CLOUDSITE      COLUMN
+REL_CD_decorators_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE   REL_CD_decorators_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE    COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION        REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION COLUMN
+REL_CD_decorators_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION    REL_CD_21E2495C31F0DBF735976C90F4CD10D1215190E1 COLUMN
+REL_CD_decorators_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION   REL_CD_D32E90288E1982363B2BD8DA9D2E90AA16F71575 COLUMN
+REL_CD_decorators_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE REL_CD_decorators_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE  COLUMN
+REL_CD_decorators_CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE     REL_CD_8AD499BB116F3213C079F643D4B3532035D092D2 COLUMN
+REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION  COLUMN
+REL_CD_decorators_TESTENTITYA_USES_TESTENTITYB REL_CD_decorators_TESTENTITYA_USES_TESTENTITYB  COLUMN
+o-ran-smo-teiv-ran-oam_ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        fa2dceaf53e045c136ce9db9bc5faae65a29fa4d        TABLE
+o-ran-smo-teiv-ran-oam_ManagedElement  o-ran-smo-teiv-ran-oam_ManagedElement   TABLE
+o-ran-smo-teiv-ran-cloud_NodeCluster   o-ran-smo-teiv-ran-cloud_NodeCluster    TABLE
+o-ran-smo-teiv-ran-cloud_CloudNativeSystem     163276fa439cdfccabb80f7acacb6fa638e8d314        TABLE
+o-ran-smo-teiv-ran-cloud_CloudNativeApplication        e01fcb87ad2c34ce66c34420255e25aaca270e5e        TABLE
+o-ran-smo-teiv-ran-cloud_CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm      ef701af8e1445ed5d377664ba1d3d1c645e31639        TABLE
+o-ran-smo-teiv-ran-cloud_CloudSite     o-ran-smo-teiv-ran-cloud_CloudSite      TABLE
+o-ran-smo-teiv-ran-cloud_Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee      bc563e4310b0538e6bdd35f52684160af5b23671        TABLE
+o-ran-smo-teiv-ran-cloud_CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn      5f8facd51b2bbddc90d9dee9be697907441892d0        TABLE
+o-ran-smo-teiv-ran-cloud_Namespace     o-ran-smo-teiv-ran-cloud_Namespace      TABLE
+o-ran-smo-teiv-ran-logical-to-equipment_Sector 22174a23af5d5a96143c83ddfa78654df0acb697        TABLE
+o-ran-smo-teiv-ran-logical_GNBCUUPFunction     8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb        TABLE
+o-ran-smo-teiv-ran-logical_ENodeBFunction      o-ran-smo-teiv-ran-logical_ENodeBFunction       TABLE
+o-ran-smo-teiv-ran-logical_NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU    300672c8a708d6af0b9af2f9accdff5e6e005721        TABLE
+o-ran-smo-teiv-ran-logical_NRCellDU    o-ran-smo-teiv-ran-logical_NRCellDU     TABLE
+o-ran-smo-teiv-ran-logical_LTESectorCarrier    c88307168935f02fdecc084ea5040bb9db16c701        TABLE
+o-ran-smo-teiv-ran-logical_GNBDUFunction       o-ran-smo-teiv-ran-logical_GNBDUFunction        TABLE
+o-ran-smo-teiv-ran-logical_NRCellCU    o-ran-smo-teiv-ran-logical_NRCellCU     TABLE
+o-ran-smo-teiv-ran-logical_GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn    3fdb9cd7557edf559a0e4de88df220e7545884b5        TABLE
+o-ran-smo-teiv-ran-equipment_AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee  341622dca4e0350289717b52df5883edc3fa0280        TABLE
+o-ran-smo-teiv-ran-logical_EUtranCell  o-ran-smo-teiv-ran-logical_EUtranCell   TABLE
+o-ran-smo-teiv-ran-logical_GNBCUCPFunction     c4a425179d3089b5288fdf059079d0ea26977f0f        TABLE
+o-ran-smo-teiv-ran-logical_NRSectorCarrier     39a335dca201ef99ae06f4ffd1908b534f8c6c39        TABLE
+o-ran-smo-teiv-ran-logical_AntennaCapability   88f1bd76c7a935fb505cf235e6819f46c55ec98a        TABLE
+o-ran-smo-teiv-ran-logical_TestEntityB o-ran-smo-teiv-ran-logical_TestEntityB  TABLE
+o-ran-smo-teiv-ran-logical_TestEntityA o-ran-smo-teiv-ran-logical_TestEntityA  TABLE
+o-ran-smo-teiv-ran-equipment_Site      o-ran-smo-teiv-ran-equipment_Site       TABLE
+o-ran-smo-teiv-ran-equipment_AntennaModule     f8caf5ebe876c3001d67efe06e4d83abf0babe31        TABLE
+o-ran-smo-teiv-ran-equipment_PhysicalNetworkAppliance  57a20807ab3f39c86b0b5bf9a819e0881353fa1e        TABLE
+o-ran-smo-teiv-ran-logical-to-cloud_GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION 70a4a84bca01ea022ab24d8cb82422c572922675        TABLE
+o-ran-smo-teiv-ran-logical-to-equipment_ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE    5b8a47d4a8297a0a1d31e091af06e26d25ef6caf        TABLE
+o-ran-smo-teiv-ran-logical-to-cloud_GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN   f86057a8762a50b1c7fb07af9d5c001bffaefd15        TABLE
+o-ran-smo-teiv-ran-logical_TESTENTITYA_PROVIDES_TESTENTITYB    73936e503f137d82d1422c0f08c66c7ff8b90209        TABLE
+o-ran-smo-teiv-ran-logical_TESTENTITYA_GROUPS_TESTENTITYB      70003c8082751e1832e7bc5c0d83db6d22c4fcdc        TABLE
+o-ran-smo-teiv-ran-equipment_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE   5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6        TABLE
+o-ran-smo-teiv-ran-equipment_ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE  cd39d44beed963d50df42cd301e63d288f911c97        TABLE
+o-ran-smo-teiv-ran-equipment_ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE  c6f3a3396e9165e886da928c5fe1382fb20dc850        TABLE
+o-ran-smo-teiv-ran-logical-to-cloud_GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION 7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7        TABLE
+o-ran-smo-teiv-ran-logical-to-cloud_GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION   10484f157f490eb5b27e40dbfaf4d5f2be17c57c        TABLE
 \.
 
-COPY ties_model.module_reference("name", "namespace", "domain", "includedModules", "revision", "content", "ownerAppId", "status") FROM stdin;
-o-ran-smo-teiv-common-yang-extensions  urn:o-ran:smo-teiv-common-yang-extensions       \N      []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgewoKICB5YW5nLXZlcnNpb24gMS4xOwogIG5hbWVzcGFjZSAidXJuOm8tcmFuOnNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMiOwogIHByZWZpeCBvci10ZWl2LXlleHQ7CgogIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOwogIGRlc2NyaXB0aW9uCiAgIlRvcG9sb2d5IGFuZCBJbnZlbnRvcnkgWUFORyBleHRlbnNpb25zIG1vZGVsLgoKICBDb3B5cmlnaHQgKGMpIDIwMjMgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogIFRoaXMgbW9kZWwgY29udGFpbnMgZXh0ZW5zaW9ucyB0byB0aGUgWUFORyBsYW5ndWFnZSB0aGF0IHRvcG9sb2d5IGFuZAogIGludmVudG9yeSBtb2RlbHMgd2lsbCB1c2UgdG8gZGVmaW5lIGFuZCBhbm5vdGF0ZSB0eXBlcyBhbmQgcmVsYXRpb25zaGlwcy4iOwoKICByZXZpc2lvbiAiMjAyNC0wNS0wMiIgewogICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICB9CgogIGV4dGVuc2lvbiBiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgewoKICAgIGRlc2NyaXB0aW9uCiAgICAgICJEZWZpbmVzIGEgYmktZGlyZWN0aW9uYWwgcmVsYXRpb25zaGlwIGluIHRoZSB0b3BvbG9neS4KCiAgICAgICBBIGJpLWRpcmVjdGlvbmFsLWFzc29jaWF0aW9uIChCREEpIGlzIGEgcmVsYXRpb25zaGlwIGNvbXByaXNpbmcgb2YgYW4KICAgICAgIEEtc2lkZSBhbmQgYSBCLXNpZGUuIFRoZSBBLXNpZGUgaXMgY29uc2lkZXJlZCB0aGUgb3JpZ2luYXRpbmcgc2lkZSBvZgogICAgICAgdGhlIHJlbGF0aW9uc2hpcDsgdGhlIEItc2lkZSBpcyBjb25zaWRlcmVkIHRoZSB0ZXJtaW5hdGluZyBzaWRlIG9mIHRoZQogICAgICAgcmVsYXRpb25zaGlwLiBUaGUgb3JkZXIgb2YgQS1zaWRlIGFuZCBCLXNpZGUgaXMgb2YgaW1wb3J0YW5jZSBhbmQgTVVTVAogICAgICAgTk9UIGJlIGNoYW5nZWQgb25jZSBkZWZpbmVkLgoKICAgICAgIEJvdGggQS1zaWRlIGFuZCBCLXNpZGUgYXJlIGRlZmluZWQgb24gYSB0eXBlLCBhbmQgYXJlIGdpdmVuIGEgcm9sZS4gQQogICAgICAgdHlwZSBtYXkgaGF2ZSBtdWx0aXBsZSBvcmlnaW5hdGluZyBhbmQvb3IgdGVybWluYXRpbmcgc2lkZXMgb2YgYQogICAgICAgcmVsYXRpb25zaGlwLCBhbGwgZGlzdGluZ3Vpc2hlZCBieSByb2xlIG5hbWUuCgogICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIG9ubHkgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlICdtb2R1bGUnIHN0YXRlbWVudC4KICAgICAgIE11bHRpcGxlICdiaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIHN0YXRlbWVudHMgYXJlIGFsbG93ZWQKICAgICAgIHBlciBwYXJlbnQgc3RhdGVtZW50LgoKICAgICAgIFN1YnN0YXRlbWVudHMgdG8gdGhlICdiaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIGRlZmluZSB0aGUKICAgICAgIEEtc2lkZSBhbmQgdGhlIEItc2lkZSwgcmVzcGVjdGl2ZWx5LCBhbmQgb3B0aW9uYWxseSBwcm9wZXJ0aWVzIG9mIHRoZQogICAgICAgcmVsYXRpb25zaGlwLiBEYXRhIG5vZGVzIG9mIHR5cGVzICdsZWFmJyBhbmQgJ2xlYWYtbGlzdCcgYXJlIHVzZWQgZm9yCiAgICAgICB0aGlzIHB1cnBvc2UuIE9uZSBvZiB0aGUgZGF0YSBub2RlcyBNVVNUIGJlIGFubm90YXRlZCB3aXRoIHRoZSAnYS1zaWRlJwogICAgICAgZXh0ZW5zaW9uOyBhbm90aGVyIGRhdGEgbm9kZSBNVVNUIGJlIGFubm90YXRlZCB3aXRoIHRoZSAnYi1zaWRlJwogICAgICAgZXh0ZW5zaW9uLiBPdGhlciBkYXRhIG5vZGVzIGRlZmluZSBwcm9wZXJ0aWVzIG9mIHRoZSByZWxhdGlvbnNoaXAuCgogICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSByZWxhdGlvbnNoaXAgbmFtZSBpcwogICAgICAgc2NvcGVkIHRvIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlY2xhcmluZyBtb2R1bGUgYW5kIE1VU1QgYmUgdW5pcXVlCiAgICAgICB3aXRoaW4gdGhlIHNjb3BlLiI7CgogICAgYXJndW1lbnQgcmVsYXRpb25zaGlwTmFtZTsKICB9CgogIGV4dGVuc2lvbiBhU2lkZSB7CiAgICBkZXNjcmlwdGlvbgogICAgICAiRGVmaW5lcyB0aGUgQS1zaWRlIG9mIGEgcmVsYXRpb25zaGlwLgoKICAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgJ2xlYWYnIG9yICdsZWFmLWxpc3QnCiAgICAgICBzdGF0ZW1lbnQsIHdoaWNoIGl0c2VsZiBtdXN0IGJlIGEgc3Vic3RhdGVtZW50IG9mIHRoZQogICAgICAgJ3VuaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIHN0YXRlbWVudC4KCiAgICAgICBUaGUgZGF0YSB0eXBlIG9mIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIE1VU1QgYmUKICAgICAgICdpbnN0YW5jZS1pZGVudGlmaWVyJy4gQ29uc3RyYWludHMgTUFZIGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgcGFyZW50CiAgICAgICAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgdG8gZW5mb3JjZSBjYXJkaW5hbGl0eS4KCiAgICAgICBUaGUgaWRlbnRpZmllciBvZiB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBpcyB1c2VkIGFzIG5hbWUgb2YKICAgICAgIHRoZSByb2xlIG9mIHRoZSBBLXNpZGUgb2YgdGhlIHJlbGF0aW9uc2hpcC4gVGhlIG5hbWUgb2YgdGhlIHJvbGUgaXMKICAgICAgIHNjb3BlZCB0byB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQS1zaWRlIGlzIGRlZmluZWQgYW5kIE1VU1QgYmUgdW5pcXVlCiAgICAgICB3aXRoaW4gdGhlIHNjb3BlLgoKICAgICAgIFdoaWxlIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIGRvZXMgbm90IHJlc3VsdCBpbiBhIHByb3BlcnR5IG9mCiAgICAgICB0aGUgcmVsYXRpb25zaGlwLCBpdCBpcyBSRUNPTU1FTkRFRCB0byBhdm9pZCB1c2luZyB0aGUgbmFtZSBvZiBhbgogICAgICAgZXhpc3RpbmcgdHlwZSBwcm9wZXJ0eSBhcyByb2xlIG5hbWUgdG8gYXZvaWQgcG90ZW50aWFsIGFtYmlndWl0aWVzCiAgICAgICBiZXR3ZWVuIHByb3BlcnRpZXMgb2YgYSB0eXBlLCBhbmQgcm9sZXMgb2YgYSByZWxhdGlvbnNoaXAgb24gdGhlIHR5cGUuCgogICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSB0eXBlIG9uIHdoaWNoIHRoZSBBLXNpZGUgcmVzaWRlcy4gSWYgdGhlCiAgICAgICB0eXBlIGlzIGRlY2xhcmVkIGluIGFub3RoZXIgbW9kdWxlLCB0aGUgdHlwZSBtdXN0IGJlIHByZWZpeGVkLCBhbmQgYQogICAgICAgY29ycmVzcG9uZGluZyAnaW1wb3J0JyBzdGF0ZW1lbnQgYmUgdXNlZCB0byBkZWNsYXJlIHRoZSBwcmVmaXguIjsKCiAgICBhcmd1bWVudCBhU2lkZVR5cGU7CiAgfQoKICBleHRlbnNpb24gYlNpZGUgewogICAgZGVzY3JpcHRpb24gIkRlZmluZXMgdGhlIEItc2lkZSBvZiBhIHJlbGF0aW9uc2hpcC4KCiAgICAgICBUaGUgc3RhdGVtZW50IE1VU1Qgb25seSBiZSBhIHN1YnN0YXRlbWVudCBvZiBhICdsZWFmJyBvciAnbGVhZi1saXN0JwogICAgICAgc3RhdGVtZW50LCB3aGljaCBpdHNlbGYgbXVzdCBiZSBhIHN1YnN0YXRlbWVudCBvZiB0aGUKICAgICAgICd1bmktZGlyZWN0aW9uYWwtdG9wb2xvZ3ktcmVsYXRpb25zaGlwJyBzdGF0ZW1lbnQuCgogICAgICAgVGhlIGRhdGEgdHlwZSBvZiB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBNVVNUIGJlCiAgICAgICAnaW5zdGFuY2UtaWRlbnRpZmllcicuIENvbnN0cmFpbnRzIE1BWSBiZSB1c2VkIGFzIHBhcnQgb2YgdGhlIHBhcmVudAogICAgICAgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIHRvIGVuZm9yY2UgY2FyZGluYWxpdHkuCgogICAgICAgVGhlIGlkZW50aWZpZXIgb2YgdGhlIHBhcmVudCAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgaXMgdXNlZCBhcyBuYW1lIG9mCiAgICAgICB0aGUgcm9sZSBvZiB0aGUgQi1zaWRlIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSBuYW1lIG9mIHRoZSByb2xlIGlzCiAgICAgICBzY29wZWQgdG8gdGhlIHR5cGUgb24gd2hpY2ggdGhlIEItc2lkZSBpcyBkZWZpbmVkIGFuZCBNVVNUIGJlIHVuaXF1ZQogICAgICAgd2l0aGluIHRoZSBzY29wZS4KCiAgICAgICBXaGlsZSB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBkb2VzIG5vdCByZXN1bHQgaW4gYSBwcm9wZXJ0eSBvZgogICAgICAgdGhlIHJlbGF0aW9uc2hpcCwgaXQgaXMgUkVDT01NRU5ERUQgdG8gYXZvaWQgdXNpbmcgdGhlIG5hbWUgb2YgYW4KICAgICAgIGV4aXN0aW5nIHR5cGUgcHJvcGVydHkgYXMgcm9sZSBuYW1lIHRvIGF2b2lkIHBvdGVudGlhbCBhbWJpZ3VpdGllcwogICAgICAgYmV0d2VlbiBwcm9wZXJ0aWVzIG9mIGEgdHlwZSwgYW5kIHJvbGVzIG9mIGEgcmVsYXRpb25zaGlwIG9uIHRoZSB0eXBlLgoKICAgICAgIFRoZSBhcmd1bWVudCBpcyB0aGUgbmFtZSBvZiB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQi1zaWRlIHJlc2lkZXMuIElmIHRoZQogICAgICAgdHlwZSBpcyBkZWNsYXJlZCBpbiBhbm90aGVyIG1vZHVsZSwgdGhlIHR5cGUgbXVzdCBiZSBwcmVmaXhlZCwgYW5kIGEKICAgICAgIGNvcnJlc3BvbmRpbmcgJ2ltcG9ydCcgc3RhdGVtZW50IGJlIHVzZWQgdG8gZGVjbGFyZSB0aGUgcHJlZml4LiI7CgogICAgYXJndW1lbnQgYlNpZGVUeXBlOwogIH0KCiAgZXh0ZW5zaW9uIGRvbWFpbiB7CiAgICBkZXNjcmlwdGlvbiAiS2V5d29yZCB1c2VkIHRvIGNhcnJ5IGRvbWFpbiBpbmZvcm1hdGlvbi4iOwogICAgYXJndW1lbnQgZG9tYWluTmFtZTsKICB9CgogIGV4dGVuc2lvbiBsYWJlbCB7CiAgICBkZXNjcmlwdGlvbiAiVGhlIGxhYmVsIGNhbiBiZSB1c2VkIHRvIGdpdmUgbW9kdWxlcyBhbmQgc3VibW9kdWxlcyBhIHNlbWFudGljIHZlcnNpb24sIGluIGFkZGl0aW9uIHRvIHRoZWlyIHJldmlzaW9uLgoKICAgICAgVGhlIGZvcm1hdCBvZiB0aGUgbGFiZWwgaXMg4oCYeC55LnrigJkg4oCTIGV4cHJlc3NlZCBhcyBwYXR0ZXJuLCBpdCBpcyBbMC05XStcXC5bMC05XStcXC5bMC05XSsKCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIHRoZSByZXZpc2lvbiBzdGF0ZW1lbnQuICBaZXJvIG9yIG9uZSByZXZpc2lvbiBsYWJlbCBzdGF0ZW1lbnRzCiAgICAgIHBlciBwYXJlbnQgc3RhdGVtZW50IGFyZSBhbGxvd2VkLgoKICAgICAgUmV2aXNpb24gbGFiZWxzIE1VU1QgYmUgdW5pcXVlIGFtb25nc3QgYWxsIHJldmlzaW9ucyBvZiBhIG1vZHVsZSBvciBzdWJtb2R1bGUuIjsKICAgICAgYXJndW1lbnQgc2VtdmVyc2lvbjsKICB9Cn0=    BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-oam-to-cloud    urn:o-ran:smo-teiv-oam-to-cloud OAM_TO_CLOUD    ["o-ran-smo-teiv-oam", "o-ran-smo-teiv-cloud"]  2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LW9hbS10by1jbG91ZCB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtb2FtLXRvLWNsb3VkIjsKICAgIHByZWZpeCBvci10ZWl2LW9hbXRvY2xvdWQ7CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggb3ItdGVpdi10eXBlczsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LW9hbSB7cHJlZml4IG9yLXRlaXYtb2FtOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNsb3VkIHtwcmVmaXggb3ItdGVpdi1jbG91ZDsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiBPJk0gdG8gQ2xvdWQgdG9wb2xvZ3kgbW9kZWwuCgogICAgQ29weXJpZ2h0IChjKSAyMDIzIEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKICAgIFRoaXMgbW9kZWwgY29udGFpbnMgdGhlIFJBTiBPJk0gdG8gQ2xvdWQgdG9wb2xvZ3kgcmVsYXRpb25zIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0wMiIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIG9yLXRlaXYteWV4dDpkb21haW4gT0FNX1RPX0NMT1VEOwoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfREVQTE9ZRURfQVNfQ0xPVURJRklFRE5GIHsgIC8vIDAuLjEgdG8gMQoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZiBkZXBsb3llZC1hcy1jbG91ZGlmaWVkTkYgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IGRlcGxveWVkIGFzIENsb3VkaWZpZWQgTkYuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGRlcGxveWVkLW1hbmFnZWRFbGVtZW50IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkaWZpZWQgTkYgZGVwbG95cyBNYW5hZ2VkIEVsZW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtY2xvdWQ6Q2xvdWRpZmllZE5GOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgICAgIG1hbmRhdG9yeSB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5GREVQTE9ZTUVOVF9TRVJWRVNfTUFOQUdFREVMRU1FTlQgeyAvLyAxLi5uIHRvIDEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgc2VydmljZWQtbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IHNlcnZpY2VkIGJ5IHRoaXMgTkYgRGVwbG95bWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1jbG91ZDpORkRlcGxveW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1uRkRlcGxveW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTkYgRGVwbG95bWVudCB0aGF0IHNlcnZlcyB0aGlzIE1hbmFnZWQgRWxlbWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1vYW06TWFuYWdlZEVsZW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgICAgfQogICAgfQp9    BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-common-yang-types       urn:o-ran:smo-teiv-common-yang-types    \N      []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsKCiAgeWFuZy12ZXJzaW9uIDEuMTsKICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyI7CiAgcHJlZml4IG9yLXRlaXYtdHlwZXM7CgogIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogIGltcG9ydCBfM2dwcC1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCB0eXBlczNncHA7IH0KCiAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgZGVzY3JpcHRpb24KICAiVG9wb2xvZ3kgYW5kIEludmVudG9yeSBjb21tb24gdHlwZXMgbW9kZWwuCgogIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgVGhpcyBtb2RlbCBjb250YWlucyByZS11c2FibGUgZGF0YSB0eXBlcyB0aGF0IHRvcG9sb2d5IGFuZCBpbnZlbnRvcnkgbW9kZWxzCiAgd2lsbCBmcmVxdWVudGx5IHVzZSBhcyBwYXJ0IG9mIHR5cGVzIGFuZCByZWxhdGlvbnNoaXBzLiI7CgogIHJldmlzaW9uICIyMDI0LTA1LTAyIiB7CiAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogIH0KCiAgZ3JvdXBpbmcgVG9wX0dycF9UeXBlIHsKCiAgICBkZXNjcmlwdGlvbiAiR3JvdXBpbmcgY29udGFpbmluZyB0aGUga2V5IGF0dHJpYnV0ZSBjb21tb24gdG8gYWxsIHR5cGVzLiBBbGwgdHlwZXMKICAgICAgICAgICAgICAgIE1VU1QgdXNlIHRoaXMgZ3JvdXBpbmcuIjsKCiAgICBsZWFmIGlkIHsKICAgICAgdHlwZSBzdHJpbmc7CiAgICAgIGRlc2NyaXB0aW9uICJVbmlxdWUgaWRlbnRpZmllciBvZiB0b3BvbG9neSBlbnRpdGllcy4gUmVwcmVzZW50cyB0aGUgRW50aXR5IEluc3RhbmNlIElkZW50aWZpZXIuIjsKICAgIH0KICB9CgogIGdyb3VwaW5nIENNX0lEIHsKCiAgICBkZXNjcmlwdGlvbiAiR3JvdXBpbmcgY29udGFpbmluZyB0aGUga2V5IGF0dHJpYnV0ZXMgdG8gbWFrZQogICAgICAgICAgICAgICAgdXNlIG9mIENvbmZpZ3VyYXRpb24gTWFuYWdlbWVudCAoQ00pLiI7CgogICAgbGVhZiBjbUhhbmRsZSB7CiAgICAgIHR5cGUgc3RyaW5nOwogICAgICBkZXNjcmlwdGlvbiAiVW5pcXVlIGlkZW50aWZpZXIgZm9yIG5ldHdvcmsgZW50aXRpZXMgaW4gQ00uIjsKICAgIH0KCiAgICBsZWFmIHJlc291cmNlSWRlbnRpZmllciB7CiAgICAgIHR5cGUgc3RyaW5nOwogICAgICBkZXNjcmlwdGlvbiAiVGhlIHhwYXRoIGV4cHJlc3Npb24gaWRlbnRpZnlpbmcgdGhlIHJlc291cmNlIGluIHRoZSBOb2RlIG1vZGVsIHlhbmcgdHJlZS4iOwogICAgfQogIH0KCiAgdHlwZWRlZiBfM0dQUF9GRE5fVHlwZSB7CiAgICB0eXBlIHR5cGVzM2dwcDpEaXN0aW5ndWlzaGVkTmFtZTsKICB9CgogIGNvbnRhaW5lciBjb25zdW1lci1kYXRhIHsKICAgIGRlc2NyaXB0aW9uICJUaGlzIGNvbnRhaW5lciBkZWZpbmVzIHRoZSBjb25zdW1lci1kYXRhLiBDb25zdW1lci1kYXRhIG1heSBiZSBhdHRhY2hlZCB0byBUb3BvbG9neSBFbnRpdHkgb3IKICAgICAgICAgICAgICAgIFRvcG9sb2d5IFJlbGF0aW9uIGluc3RhbmNlLCBvdXRzaWRlIG9mIHRoZSBkZWNsYXJlZCBUb3BvbG9neSBFbnRpdHkgb3IgVG9wb2xvZ3kgUmVsYXRpb25zaGlwJ3MgYXR0cmlidXRlcy4KICAgICAgICAgICAgICAgIFRoaXMgY29udGFpbmVyIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQsIGFuZCBpdCBNVVNUIE5PVCBiZSBhdWdtZW50ZWQgb3IgZGV2aWF0ZWQgaW4gYW55IHdheSwgdW5sZXNzIHN0YXRlZAogICAgICAgICAgICAgICAgb3RoZXJ3aXNlLiI7CgogICAgY29udGFpbmVyIGRlY29yYXRvcnMgewogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBjb250YWluZXIgc2VydmVzIGFzIGV4dGVuc2lvbiBwb2ludCBmb3IgYXBwbGljYXRpb25zIHdpc2hpbmcgdG8gZGVmaW5lIHRoZWlyIG93biBkZWNvcmF0b3JzLgogICAgICAgICAgICAgICAgICBUaGlzIGlzIGRvbmUgdmlhIGF1Z21lbnRhdGlvbnMuIFRoZXkgY2FuIG9ubHkgYmUgZGVmaW5lZCBpbiBuYW1lIHZhbHVlIHBhaXIuIjsKICAgIH0KCiAgICBsZWFmLWxpc3QgY2xhc3NpZmllcnMgewogICAgICBkZXNjcmlwdGlvbiAiQ29uc3VtZXIgZGVmaW5lZCB0YWdzIHRvIHRvcG9sb2d5IGVudGl0aWVzIGFuZCByZWxhdGlvbnNoaXBzLiI7CiAgICAgIHR5cGUgaWRlbnRpdHlyZWYgeyBiYXNlIGNsYXNzaWZpZXI7IH0KICAgIH0KCiAgICBsZWFmLWxpc3Qgc291cmNlSWRzIHsKICAgICAgZGVzY3JpcHRpb24gIkFuIG9yZGVyZWQgbGlzdCBvZiBpZGVudGl0aWVzIHRoYXQgcmVwcmVzZW50IHRoZSBzZXQgb2YgbmF0aXZlIHNvdXJjZSBpZGVudGlmaWVycyBmb3IgcGFydGljaXBhdGluZwogICAgICAgICAgICAgICAgICBlbnRpdGllcy4iOwogICAgICB0eXBlIHN0cmluZzsKICAgICAgb3JkZXJlZC1ieSB1c2VyOwogICAgfQoKICAgIGNvbnRhaW5lciBtZXRhZGF0YSB7CiAgICAgIGRlc2NyaXB0aW9uICJUaGlzIGNvbnRhaW5lciBzZXJ2ZXMgYXMgZXh0ZW5zaW9uIHBvaW50IHRvIGRlZmluZSBtZXRhZGF0YS4gVGhleSBjYW4gb25seSBiZSBkZWZpbmVkIGluIG5hbWUgdmFsdWUKICAgICAgICAgICAgICAgICAgcGFpci4iOwogICAgfQogIH0KCiAgaWRlbnRpdHkgY2xhc3NpZmllcnsKICAgIGRlc2NyaXB0aW9uICAiVGhlIGNsYXNzaWZpZXIgaXMgdXNlZCBhcyBhIGJhc2UgdG8gcHJvdmlkZSBhbGwgY2xhc3NpZmllcnMgd2l0aCBpZGVudGl0eS4gIjsKICB9Cn0=    BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-oam     urn:o-ran:smo-teiv-oam  OAM     []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LW9hbSB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtb2FtIjsKICAgIHByZWZpeCBvci10ZWl2LW9hbTsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBvcmdhbml6YXRpb24gIkVyaWNzc29uIEFCIjsKICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOwogICAgZGVzY3JpcHRpb24KICAgICJSQU4gTyZNIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIE8mTSBkb21haW4sIHdoaWNoIGFyZSBpbnRlbmRlZCB0byByZXByZXNlbnQgbWFuYWdlbWVudCBzeXN0ZW1zCiAgICBhbmQgbWFuYWdlbWVudCBpbnRlcmZhY2VzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMDIiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIE9BTTsKCiAgICBsaXN0IE1hbmFnZWRFbGVtZW50IHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBNYW5hZ2VkIEVsZW1lbnQgKE1FKSBpcyBhIG5vZGUgaW50byBhIHRlbGVjb21tdW5pY2F0aW9uIG5ldHdvcmsKICAgICAgICAgICAgICAgICAgICBwcm92aWRpbmcgc3VwcG9ydCBhbmQvb3Igc2VydmljZSB0byBzdWJzY3JpYmVycy4gQW4gTUUgY29tbXVuaWNhdGVzCiAgICAgICAgICAgICAgICAgICAgd2l0aCBhIG1hbmFnZXIgYXBwbGljYXRpb24gKGRpcmVjdGx5IG9yIGluZGlyZWN0bHkpIG92ZXIgb25lIG9yIG1vcmUKICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2VzIGZvciB0aGUgcHVycG9zZSBvZiBiZWluZyBtb25pdG9yZWQgYW5kL29yIGNvbnRyb2xsZWQuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBmZG4gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoaXMgRnVsbCBEaXN0aW5ndWlzaGVkIE5hbWUgKEZETikgaWRlbnRpZmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gaW5zdGFuY2Ugb2YgdGhlIE1hbmFnZWRFbGVtZW50IE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFuYWdlZEVsZW1lbnQuIjsKICAgICAgICAgICAgICAgIHR5cGUgb3ItdGVpdi10eXBlczpfM0dQUF9GRE5fVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9        BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-oam-to-ran      urn:o-ran:smo-teiv-oam-to-ran   OAM_TO_RAN      ["o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran"]    2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LW9hbS10by1yYW4gewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOm8tcmFuOnNtby10ZWl2LW9hbS10by1yYW4iOwogICAgcHJlZml4IG9yLXRlaXYtb2FtdG9yYW47CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggb3ItdGVpdi10eXBlczsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LW9hbSB7cHJlZml4IG9yLXRlaXYtb2FtOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LXJhbiB7cHJlZml4IG9yLXRlaXYtcmFuOyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiUkFOIE8mTSB0byBMb2dpY2FsIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSBSQU4gTyZNIHRvIExvZ2ljYWwgdG9wb2xvZ3kgcmVsYXRpb25zIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0wMiIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIG9yLXRlaXYteWV4dDpkb21haW4gT0FNX1RPX1JBTjsKCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX01BTkFHRVNfRU5PREVCRlVOQ1RJT04geyAgIC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IG1hbmFnZXMgZU5vZGVCIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBvci10ZWl2LW9hbTpNYW5hZ2VkRWxlbWVudDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBtYW5hZ2VkLWJ5LW1hbmFnZWRFbGVtZW50IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImVOb2RlQiBGdW5jdGlvbiBtYW5hZ2VkIGJ5IE1hbmFnZWQgRWxlbWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46RU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJEVUZVTkNUSU9OIHsgICAgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgbWFuYWdlZC1nbmJkdUZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk1hbmFnZWQgRWxlbWVudCBtYW5hZ2VzIGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1vYW06TWFuYWdlZEVsZW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgbWFuYWdlZC1ieS1tYW5hZ2VkRWxlbWVudCB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItRFUgRnVuY3Rpb24gbWFuYWdlZCBieSBNYW5hZ2VkIEVsZW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVUNQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtQ1AgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLUNQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVUNQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVVVQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1dXBGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtVVAgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLVVQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVVVQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQp9        BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-ran     urn:o-ran:smo-teiv-ran  RAN     []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJhbiB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtcmFuIjsKICAgIHByZWZpeCBvci10ZWl2LXJhbjsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgXzNncHAtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggdHlwZXMzZ3BwOyB9CgogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgICAgICBwcmVmaXggZ2VvOwogICAgICAgIHJlZmVyZW5jZSAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiBMb2dpY2FsIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIExvZ2ljYWwgZG9tYWluLCB3aGljaCByZXByZXNlbnRzIHRoZSBmdW5jdGlvbmFsIGNhcGFiaWxpdHkKICAgIG9mIHRoZSBkZXBsb3llZCBSQU4gdGhhdCBhcmUgcmVsZXZhbnQgdG8gckFwcHMgdXNlIGNhc2VzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMDIiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIFJBTjsKCiAgICBsaXN0IEdOQkRVRnVuY3Rpb24gewogICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUIgRGlzdHJpYnV0ZWQgVW5pdCAoZ05CLURVKS4KCiAgICAgICAgICAgICAgICAgICAgQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ2VudHJhbGl6ZWQgVW5pdAogICAgICAgICAgICAgICAgICAgIChnTkItQ1UpIGFuZCBhIGdOQi1EVS4gVGhlIENVIHByb2Nlc3NlcyBub24tcmVhbAogICAgICAgICAgICAgICAgICAgIHRpbWUgcHJvdG9jb2xzIGFuZCBzZXJ2aWNlcywgYW5kIHRoZSBEVSBwcm9jZXNzZXMKICAgICAgICAgICAgICAgICAgICBQSFkgbGV2ZWwgcHJvdG9jb2wgYW5kIHJlYWwgdGltZSBzZXJ2aWNlcy4gVGhlCiAgICAgICAgICAgICAgICAgICAgZ05CLUNVIGFuZCB0aGUgZ05CLURVIHVuaXRzIGFyZSBjb25uZWN0ZWQgdmlhCiAgICAgICAgICAgICAgICAgICAgRjEgbG9naWNhbCBpbnRlcmZhY2UuCgogICAgICAgICAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgaXMgdHJ1ZSBmb3IgYSBnTkItRFU6CiAgICAgICAgICAgICAgICAgICAgSXMgY29ubmVjdGVkIHRvIHRoZSBnTkItQ1UtQ1AgdGhyb3VnaCB0aGUgRjEtQwogICAgICAgICAgICAgICAgICAgIGludGVyZmFjZS5JcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1DVS1VUCB0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgdGhlIEYxLVUgaW50ZXJmYWNlLiBPbmUgZ05CLURVIGlzIGNvbm5lY3RlZCB0byBvbmx5CiAgICAgICAgICAgICAgICAgICAgb25lIGdOQi1DVS1DUC4gT25lIGdOQi1EVSBjYW4gYmUgY29ubmVjdGVkIHRvCiAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGUgZ05CLUNVLVVQcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUgc2FtZQogICAgICAgICAgICAgICAgICAgIGdOQi1DVS1DUC4KICAgICAgICAgICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUKICAgICAgICAgICAgICAgICAgICBnTkItQ1UtVVBzIGFuZCBtdWx0aXBsZSBnTkItRFVzLiBnTkItRFUgaXMgYSBjb25jcmV0ZQogICAgICAgICAgICAgICAgICAgIGNsYXNzIHRoYXQgZXh0ZW5kcyB0aGUgTkctUkFOIG5vZGUgb2JqZWN0LiBJbiBUb3BvbG9neSwgeW91CiAgICAgICAgICAgICAgICAgICAgY2FuIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQgZGVsZXRlIHRoZSBnTkItRFUgb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZmRuIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIEZ1bGwgRGlzdGluZ3Vpc2hlZCBOYW1lIChGRE4pIGlkZW50aWZpZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIHRoZSBHTkJEVUZ1bmN0aW9uIE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgR05CRFVGdW5jdGlvbi4iOwogICAgICAgICAgICAgICAgdHlwZSBvci10ZWl2LXR5cGVzOl8zR1BQX0ZETl9UeXBlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250YWluZXIgZFVwTE1OSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlBMTU4gaWRlbnRpZmllciB1c2VkIGFzIHBhcnQgb2YgUE0gRXZlbnRzIGRhdGEiOwogICAgICAgICAgICAgICAgdXNlcyB0eXBlczNncHA6UExNTklkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGdOQkRVSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgRFUgd2l0aGluIGEgZ05vZGVCIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGdOQklkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJJZGVudGl0eSBvZiBnTm9kZUIgd2l0aGluIGEgUExNTiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBjbUlkIHsKICAgICAgICAgICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpDTV9JRDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEdOQkNVQ1BGdW5jdGlvbiB7CiAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQiBDZW50cmFsaXplZCBVbml0IENvbnRyb2wgUGxhbmUgKGdOQi1DVS1DUCkKCiAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyBhIGxvZ2ljYWwgbm9kZSBob3N0aW5nIHRoZSBSYWRpbyBSZXNvdXJjZQogICAgICAgICAgICAgICAgICAgIENvbnRyb2wgKFJSQykgYW5kIHRoZSBjb250cm9sIHBsYW5lIHBhcnQgb2YgdGhlCiAgICAgICAgICAgICAgICAgICAgUGFja2V0IERhdGEgQ29udmVyZ2VuY2UgUHJvdG9jb2wgKFBEQ1ApIG9mIHRoZQogICAgICAgICAgICAgICAgICAgIGdOb2RlQiBDZW50cmFsaXplZCBVbml0IChnTkItQ1UpIGZvciBhbiBFLVVUUkFOIGdOb2RlQgogICAgICAgICAgICAgICAgICAgIChlbi1nTkIpIG9yIGEgZ05vZGVCIChnTkIpLiBUaGUgZ05CLUNVLUNQIHRlcm1pbmF0ZXMKICAgICAgICAgICAgICAgICAgICB0aGUgRTEgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTkItQ1UtVVAgYW5kIHRoZQogICAgICAgICAgICAgICAgICAgIEYxLUMgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTm9kZUIKICAgICAgICAgICAgICAgICAgICBEaXN0cmlidXRlZCBVbml0IChnTkItRFUpLgoKICAgICAgICAgICAgICAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIGEgZ05CLUNVLUNQOgogICAgICAgICAgICAgICAgICAgIElzIGNvbm5lY3RlZCB0byB0aGUgZ05CLURVIHRocm91Z2ggdGhlIEYxLUMgaW50ZXJmYWNlLgogICAgICAgICAgICAgICAgICAgIElzIGNvbm5lY3RlZCB0byB0aGUgZ05CLUNVLVVQIHRocm91Z2ggdGhlIEUxIGludGVyZmFjZS4KICAgICAgICAgICAgICAgICAgICBPbmx5IG9uZSBnTkItQ1UtQ1AgaXMgY29ubmVjdGVkIHRvIG9uZSBnTkItRFUuCiAgICAgICAgICAgICAgICAgICAgT25seSBvbmUgZ05CLUNVLUNQIGlzIGNvbm5lY3RlZCB0byBvbmUgZ05CLUNVLVVQLgogICAgICAgICAgICAgICAgICAgIE9uZSBnTkItRFUgY2FuIGJlIGNvbm5lY3RlZCB0byBtdWx0aXBsZSBnTkItQ1UtVVBzCiAgICAgICAgICAgICAgICAgICAgdW5kZXIgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLk9uZSBnTkItQ1UtVVAKICAgICAgICAgICAgICAgICAgICBjYW4gYmUgY29ubmVjdGVkIHRvIG11bHRpcGxlIERVcyB1bmRlciB0aGUgY29udHJvbCBvZgogICAgICAgICAgICAgICAgICAgIHRoZSBzYW1lIGdOQi1DVS1DUC4KICAgICAgICAgICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUKICAgICAgICAgICAgICAgICAgICBnTkItQ1UtVVBzIGFuZCBtdWx0aXBsZSBnTkItRFVzLiBBIGdOQi1DVS1DUCBpcyBhCiAgICAgICAgICAgICAgICAgICAgY29uY3JldGUgY2xhc3MgdGhhdCBleHRlbmRzIHRoZSBORy1SQU4gbm9kZSBvYmplY3QuCiAgICAgICAgICAgICAgICAgICAgSW4gVG9wb2xvZ3ksIHlvdSBjYW4gY3JlYXRlLCByZWFkLCB1cGRhdGUsIGFuZCBkZWxldGUKICAgICAgICAgICAgICAgICAgICB0aGUgZ05CLUNVLUNQIG9iamVjdC4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGZkbiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBGdWxsIERpc3Rpbmd1aXNoZWQgTmFtZSAoRkROKSBpZGVudGlmaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiB0aGUgR05CQ1VDUEZ1bmN0aW9uIE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgR05CQ1VDUEZ1bmN0aW9uLiI7CiAgICAgICAgICAgICAgICB0eXBlIG9yLXRlaXYtdHlwZXM6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZ05CQ1VOYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIGdOb2RlQi1DVSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZ05CSWRMZW5ndGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxlbmd0aCBvZiBnTkJJZCBiaXQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250YWluZXIgcExNTklkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJQTE1OIGlkZW50aWZpZXIgdG8gYmUgdXNlZCBhcyBwYXJ0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZiBnbG9iYWwgUkFOIG5vZGUgaWRlbnRpdHkiOwogICAgICAgICAgICAgICAgdXNlcyB0eXBlczNncHA6UExNTklkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250YWluZXIgY21JZCB7CiAgICAgICAgICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6Q01fSUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBHTkJDVVVQRnVuY3Rpb24gewogICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUIgQ2VudHJhbGl6ZWQgVW5pdCBVc2VyIFBsYW5lIChnTkItQ1UtVVApCgogICAgICAgICAgICAgICAgICAgIEEgZ05CLUNVLVVQIGlzIGEgbG9naWNhbCBub2RlIGhvc3RpbmcgdGhlIFVzZXIKICAgICAgICAgICAgICAgICAgICBQbGFuZSBwYXJ0IG9mIHRoZSBQYWNrZXQgRGF0YSBDb252ZXJnZW5jZSwKICAgICAgICAgICAgICAgICAgICBQcm90b2NvbCAoUERDUCkgb2YgdGhlIGdOb2RlQiBDZW50cmFsaXplZCBVbml0CiAgICAgICAgICAgICAgICAgICAgKGdOQi1DVSkgZm9yIGFuIEUtVVRSQU4gZ05vZGVCIChlbi1nTkIpLCBhbmQgdGhlCiAgICAgICAgICAgICAgICAgICAgVXNlciBQbGFuZSBwYXJ0IG9mIHRoZSBQRENQIHByb3RvY29sIGFuZCB0aGUKICAgICAgICAgICAgICAgICAgICBTZXJ2aWNlIERhdGEgQWRhcHRhdGlvbiBQcm90b2NvbCAoU0RBUCkgb2YgdGhlCiAgICAgICAgICAgICAgICAgICAgZ05CLUNVIGZvciBhIGdOb2RlQiAoZ05CKS4gVGhlIGdOQi1DVS1VUCB0ZXJtaW5hdGVzCiAgICAgICAgICAgICAgICAgICAgdGhlIEUxIGludGVyZmFjZSBjb25uZWN0ZWQgd2l0aCB0aGUgZ05CLUNVLUNQIGFuZAogICAgICAgICAgICAgICAgICAgIHRoZSBGMS1VIGludGVyZmFjZSBjb25uZWN0ZWQgd2l0aCB0aGUgZ05vZGVCCiAgICAgICAgICAgICAgICAgICAgRGlzdHJpYnV0ZWQgVW5pdCAoZ05CLURVKS4KCiAgICAgICAgICAgICAgICAgICAgVGhlIGZvbGxvd2luZyBpcyB0cnVlIGZvciBhIGdOQi1DVS1VUDoKICAgICAgICAgICAgICAgICAgICBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1EVSB0aHJvdWdoIHRoZQogICAgICAgICAgICAgICAgICAgIEYxLVUgaW50ZXJmYWNlLiBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1DVS1DUCB0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgdGhlIEUxIGludGVyZmFjZS4gT25lIGdOQi1DVS1VUCBpcyBjb25uZWN0ZWQgdG8gb25seSBvbmUKICAgICAgICAgICAgICAgICAgICBnTkItQ1UtQ1AuIE9uZSBnTkItRFUgY2FuIGJlIGNvbm5lY3RlZCB0byBtdWx0aXBsZQogICAgICAgICAgICAgICAgICAgIGdOQi1DVS1VUHMgdW5kZXIgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLiBPbmUKICAgICAgICAgICAgICAgICAgICBnTkItQ1UtVVAgY2FuIGJlIGNvbm5lY3RlZCB0byBtdWx0aXBsZSBEVXMgdW5kZXIgdGhlCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCBvZiB0aGUgc2FtZSBnTkItQ1UtQ1AuCiAgICAgICAgICAgICAgICAgICAgTm90ZTogQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ1UtQ1AsIG11bHRpcGxlIGdOQi1DVS1VUHMKICAgICAgICAgICAgICAgICAgICBhbmQgbXVsdGlwbGUgZ05CLURVcy4gQSBnTkItQ1UtVVAgaXMgYSBjb25jcmV0ZSBjbGFzcyB0aGF0CiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kcyB0aGUgTkctUkFOIG5vZGUgb2JqZWN0LiBJbiBUb3BvbG9neSwgeW91IGNhbgogICAgICAgICAgICAgICAgICAgIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQgZGVsZXRlIHRoZSBnTkItQ1UtVVAgb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZmRuIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIEZ1bGwgRGlzdGluZ3Vpc2hlZCBOYW1lIChGRE4pIGlkZW50aWZpZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIHRoZSBHTkJDVVVQRnVuY3Rpb24gTU8uIEl0IGNvbnRhaW5zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZnVsbCBwYXRoIGZyb20gdGhlIFN1Ym5ldHdvcmsgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTkJDVVVQRnVuY3Rpb24uIjsKICAgICAgICAgICAgICAgIHR5cGUgb3ItdGVpdi10eXBlczpfM0dQUF9GRE5fVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZ05CSWRMZW5ndGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxlbmd0aCBvZiBnTkJJZCBiaXQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250YWluZXIgY21JZCB7CiAgICAgICAgICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6Q01fSUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBOUkNlbGxDVSB7CiAgICAgICAgZGVzY3JpcHRpb24gIlJlcHJlc2VudHMgYW4gTlIgQ2VsbCBpbiBnTm9kZUItQ1UuCgogICAgICAgICAgICAgICAgICAgIDVHIE5SIGlzIGEgbmV3IHJhZGlvIGFjY2VzcyB0ZWNobm9sb2d5IChSQVQpCiAgICAgICAgICAgICAgICAgICAgZGV2ZWxvcGVkIGJ5IDNHUFAgZm9yIHRoZSA1RyAoZmlmdGggZ2VuZXJhdGlvbikKICAgICAgICAgICAgICAgICAgICBtb2JpbGUgbmV0d29yay4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdGhlIGdsb2JhbAogICAgICAgICAgICAgICAgICAgIHN0YW5kYXJkIGZvciB0aGUgYWlyIGludGVyZmFjZSBvZiA1RyBuZXR3b3Jrcy4KCiAgICAgICAgICAgICAgICAgICAgNUcgTlIgaGFzIHN5bmNocm9uaXphdGlvbiBzaWduYWwgdGhhdCBpcyBrbm93biBhcwogICAgICAgICAgICAgICAgICAgIFByaW1hcnkgU3luY2hyb25pemF0aW9uIHNpZ25hbCAoUFNTKSBhbmQgU2Vjb25kYXJ5CiAgICAgICAgICAgICAgICAgICAgU3luY2hyb25pemF0aW9uIHNpZ25hbCAoU1NTKS4gVGhlc2Ugc2lnbmFscyBhcmUKICAgICAgICAgICAgICAgICAgICBzcGVjaWZpYyB0byBOUiBwaHlzaWNhbCBsYXllciBhbmQgcHJvdmlkZSB0aGUKICAgICAgICAgICAgICAgICAgICBmb2xsb3dpbmcgaW5mb3JtYXRpb24gcmVxdWlyZWQgYnkgVUUgZm9yIGRvd25saW5rCiAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemF0aW9uOiBQU1MgcHJvdmlkZXMgUmFkaW8gRnJhbWUgQm91bmRhcnkKICAgICAgICAgICAgICAgICAgICAoUG9zaXRpb24gb2YgMXN0IFN5bWJvbCBpbiBhIFJhZGlvIGZyYW1lKSBTU1MgcHJvdmlkZXMKICAgICAgICAgICAgICAgICAgICBTdWJmcmFtZSBCb3VuZGFyeSAoUG9zaXRpb24gb2YgMXN0IFN5bWJvbCBpbiBhIFN1YmZyYW1lKQogICAgICAgICAgICAgICAgICAgIFBoeXNpY2FsIExheWVyIENlbGwgSUQgKFBDSSkgaW5mb3JtYXRpb24gdXNpbmcgYm90aAogICAgICAgICAgICAgICAgICAgIFBTUyBhbmQgU1NTLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZmRuIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIEZ1bGwgRGlzdGluZ3Vpc2hlZCBOYW1lIChGRE4pIGlkZW50aWZpZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIHRoZSBOUkNlbGxDVSBNTy4gSXQgY29udGFpbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmdWxsIHBhdGggZnJvbSB0aGUgU3VibmV0d29yayB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5SQ2VsbENVLiI7CiAgICAgICAgICAgICAgICB0eXBlIG9yLXRlaXYtdHlwZXM6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgY2VsbExvY2FsSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVzZWQgdG9nZXRoZXIgd2l0aCBnTm9kZUIgaWRlbnRpZmllciB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZnkgTlIgY2VsbCBpbiBQTE1OLiBVc2VkIHRvZ2V0aGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIGdOQklkIHRvIGZvcm0gTkNJLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIHBsbW5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBJRCBmb3IgTlIgQ0dJLiBJZiBlbXB0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdOQkNVQ1BGdW5jdGlvbjo6cExNTklkIGlzIHVzZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBQTE1OIElEIGluIE5SIENHSSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgbkNJIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsIElkZW50aXR5IjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG5SVEFDIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBUcmFja2luZyBBcmVhIENvZGUgKFRBQykiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBjbUlkIHsKICAgICAgICAgICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpDTV9JRDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IE5SQ2VsbERVIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyBhbiBOUiBDZWxsIGluIGdOb2RlQi1EVS4KCiAgICAgICAgICAgICAgICAgICAgNUcgTlIgaXMgYSBuZXcgcmFkaW8gYWNjZXNzIHRlY2hub2xvZ3kgKFJBVCkKICAgICAgICAgICAgICAgICAgICBkZXZlbG9wZWQgYnkgM0dQUCBmb3IgdGhlIDVHIChmaWZ0aCBnZW5lcmF0aW9uKQogICAgICAgICAgICAgICAgICAgIG1vYmlsZSBuZXR3b3JrLiBJdCBpcyBkZXNpZ25lZCB0byBiZSB0aGUgZ2xvYmFsCiAgICAgICAgICAgICAgICAgICAgc3RhbmRhcmQgZm9yIHRoZSBhaXIgaW50ZXJmYWNlIG9mIDVHIG5ldHdvcmtzLgoKICAgICAgICAgICAgICAgICAgICA1RyBOUiBoYXMgc3luY2hyb25pemF0aW9uIHNpZ25hbCB0aGF0IGlzIGtub3duIGFzCiAgICAgICAgICAgICAgICAgICAgUHJpbWFyeSBTeW5jaHJvbml6YXRpb24gc2lnbmFsIChQU1MpIGFuZCBTZWNvbmRhcnkKICAgICAgICAgICAgICAgICAgICBTeW5jaHJvbml6YXRpb24gc2lnbmFsIChTU1MpLiBUaGVzZSBzaWduYWxzIGFyZQogICAgICAgICAgICAgICAgICAgIHNwZWNpZmljIHRvIE5SIHBoeXNpY2FsIGxheWVyIGFuZCBwcm92aWRlIHRoZQogICAgICAgICAgICAgICAgICAgIGZvbGxvd2luZyBpbmZvcm1hdGlvbiByZXF1aXJlZCBieSBVRSBmb3IgZG93bmxpbmsKICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6YXRpb246IFBTUyBwcm92aWRlcyBSYWRpbyBGcmFtZSBCb3VuZGFyeQogICAgICAgICAgICAgICAgICAgIChQb3NpdGlvbiBvZiAxc3QgU3ltYm9sIGluIGEgUmFkaW8gZnJhbWUpIFNTUyBwcm92aWRlcwogICAgICAgICAgICAgICAgICAgIFN1YmZyYW1lIEJvdW5kYXJ5IChQb3NpdGlvbiBvZiAxc3QgU3ltYm9sIGluIGEgU3ViZnJhbWUpCiAgICAgICAgICAgICAgICAgICAgUGh5c2ljYWwgTGF5ZXIgQ2VsbCBJRCAoUENJKSBpbmZvcm1hdGlvbiB1c2luZyBib3RoCiAgICAgICAgICAgICAgICAgICAgUFNTIGFuZCBTU1MuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBmZG4gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoaXMgRnVsbCBEaXN0aW5ndWlzaGVkIE5hbWUgKEZETikgaWRlbnRpZmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gaW5zdGFuY2Ugb2YgdGhlIE5SQ2VsbERVIE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlJDZWxsRFUuIjsKICAgICAgICAgICAgICAgIHR5cGUgb3ItdGVpdi10eXBlczpfM0dQUF9GRE5fVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBjZWxsTG9jYWxJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVXNlZCB0b2dldGhlciB3aXRoIGdOb2RlQiBpZGVudGlmaWVyIHRvIGlkZW50aWZ5IE5SCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2VsbCBpbiBQTE1OLiBVc2VkIHRvZ2V0aGVyIHdpdGggZ05CSWQgdG8gZm9ybSBOQ0kuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG5DSSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbCBJZGVudGl0eS4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgblJQQ0kgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBQaHlzaWNhbCBDZWxsIElkZW50aXR5IChQQ0kpIG9mIHRoZSBOUiBjZWxsLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBuUlRBQyB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgVHJhY2tpbmcgQXJlYSBDb2RlIChUQUMpLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgRU5vZGVCRnVuY3Rpb24gewogICAgICAgIGRlc2NyaXB0aW9uICJBbiBFdm9sdmVkIE5vZGUgQiAoZU5vZGVCKSBpcyB0aGUgb25seSBtYW5kYXRvcnkKICAgICAgICAgICAgICAgICAgICBub2RlIGluIHRoZSByYWRpbyBhY2Nlc3MgbmV0d29yayAoUkFOKSBvZiBMb25nLVRlcm0KICAgICAgICAgICAgICAgICAgICBFdm9sdXRpb24gKExURSkuIFRoZSBlTm9kZUIgaXMgYSBjb21wbGV4IGJhc2UKICAgICAgICAgICAgICAgICAgICBzdGF0aW9uIHRoYXQgaGFuZGxlcyByYWRpbyBjb21tdW5pY2F0aW9ucwogICAgICAgICAgICAgICAgICAgIGluIHRoZSBjZWxsIGFuZCBjYXJyaWVzIG91dCByYWRpbyByZXNvdXJjZQogICAgICAgICAgICAgICAgICAgIG1hbmFnZW1lbnQgYW5kIGhhbmRvdmVyIGRlY2lzaW9ucy4gVW5saWtlIDIvM0cKICAgICAgICAgICAgICAgICAgICB3aXJlbGVzcyBSQU4sIHRoZXJlIGlzIG5vIGNlbnRyYWxpemVkIHJhZGlvIG5ldHdvcmsKICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyIGluIExURS4gSXQgaXMgdGhlIGhhcmR3YXJlIHRoYXQgaXMgY29ubmVjdGVkCiAgICAgICAgICAgICAgICAgICAgdG8gdGhlIG1vYmlsZSBwaG9uZSBuZXR3b3JrIHRoYXQgY29tbXVuaWNhdGVzCiAgICAgICAgICAgICAgICAgICAgZGlyZWN0bHkgd2l0aCBtb2JpbGUgaGFuZHNldHMgKFVzZXIgRXF1aXBtZW50KSwgbGlrZSBhIGJhc2UKICAgICAgICAgICAgICAgICAgICB0cmFuc2NlaXZlciBzdGF0aW9uIChCVFMpIGluIEdTTSBuZXR3b3Jrcy4gVGhpcyBzaW1wbGlmaWVzCiAgICAgICAgICAgICAgICAgICAgdGhlIGFyY2hpdGVjdHVyZSBhbmQgYWxsb3dzIGxvd2VyIHJlc3BvbnNlIHRpbWVzLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZmRuIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIEZ1bGwgRGlzdGluZ3Vpc2hlZCBOYW1lIChGRE4pIGlkZW50aWZpZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuIGluc3RhbmNlIG9mIHRoZSBFTm9kZUJGdW5jdGlvbiBNTy4gSXQgY29udGFpbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmdWxsIHBhdGggZnJvbSB0aGUgU3VibmV0d29yayB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVOb2RlQkZ1bmN0aW9uLiI7CiAgICAgICAgICAgICAgICB0eXBlIG9yLXRlaXYtdHlwZXM6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZU5CSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgSUQgdGhhdCBmb3JtcyBwYXJ0IG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgQ2VsbCBHbG9iYWwgSWRlbnRpdHksIGFuZCBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxzbyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIG92ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBTMSBpbnRlcmZhY2UiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBlTm9kZUJQbG1uSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgUHVibGljIExhbmQgTW9iaWxlIE5ldHdvcmsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQTE1OKSBJRCB0aGF0IGZvcm1zIHBhcnQgb2YgdGhlIEVOb2RlQgogICAgICAgICAgICAgICAgICAgICAgICAgICAgR2xvYmFsIElEIHVzZWQgdG8gaWRlbnRpZnkgdGhlIG5vZGUgb3ZlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIFMxIGludGVyZmFjZS4gTm90ZTogVGhlIHZhbHVlIChNQ0M9MDAxLCBNTkM9MDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRpY2F0ZXMgdGhhdCB0aGUgUExNTiBpcyBub3QgaW5pdGlhdGVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIGNhbiBub3QgYmUgdXNlZCBhcyBhIHZhbGlkIFBMTU4gSWRlbnRpdHkuIjsKCiAgICAgICAgICAgICAgICBsZWFmIG1jYyB7CiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBNQ0MgcGFydCBvZiBhIFBMTU4gaWRlbnRpdHkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIGluIHRoZSByYWRpbyBuZXR3b3JrLiI7CiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnQzMiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlIDAuLjk5OTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZWFmIG1uYyB7CiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBNTkMgcGFydCBvZiBhIFBMTU4gaWRlbnRpdHkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIGluIHRoZSByYWRpbyBuZXR3b3JrLiI7CiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnQzMiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlIDAuLjk5OTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZWFmIG1uY0xlbmd0aCB7CiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBsZW5ndGggb2YgdGhlIE1OQyBwYXJ0IG9mIGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTE1OIGlkZW50aXR5IHVzZWQgaW4gdGhlIHJhZGlvIG5ldHdvcmsuIjsKICAgICAgICAgICAgICAgICAgICB0eXBlIGludDMyIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgMi4uMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBjbUlkIHsKICAgICAgICAgICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpDTV9JRDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEVVdHJhbkNlbGwgewogICAgICAgIGRlc2NyaXB0aW9uICJSZXByZXNlbnRzIGFuIEZERCBvciBUREQgRVV0cmFuQ2VsbCBhbmQKICAgICAgICAgICAgICAgICAgICBjb250YWlucyBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2VsbC4KICAgICAgICAgICAgICAgICAgICBJdCBhbHNvIGNvbnRhaW5zIHBhcmFtZXRlcnMgZm9yIHRoZQogICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeSBjb21tb24gY2hhbm5lbHMuIEFuIEVVVFJBTiBzdGFuZHMKICAgICAgICAgICAgICAgICAgICBmb3IgRXZvbHZlZCBVbml2ZXJzYWwgTW9iaWxlIFRlbGVjb21tdW5pY2F0aW9ucwogICAgICAgICAgICAgICAgICAgIFN5c3RlbSAoVU1UUykgVGVycmVzdHJpYWwgUmFkaW8gQWNjZXNzIE5ldHdvcmsKICAgICAgICAgICAgICAgICAgICB3aGljaCBjb250YWlucyBhbiBlTm9kZUIuIFRoZSBlTm9kZUIgY29uY3JldGUKICAgICAgICAgICAgICAgICAgICBjbGFzcyBpcyBleHRlbmRlZCBmcm9tIHRoZSBFVVRSQU4gTm9kZSBhYnN0cmFjdCBjbGFzcy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGZkbiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBGdWxsIERpc3Rpbmd1aXNoZWQgTmFtZSAoRkROKSBpZGVudGlmaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiBlaXRoZXIgdGhlIEVVdHJhbkNlbGxGREQgTU8gb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBFVXRyYW5DZWxsVEREIE1PLiBJdCBjb250YWlucyB0aGUgZnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZSBFVXRyYW5DZWxsRkREIG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFVXRyYW5DZWxsVERELiI7CiAgICAgICAgICAgICAgICB0eXBlIG9yLXRlaXYtdHlwZXM6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgY2VsbElkewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlJCUyBpbnRlcm5hbCBJRCBhdHRyaWJ1dGUgZm9yIEVVdHJhbkNlbGwuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdXN0IGJlIHVuaXF1ZSBpbiB0aGUgUkJTLiBUb2dldGhlciB3aXRoIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZSBJRCBhbmQgUHVibGljIExhbmQgTW9iaWxlIE5ldHdvcmsgKFBMTU4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGlzIGEgdW5pdmVyc2FsbHkgdW5pcXVlIGNlbGwgSUQiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZWFyZmNuZGwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjaGFubmVsIG51bWJlciBmb3IgdGhlIGNlbnRyYWwgZG93bmxpbmsgZnJlcXVlbmN5LiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBlYXJmY251bCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiQ2hhbm5lbCBudW1iZXIgZm9yIHRoZSBjZW50cmFsIHVwbGluayBmcmVxdWVuY3kiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZGxDaGFubmVsQmFuZHdpZHRoIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgZG93bmxpbmsgY2hhbm5lbCBiYW5kd2lkdGggaW4gdGhlIEZERCBjZWxsLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBlYXJmY24gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFLVVUUkEgQWJzb2x1dGUgUmFkaW8gRnJlcXVlbmN5IENoYW5uZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bWJlciAoRUFSRkNOKSBmb3IgdGhlIFRERCBjZWxsIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGNoYW5uZWxCYW5kd2lkdGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjaGFubmVsIGJhbmR3aWR0aCBpbiB0aGUgVEREIGNlbGwuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIHRhYyB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVHJhY2tpbmcgQXJlYSBDb2RlIGZvciB0aGUgRVV0cmFuIENlbGwiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZHVwbGV4VHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdG9yIG9mIEVVdHJhbkNlbGwgdHlwZSwgRkREIG9yIFRERCI7CiAgICAgICAgICAgICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICAgICAgICAgICAgICBlbnVtIGZkZCB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJGREQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbnVtIHRkZCB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUREQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTlJTZWN0b3JDYXJyaWVyIHsKICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIE5SIFNlY3RvciBDYXJyaWVyIG9iamVjdCBwcm92aWRlcwogICAgICAgICAgICAgICAgICAgIHRoZSBhdHRyaWJ1dGVzIGZvciBkZWZpbmluZyB0aGUgbG9naWNhbAogICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlcmlzdGljcyBvZiBhIGNhcnJpZXIgKGNlbGwpIGluIGEKICAgICAgICAgICAgICAgICAgICBzZWN0b3IuIEEgc2VjdG9yIGlzIGEgY292ZXJhZ2UgYXJlYSBhc3NvY2lhdGVkCiAgICAgICAgICAgICAgICAgICAgd2l0aCBhIGJhc2Ugc3RhdGlvbiBoYXZpbmcgaXRzIG93biBhbnRlbm5hcywKICAgICAgICAgICAgICAgICAgICByYWRpbyBwb3J0cywgYW5kIGNvbnRyb2wgY2hhbm5lbHMuIFRoZSBjb25jZXB0CiAgICAgICAgICAgICAgICAgICAgb2Ygc2VjdG9ycyB3YXMgZGV2ZWxvcGVkIHRvIGltcHJvdmUgY28tY2hhbm5lbAogICAgICAgICAgICAgICAgICAgIGludGVyZmVyZW5jZSBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcwogICAgICAgICAgICAgICAgICAgIHN5c3RlbXMgdXNlIHRocmVlIHNlY3RvciBjZWxscy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGZkbiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBGdWxsIERpc3Rpbmd1aXNoZWQgTmFtZSAoRkROKSBpZGVudGlmaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiB0aGUgTlJTZWN0b3JDYXJyaWVyIE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlJTZWN0b3JDYXJyaWVyLiI7CiAgICAgICAgICAgICAgICB0eXBlIG9yLXRlaXYtdHlwZXM6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgYXJmY25ETCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQWJzb2x1dGUgUmFkaW8gRnJlcXVlbmN5IENoYW5uZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bWJlciAoTlItQVJGQ04pIGZvciBkb3dubGluayI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBhcmZjblVMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBBYnNvbHV0ZSBSYWRpbyBmcmVxdWVuY3kgQ2hhbm5lbCBOdW1iZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChOUi1BUkZDTikgZm9yIHVwbGluay4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZnJlcXVlbmN5REwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlJGIFJlZmVyZW5jZSBGcmVxdWVuY3kgb2YgZG93bmxpbmsgY2hhbm5lbCI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBmcmVxdWVuY3lVTCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUkYgUmVmZXJlbmNlIEZyZXF1ZW5jeSBvZiB1cGxpbmsgY2hhbm5lbCI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBiU0NoYW5uZWxCd0RMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJCUyBDaGFubmVsIGJhbmR3aWR0aCBpbiBNSHogZm9yIGRvd25saW5rLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTFRFU2VjdG9yQ2FycmllciB7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBMVEUgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZQogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgZm9yIGRlZmluaW5nIHRoZSBsb2dpY2FsIGNoYXJhY3RlcmlzdGljcwogICAgICAgICAgICAgICAgICAgIG9mIGEgY2FycmllciAoY2VsbCkgaW4gYSBzZWN0b3IuIEEgc2VjdG9yIGlzIGEgY292ZXJhZ2UKICAgICAgICAgICAgICAgICAgICBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbiBoYXZpbmcKICAgICAgICAgICAgICAgICAgICBpdHMgb3duIGFudGVubmFzLCByYWRpbyBwb3J0cywgYW5kIGNvbnRyb2wgY2hhbm5lbHMuCiAgICAgICAgICAgICAgICAgICAgVGhlIGNvbmNlcHQgb2Ygc2VjdG9ycyB3YXMgZGV2ZWxvcGVkIHRvIGltcHJvdmUgY28tY2hhbm5lbAogICAgICAgICAgICAgICAgICAgIGludGVyZmVyZW5jZSBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zCiAgICAgICAgICAgICAgICAgICAgdXNlIHRocmVlIHNlY3RvciBjZWxscy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGZkbiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBGdWxsIERpc3Rpbmd1aXNoZWQgTmFtZSAoRkROKSBpZGVudGlmaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiB0aGUgU2VjdG9yQ2FycmllciBNTy4gSXQgY29udGFpbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmdWxsIHBhdGggZnJvbSB0aGUgU3VibmV0d29yayB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlY3RvckNhcnJpZXIuIjsKICAgICAgICAgICAgICAgIHR5cGUgb3ItdGVpdi10eXBlczpfM0dQUF9GRE5fVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBzZWN0b3JDYXJyaWVyVHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzZWN0b3IgY2FycmllcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxsZWQgYnkgTU8gU2VjdG9yQ2FycmllciBpcyBhIGRpZ2l0YWwgc2VjdG9yLiI7CiAgICAgICAgICAgICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICAgICAgICAgICAgICBlbnVtIG5vcm1hbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTm90IGEgZGlnaXRhbCBzZWN0b3IiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbnVtIGxlZnRfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAxOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVmdCBkaWdpdGFsIHNlY3RvciBmb3IgMkRTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSByaWdodF9kaWdpdGFsX3NlY3RvciB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJSaWdodCBkaWdpdGFsIHNlY3RvciBmb3IgMkRTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBsZWZ0X2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDM7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMZWZ0IGRpZ2l0YWwgc2VjdG9yIGZvciAzRFMiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbnVtIHJpZ2h0X2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJSaWdodCBkaWdpdGFsIHNlY3RvciBmb3IgM0RTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBtaWRkbGVfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA1OwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWlkZGxlIGRpZ2l0YWwgc2VjdG9yIGZvciAzRFMiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgQW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIE1PIHNlcnZlcyBhcyBhIG1hcHBpbmcgYmV0d2VlbiB0aGUgY2VsbAogICAgICAgICAgICAgICAgICAgIGFuZCB0aGUgUkJTIGVxdWlwbWVudCB1c2VkIHRvIHByb3ZpZGUgY292ZXJhZ2UKICAgICAgICAgICAgICAgICAgICBpbiBhIGNlcnRhaW4gZ2VvZ3JhcGhpY2FsIGFyZWEuIFRoZSBNTyBhbHNvCiAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgdGhlIG1heGltdW0gb3V0cHV0IHBvd2VyIG9mIHRoZSBzZWN0b3IuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBmZG4gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoaXMgRnVsbCBEaXN0aW5ndWlzaGVkIE5hbWUgKEZETikgaWRlbnRpZmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gaW5zdGFuY2Ugb2YgdGhlIFNlY3RvckVxdWlwbWVudEZ1bmN0aW9uIE1PLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXQgY29udGFpbnMgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byB0aGUgU2VjdG9yRXF1aXBtZW50RnVuY3Rpb24uIjsKICAgICAgICAgICAgICAgIHR5cGUgb3ItdGVpdi10eXBlczpfM0dQUF9GRE5fVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZi1saXN0IGVVdHJhbkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgTFRFIGZyZXF1ZW5jeSBiYW5kcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBhc3NvY2lhdGVkIGhhcmR3YXJlIHN1cHBvcnRzIjsKICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgZ2VyYW5GcUJhbmRzIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMaXN0IG9mIEdFUkFOIGZyZXF1ZW5jeSBiYW5kcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBhc3NvY2lhdGVkIGhhcmR3YXJlIHN1cHBvcnRzIjsKICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgblJGcUJhbmRzIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMaXN0IG9mIE5SIGZyZXF1ZW5jeSBiYW5kcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2NpYXRlZCBoYXJkd2FyZSBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgU2VjdG9yIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBncm91cCBvZiBjby1sb2NhdGVkIENlbGxzIHRoYXQKICAgICAgICAgICAgICAgICAgICBoYXZlIGEgc2hhcmVkIGNvdmVyYWdlIGFyZWEuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBzZWN0b3JJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVW5pdmVyc2FsbHkgdW5pcXVlIElEIGdlbmVyYXRlZCBieSB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY3RvcidzIGRpc2NvdmVyeSBtZWNoYW5pc20uIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDY0OwogICAgICAgICAgICB9CgogICAgICAgICAgICB1c2VzIGdlbzpnZW8tbG9jYXRpb247CgogICAgICAgICAgICBsZWFmIGF6aW11dGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkF2ZXJhZ2UgdmFsdWUgb2YgdGhlIGF6aW11dGhzIG9mIHRoZSBjZWxscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcHJpc2luZyB0aGUgc2VjdG9yLCBkZXRlcm1pbmVkIGR1cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VjdG9yIGRpc2NvdmVyeS4iOwogICAgICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjR7CiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1bml0cyAiZGVncmVlcyI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfRVVUUkFOQ0VMTCB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIEVVVFJBTiBDZWxsLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBFTm9kZUJGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBwcm92aWRlZC1ieS1lbm9kZWJGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCBwcm92aWRlZCBieSBlTm9kZUIgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEVVdHJhbkNlbGw7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHByb3ZpZGVkIGJ5IGVOb2RlQiBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTFRFU2VjdG9yQ2FycmllcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBHTkJEVUZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTERVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIENlbGwtRFUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIEdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZ25iZHVGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLURVIHByb3ZpZGVkIGJ5IGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CRFVGVU5DVElPTl9QUk9WSURFU19OUlNFQ1RPUkNBUlJJRVIgeyAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBwcm92aWRlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBHTkJEVUZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmR1RnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgU2VjdG9yIENhcnJpZXIgcHJvdmlkZWQgYnkgZ05vZGVCLURVIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUlNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CQ1VDUEZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTENVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsQ3UgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVQ1AgRnVuY3Rpb24gcHJvdmlkZXMgTlIgQ2VsbC1DVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgR05CQ1VDUEZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLUNVIHByb3ZpZGVkIGJ5IGdOb2RlQi1DVUNQIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUkNlbGxDVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBFVVRSQU5DRUxMX1VTRVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHVzZWQtbHRlU2VjdG9yQ2FycmllciB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCB1c2VzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRVV0cmFuQ2VsbDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgRVVUUkFOIENlbGwuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBMVEVTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMVEUgU2VjdG9yIENhcnJpZXIgdXNlcyBBbnRlbm5hIENhcGFiaWxpdHkuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYtbGlzdCB1c2VkLWJ5LWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTFRFIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBBbnRlbm5hQ2FwYWJpbGl0eTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5SQ0VMTERVX1VTRVNfTlJTRUNUT1JDQVJSSUVSIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSB1c2VzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBOUkNlbGxEVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LW5yQ2VsbER1IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgTlIgQ2VsbC1EVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTlJTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBTZWN0b3IgQ2FycmllciB1c2VzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1ieS1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTlIgU2VjdG9yIENhcnJpZXIuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgU0VDVE9SX0dST1VQU19OUkNFTExEVSB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IGdyb3VwZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBOUiBDZWxsLURVLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBTZWN0b3I7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgZ3JvdXBlZC1ieS1zZWN0b3IgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSBncm91cGVkIGJ5IFNlY3Rvci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBTRUNUT1JfR1JPVVBTX0VVVFJBTkNFTEwgeyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBFVVRSQU4gQ2VsbC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgU2VjdG9yOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGdyb3VwZWQtYnktc2VjdG9yIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkVVVFJBTiBDZWxsIGdyb3VwZWQgYnkgU2VjdG9yLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBFVXRyYW5DZWxsOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQp9        BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-equipment       urn:o-ran:smo-teiv-equipment    EQUIPMENT       []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWVxdWlwbWVudCB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtZXF1aXBtZW50IjsKICAgIHByZWZpeCBvci10ZWl2LWVxdWlwOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7cHJlZml4IG9yLXRlaXYtdHlwZXM7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IG9yLXRlaXYteWV4dDsgfQoKICAgIGltcG9ydCBpZXRmLWdlby1sb2NhdGlvbiB7CiAgICAgICAgcHJlZml4IGdlbzsKICAgICAgICByZWZlcmVuY2UgIlJGQyA5MTc5OiBBIFlBTkcgR3JvdXBpbmcgZm9yIEdlb2dyYXBoaWMgTG9jYXRpb25zIjsKICAgIH0KCiAgICBvcmdhbml6YXRpb24gIkVyaWNzc29uIEFCIjsKICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOwogICAgZGVzY3JpcHRpb24KICAgICJSQU4gRXF1aXBtZW50IHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIEVxdWlwbWVudCBkb21haW4sIHdoaWNoIGlzIG1vZGVsbGVkIHRvIHVuZGVyc3RhbmQgdGhlIHBoeXNpY2FsCiAgICBsb2NhdGlvbiBvZiBlcXVpcG1lbnQgc3VjaCBhcyBhbnRlbm5hcyBhc3NvY2lhdGVkIHdpdGggYSBjZWxsL2NhcnJpZXIKICAgIGFuZCB0aGVpciByZWxldmFudCBwcm9wZXJ0aWVzIGUuZy4gdGlsdCwgbWF4IHBvd2VyIGV0Yy4iOwoKICAgIHJldmlzaW9uICIyMDI0LTA1LTAyIiB7CiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmRvbWFpbiBFUVVJUE1FTlQ7CgogICAgbGlzdCBBbnRlbm5hTW9kdWxlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gQW50ZW5uYSBNb2R1bGUgcmVwcmVzZW50cyB0aGUKICAgICAgICAgICAgICAgICAgICBwaHlzaWNhbCBhc3BlY3Qgb2YgYW4gYW50ZW5uYS4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGZkbiB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBGdWxsIERpc3Rpbmd1aXNoZWQgTmFtZSAoRkROKSBpZGVudGlmaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiB0aGUgQW50ZW5uYVN1YlVuaXQgTU8uIEl0IGNvbnRhaW5zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZnVsbCBwYXRoIGZyb20gdGhlIFN1Ym5ldHdvcmsgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnRlbm5hU3ViVW5pdC4iOwogICAgICAgICAgICAgICAgdHlwZSBvci10ZWl2LXR5cGVzOl8zR1BQX0ZETl9UeXBlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGFudGVubmFNb2RlbE51bWJlciB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVmVuZG9yLXNwZWNpZmljIGFudGVubmEgbW9kZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIuIFRoaXMgYXR0cmlidXRlIGlzIHBhcnQgb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFJU0cgdjMgQURCIFN0YW5kYXJkIGFuZCBoYXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vIG9wZXJhdGlvbmFsIGltcGFjdC4iOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgbWVjaGFuaWNhbEFudGVubmFCZWFyaW5nIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIGJlYXJpbmcgb24gYW50ZW5uYSBzdWJ1bml0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVyZSBhbnRlbm5hIHVuaXQgaXMgaW5zdGFsbGVkLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBtZWNoYW5pY2FsQW50ZW5uYVRpbHQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBmaXhlZCBhbnRlbm5hIHRpbHQgb2YgdGhlIGluc3RhbGxhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmluZWQgYXMgdGhlIGluY2xpbmF0aW9uIG9mIHRoZSBhbnRlbm5hCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50IHJlc3BlY3QgdG8gdGhlIHZlcnRpY2FsIHBsYW5lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXQgaXMgYSBzaWduZWQgdmFsdWUuIFBvc2l0aXZlIGluZGljYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bnRpbHQsIGFuZCBuZWdhdGl2ZSBpbmRpY2F0ZXMgdXB0aWx0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBwb3NpdGlvbldpdGhpblNlY3RvciB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSB1bml0IHBvc2l0aW9uIHdpdGhpbiBzZWN0b3IuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGF0dHJpYnV0ZSBpcyBwYXJ0IG9mIEFJU0cgdjMgQURCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFuZGFyZCBhbmQgaGFzIG5vIG9wZXJhdGlvbmFsIGltcGFjdC4iOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgdG90YWxUaWx0IHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUb3RhbCBhbnRlbm5hIGVsZXZhdGlvbiBpbmNsdWRpbmcgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YWxsZWQgdGlsdCBhbmQgdGhlIHRpbHQgYXBwbGllZCBieQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIFJlbW90ZSBFbGVjdHJpY2FsIFRpbHQgKFJFVCkuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVsZWN0cmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiRWxlY3RyaWNhbGx5LWNvbnRyb2xsZWQgdGlsdCBvZiBtYWluIGJlYW0gbWF4aW11bQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCByZXNwZWN0IHRvIGRpcmVjdGlvbiBvcnRob2dvbmFsIHRvIGFudGVubmEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgYXhpcyAoc2VlIDNHUFAgVFMgMjUuNDY2KS4gVmFsdWUgaXMgc2lnbmVkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlsdCBkb3duIGlzIHBvc2l0aXZlLCB0aWx0IHVwIGlzIG5lZ2F0aXZlLiI7CiAgICAgICAgICAgICAgICB0eXBlIHVpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZi1saXN0IGFudGVubmFCZWFtV2lkdGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBhbmd1bGFyIHNwYW4gb2YgdGhlIG1haW4gbG9iZSBvZiB0aGUgYW50ZW5uYSByYWRpYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiBpbiB0aGUgaG9yaXpvbnRhbCBwbGFuZS4gTWVhc3VyZWQgaW4gZGVncmVlcy4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzZXMgZ2VvOmdlby1sb2NhdGlvbjsKCiAgICAgICAgICAgIGNvbnRhaW5lciBjbUlkIHsKICAgICAgICAgICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpDTV9JRDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IFNpdGUgewogICAgICAgIGRlc2NyaXB0aW9uICJBIHNpdGUgaXMgYSBwaHlzaWNhbCBsb2NhdGlvbiB3aGVyZSBhbiBBbnRlbm5hIG9yCiAgICAgICAgICAgICAgICAgICAgUGh5c2ljYWwgTkYgY2FuIGJlIGluc3RhbGxlZC4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIG5hbWUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5hbWUgb2YgU2l0ZSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdXNlcyBnZW86Z2VvLWxvY2F0aW9uOwoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgUGh5c2ljYWxORiB7CiAgICAgICAgZGVzY3JpcHRpb24gIlJlcHJlc2VudHMgYSBQaHlzaWNhbCBORiwKICAgICAgICAgICAgICAgICAgICB3aGljaCBpcyB1c2VkIHRvIHJlYWxpc2UgTmV0d29yayBGdW5jdGlvbnMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBuYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIFBoeXNpY2FsIE5GLiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiB0eXBlIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUeXBlIG9mIFBoeXNpY2FsIE5GLiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdXNlcyBnZW86Z2VvLWxvY2F0aW9uOwoKICAgICAgICAgICAgY29udGFpbmVyIGNtSWQgewogICAgICAgICAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOkNNX0lEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgQU5URU5OQU1PRFVMRV9JTlNUQUxMRURfQVRfU0lURSB7IC8vIDAuLm4gdG8gMC4uMQoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZiBpbnN0YWxsZWQtYXQtc2l0ZSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIE1vZHVsZSBpbnN0YWxsZWQgYXQgU2l0ZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgQW50ZW5uYU1vZHVsZTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IGluc3RhbGxlZC1hbnRlbm5hTW9kdWxlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIlNpdGUgd2hlcmUgQW50ZW5uYSBNb2R1bGUgaXMgaW5zdGFsbGVkLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBTaXRlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgUEhZU0lDQUxORl9JTlNUQUxMRURfQVRfU0lURSB7IC8vIDEuLm4gdG8gMC4uMQoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZiBpbnN0YWxsZWQtYXQtc2l0ZSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJQaHlzaWNhbCBORiBpbnN0YWxsZWQgYXQgU2l0ZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgUGh5c2ljYWxORjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IGluc3RhbGxlZC1waHlzaWNhbE5GIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIlNpdGUgd2hlcmUgUGh5c2ljYWwgTkYgaXMgaW5zdGFsbGVkLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBTaXRlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgICAgIG1pbi1lbGVtZW50cyAxOwogICAgICAgIH0KICAgIH0KfQ==        BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-cloud-to-ran    urn:o-ran:smo-teiv-cloud-to-ran CLOUD_TO_RAN    ["o-ran-smo-teiv-cloud", "o-ran-smo-teiv-ran"]  2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNsb3VkLXRvLXJhbiB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtY2xvdWQtdG8tcmFuIjsKICAgIHByZWZpeCBvci10ZWl2LWNsb3VkdG9yYW47CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggb3ItdGVpdi10eXBlczsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNsb3VkIHtwcmVmaXggb3ItdGVpdi1jbG91ZDsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1yYW4ge3ByZWZpeCBvci10ZWl2LXJhbjsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiBDbG91ZCB0byBSQU4gTG9naWNhbCB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjMgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIENsb3VkIHRvIFJBTiBMb2dpY2FsIHRvcG9sb2d5IHJlbGF0aW9ucyI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMDIiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIENMT1VEX1RPX1JBTjsKCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5GREVQTE9ZTUVOVF9TRVJWRVNfR05CRFVGVU5DVElPTiB7IC8vIDAuLm4gdG8gMC4ubQoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHNlcnZpY2VkLWduYmR1RnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCRFUgRnVuY3Rpb24gc2VydmljZWQgYnkgdGhpcyBORiBEZXBsb3ltZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBvci10ZWl2LWNsb3VkOk5GRGVwbG95bWVudDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IHNlcnZpbmctbkZEZXBsb3ltZW50IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5GIERlcGxveW1lbnQgdGhhdCBzZXJ2ZXMgdGhpcyBnTm9kZUJEVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46R05CRFVGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5GREVQTE9ZTUVOVF9TRVJWRVNfR05CQ1VDUEZVTkNUSU9OIHsgLy8gMC4ubiB0byAwLi5tCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtZ25iY3VjcEZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQi1DVS1DUCBGdW5jdGlvbiBzZXJ2aWNlZCBieSB0aGlzIE5GIERlcGxveW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtY2xvdWQ6TkZEZXBsb3ltZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1uRkRlcGxveW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTkYgRGVwbG95bWVudCB0aGF0IHNlcnZlcyB0aGlzIGdOb2RlQkNVQ1AgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkNVQ1BGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5GREVQTE9ZTUVOVF9TRVJWRVNfR05CQ1VVUEZVTkNUSU9OIHsgLy8gMC4ubiB0byAwLi5tCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtZ25iY3V1cEZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQi1DVS1VUCBGdW5jdGlvbiBzZXJ2aWNlZCBieSB0aGlzIE5GIERlcGxveW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtY2xvdWQ6TkZEZXBsb3ltZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1uRkRlcGxveW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTkYgRGVwbG95bWVudCB0aGF0IHNlcnZlcyB0aGlzIGdOb2RlQkNVVVAgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkNVVVBGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KfQ==    BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-cloud   urn:o-ran:smo-teiv-cloud        CLOUD   []      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNsb3VkIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1jbG91ZCI7CiAgICBwcmVmaXggb3ItdGVpdi1jbG91ZDsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgaWV0Zi1nZW8tbG9jYXRpb24gewogICAgICAgIHByZWZpeCBnZW87CiAgICAgICAgcmVmZXJlbmNlICJSRkMgOTE3OTogQSBZQU5HIEdyb3VwaW5nIGZvciBHZW9ncmFwaGljIExvY2F0aW9ucyI7CiAgICB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiUkFOIENsb3VkIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIENMT1VEIGRvbWFpbiwgd2hpY2ggY29tcHJpc2VzIGNsb3VkIGluZnJhc3RydWN0dXJlIGFuZAogICAgZGVwbG95bWVudCBhc3BlY3RzIHRoYXQgY2FuIGJlIHVzZWQgaW4gdGhlIHRvcG9sb2d5IG1vZGVsLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMDIiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIENMT1VEOwoKICAgIGxpc3QgQ2xvdWRpZmllZE5GIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBSQU4gTmV0d29yayBGdW5jdGlvbiBzb2Z0d2FyZSB0aGF0IGlzIGRlcGxveWVkIGluIHRoZSBPLUNsb3VkIHZpYSBvbmUgb3IgbW9yZSBORiBEZXBsb3ltZW50cy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIG5hbWUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5hbWUgb2YgQ2xvdWRpZmllZCBORiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IE5GRGVwbG95bWVudCB7CiAgICAgICAgZGVzY3JpcHRpb24gIkEgc29mdHdhcmUgZGVwbG95bWVudCBvbiBPLUNsb3VkIHJlc291cmNlcyB0aGF0IHJlYWxpemVzLCBhbGwgb3IgcGFydCBvZiwgYSBDbG91ZGlmaWVkIE5GLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgbmFtZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTmFtZSBvZiBORiBEZXBsb3ltZW50IjsKICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgQ2xvdWROYW1lc3BhY2UgewogICAgICAgIGRlc2NyaXB0aW9uICJDbG91ZE5hbWVzcGFjZSBwcm92aWRlIGEgbWVjaGFuaXNtIGZvciBpc29sYXRpbmcKICAgICAgICAgICAgICAgICAgICBncm91cHMgb2YgcmVzb3VyY2VzIHdpdGhpbiBhIHNpbmdsZSBjbHVzdGVyLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgbmFtZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTmFtZSBvZiBDbG91ZCBOYW1lc3BhY2UiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBOb2RlQ2x1c3RlciB7CiAgICAgICAgZGVzY3JpcHRpb24gIkEgTm9kZUNsdXN0ZXIgbWFuYWdlcyBhIGNvbGxlY3Rpb24gb2YgTm9kZXMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBuYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIE5vZGUgQ2x1c3RlciI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IENsb3VkU2l0ZSB7CiAgICAgICAgZGVzY3JpcHRpb24gIlJlcHJlc2VudHMgdGhlIGluZnJhc3RydWN0dXJlIHRoYXQKICAgICAgICAgICAgICAgICAgICBob3N0cyB0aGUgTkYgRGVwbG95bWVudC4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIG5hbWUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5hbWUgb2YgQ2xvdWQgU2l0ZSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdXNlcyBnZW86Z2VvLWxvY2F0aW9uOwogICAgICAgIH0KICAgIH0KCgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBDTE9VRElGSUVETkZfQ09NUFJJU0VTX05GREVQTE9ZTUVOVCB7IC8vIDEgdG8gMS4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IGNvbXByaXNlZC1uRkRlcGxveW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQ2xvdWRpZmllZCBORiBjb21wcmlzZXMgb2YgdGhlc2UgTkYgRGVwbG95bWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgQ2xvdWRpZmllZE5GOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgICAgIG1pbi1lbGVtZW50cyAxOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBjb21wcmlzZWQtYnktY2xvdWRpZmllZE5GIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5GIERlcGxveW1lbnQgcGFydCBvZiBDbG91ZGlmaWVkIE5GLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBORkRlcGxveW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTkZERVBMT1lNRU5UX0RFUExPWUVEX09OX0NMT1VETkFNRVNQQUNFIHsgLy8gMS4ubiB0byAxLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgZGVwbG95ZWQtb24tY2xvdWROYW1lc3BhY2UgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTkYgRGVwbG95bWVudCBkZXBsb3llZCBvbiBDbG91ZCBOYW1lc3BhY2UuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIE5GRGVwbG95bWVudDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtaW4tZWxlbWVudHMgMTsKICAgICAgICB9CgogICAgICAgIGxlYWYtbGlzdCBkZXBsb3llZC1uRkRlcGxveW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQ2xvdWQgTmFtZXNwYWNlIGRlcGxveXMgTkYgRGVwbG95bWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgQ2xvdWROYW1lc3BhY2U7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgQ0xPVUROQU1FU1BBQ0VfREVQTE9ZRURfT05fTk9ERUNMVVNURVIgeyAvLyAxLi5uIHRvIDEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgZGVwbG95ZWQtb24tbm9kZUNsdXN0ZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQ2xvdWQgTmFtZXNwYWNlIGRlcGxveWVkIG9uIE5vZGUgQ2x1c3Rlci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgQ2xvdWROYW1lc3BhY2U7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgZGVwbG95ZWQtY2xvdWROYW1lc3BhY2UgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTm9kZSBDbHVzdGVyIGRlcGxveXMgQ2xvdWQgTmFtZXNwYWNlLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOb2RlQ2x1c3RlcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtaW4tZWxlbWVudHMgMTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBOT0RFQ0xVU1RFUl9MT0NBVEVEX0FUX0NMT1VEU0lURSB7IC8vIDEuLm4gdG8gMS4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IGxvY2F0ZWQtYXQtY2xvdWRTaXRlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5vZGUgQ2x1c3RlciBsb2NhdGVkIGF0IENsb3VkIFNpdGUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIE5vZGVDbHVzdGVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgICAgIG1pbi1lbGVtZW50cyAxOwogICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IGxvY2F0aW9uLW9mLW5vZGVDbHVzdGVyIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkIFNpdGUgaXMgbG9jYXRpb24gb2YgTm9kZSBDbHVzdGVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBDbG91ZFNpdGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgICAgfQogICAgfQp9        BUILT_IN_MODULE IN_USAGE
-o-ran-smo-teiv-equipment-to-ran        urn:o-ran:smo-teiv-equipment-to-ran     EQUIPMENT_TO_RAN        ["o-ran-smo-teiv-equipment", "o-ran-smo-teiv-ran"]      2024-05-02      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWVxdWlwbWVudC10by1yYW4gewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOm8tcmFuOnNtby10ZWl2LWVxdWlwbWVudC10by1yYW4iOwogICAgcHJlZml4IG9yLXRlaXYtZXF1aXB0b3JhbjsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtZXF1aXBtZW50IHtwcmVmaXggb3ItdGVpdi1lcXVpcDsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1yYW4ge3ByZWZpeCBvci10ZWl2LXJhbjsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiBFcXVpcG1lbnQgdG8gTG9naWNhbCB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjMgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIEVxdWlwbWVudCB0byBMb2dpY2FsIHRvcG9sb2d5CiAgICBlbnRpdGllcyBhbmQgcmVsYXRpb25zLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMDIiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIEVRVUlQTUVOVF9UT19SQU47CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBQSFlTSUNBTE5GX1NFUlZFU19HTkJEVUZVTkNUSU9OIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtZ25iZHVGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItRFUgRnVuY3Rpb24gc2VydmljZWQgYnkgdGhpcyBQaHlzaWNhbCBORi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1lcXVpcDpQaHlzaWNhbE5GOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHNlcnZpbmctcGh5c2ljYWxORiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJQaHlzaWNhbCBORiBzZXJ2ZXMgdGhpcyBnTm9kZUItRFUgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBQSFlTSUNBTE5GX1NFUlZFU19HTkJDVUNQRlVOQ1RJT04geyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBzZXJ2aWNlZC1nbmJjdWNwRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVQ1AgRnVuY3Rpb24gc2VydmljZWQgYnkgdGhpcyBQaHlzaWNhbCBORi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1lcXVpcDpQaHlzaWNhbE5GOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHNlcnZpbmctcGh5c2ljYWxORiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJQaHlzaWNhbCBORiBzZXJ2ZXMgdGhpcyBnTm9kZUItQ1VDUCBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46R05CQ1VDUEZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgUEhZU0lDQUxORl9TRVJWRVNfR05CQ1VVUEZVTkNUSU9OIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtZ25iY3V1cEZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQi1DVVVQIEZ1bmN0aW9uIHNlcnZpY2VkIGJ5IHRoaXMgUGh5c2ljYWwgTkYuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtZXF1aXA6UGh5c2ljYWxORjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBzZXJ2aW5nLXBoeXNpY2FsTkYgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiUGh5c2ljYWwgTkYgc2VydmVzIHRoaXMgZ05vZGVCLUNVVVAgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkNVVVBGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIFBIWVNJQ0FMTkZfU0VSVkVTX0VOT0RFQkZVTkNUSU9OIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHNlcnZpY2VkIGJ5IHRoaXMgUGh5c2ljYWwgTkYuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtZXF1aXA6UGh5c2ljYWxORjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBzZXJ2aW5nLXBoeXNpY2FsTkYgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiUGh5c2ljYWwgTkYgc2VydmVzIHRoaXMgZU5vZGVCIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpFTm9kZUJGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIEFOVEVOTkFNT0RVTEVfU0VSVkVTX0FOVEVOTkFDQVBBQklMSVRZIHsgLy8gMC4ubiB0byAwLi5tCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtYW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHNlcnZpY2VkIGJ5IHRoaXMgQW50ZW5uYSBNb2R1bGUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtZXF1aXA6QW50ZW5uYU1vZHVsZTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IHNlcnZpbmctYW50ZW5uYU1vZHVsZSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIE1vZHVsZSBzZXJ2ZXMgdGhpcyBBbnRlbm5hIENhcGFiaWxpdHkuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgU0VDVE9SX0dST1VQU19BTlRFTk5BTU9EVUxFIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgZ3JvdXBlZC1hbnRlbm5hTW9kdWxlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIlNlY3RvciBncm91cHMgQW50ZW5uYSBNb2R1bGUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtcmFuOlNlY3RvcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBncm91cGVkLWJ5LXNlY3RvciB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIE1vZHVsZSBncm91cGVkIGJ5IFNlY3Rvci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1lcXVpcDpBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQp9        BUILT_IN_MODULE IN_USAGE
+COPY ties_model.module_reference("name","revision", "namespace", "domain", "includedModules", "content") FROM stdin;
+o-ran-smo-teiv-ran-logical-to-cloud    2023-10-24      urn:rdns:o-ran:-ran-logical-to-cloud    RAN_LOGICAL_TO_CLOUD    ["o-ran-smo-teiv-ran-logical", "o-ran-smo-teiv-ran-cloud"]      bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbC10by1jbG91ZCB7DQogICAgeWFuZy12ZXJzaW9uIDEuMTsNCiAgICBuYW1lc3BhY2UgInVybjpyZG5zOmNvbTplcmljc3Nvbjp0b3BpbnZtb2RlbDplcmljc3Nvbi10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbC10by1jbG91ZCI7DQogICAgcHJlZml4IHJhbmxvZ3RvY2xvdWRlcml0b3BpbnY7DQoNCiAgICBpbXBvcnQgZXJpY3Nzb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggeWV4dGU7IH0NCg0KICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCB0eXBlc2VyaXRvcGludjsgfQ0KDQogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggeWV4dGVyaXRvcGludjsgfQ0KDQogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbCB7cHJlZml4IHJhbmxvZ2VyaXRvcGludjsgfQ0KDQogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tY2xvdWQge3ByZWZpeCByYW5jbG91ZGVyaXRvcGludjsgfQ0KDQogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7DQogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7DQogICAgZGVzY3JpcHRpb24NCiAgICAiUkFOIExvZ2ljYWwgdG8gUkFOIENsb3VkIHRvcG9sb2d5IG1vZGVsLg0KDQogICAgQ29weXJpZ2h0IChjKSAyMDIzIEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KDQogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIExvZ2ljYWwgdG8gUkFOIENsb3VkIHRvcG9sb2d5IHJlbGF0aW9ucyI7DQoNCiAgICByZXZpc2lvbiAiMjAyMy0xMC0yNCIgew0KICAgICAgICBkZXNjcmlwdGlvbg0KICAgICAgICAiSW5pdGlhbCByZXZpc2lvbi4iOw0KICAgICAgICB5ZXh0ZTp2ZXJzaW9uICIwIjsNCiAgICAgICAgeWV4dGU6cmVsZWFzZSAiMSI7DQogICAgICAgIHlleHRlOmNvcnJlY3Rpb24gIjEiOw0KICAgIH0NCg0KICAgIHlleHRlcml0b3BpbnY6ZG9tYWluIFJBTl9MT0dJQ0FMX1RPX0NMT1VEOw0KDQogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CRFVGVU5DVElPTl9SRUFMSVNFRF9CWV9DTE9VRE5BVElWRUFQUExJQ0FUSU9OIHsgLy8gMC4ubiB0byAwLi5tDQoNCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7DQogICAgICAgIGtleSBpZDsNCg0KICAgICAgICBsZWFmLWxpc3QgcmVhbGlzZWQtYnktY2xvdWROYXRpdmVBcHBsaWNhdGlvbiB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHJlYWxpc2VkIGJ5DQogICAgICAgICAgICAgICAgICAgICAgICAgQ2xvdWQgTmF0aXZlIEFwcGxpY2F0aW9uLiI7DQogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmFTaWRlIHJhbmxvZ2VyaXRvcGludjpHTkJEVUZ1bmN0aW9uOw0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICB9DQoNCiAgICAgICAgbGVhZi1saXN0IHJlYWxpc2VkLWduYmR1RnVuY3Rpb24gew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkIE5hdGl2ZSBBcHBsaWNhdGlvbiByZWFsaXNlcyBnTm9kZUJEVSBGdW5jdGlvbi4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjpiU2lkZSByYW5jbG91ZGVyaXRvcGludjpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOw0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CQ1VDUEZVTkNUSU9OX1JFQUxJU0VEX0JZX0NMT1VETkFUSVZFQVBQTElDQVRJT04geyAvLyAwLi5uIHRvIDAuLm0NCg0KICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsNCiAgICAgICAga2V5IGlkOw0KDQogICAgICAgIGxlYWYtbGlzdCByZWFsaXNlZC1ieS1jbG91ZE5hdGl2ZUFwcGxpY2F0aW9uIHsNCiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItQ1UtQ1AgRnVuY3Rpb24gcmVhbGlzZWQgYnkNCiAgICAgICAgICAgICAgICAgICAgICAgIENsb3VkIE5hdGl2ZSBBcHBsaWNhdGlvbi4uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YVNpZGUgcmFubG9nZXJpdG9waW52OkdOQkNVQ1BGdW5jdGlvbjsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGxlYWYtbGlzdCByZWFsaXNlZC1nbmJjdWNwRnVuY3Rpb24gew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkIE5hdGl2ZSBBcHBsaWNhdGlvbiByZWFsaXNlcw0KICAgICAgICAgICAgICAgICAgICAgICAgZ05vZGVCQ1VDUCBGdW5jdGlvbi4uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgcmFuY2xvdWRlcml0b3BpbnY6Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIHlleHRlcml0b3BpbnY6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIEdOQkNVVVBGVU5DVElPTl9SRUFMSVNFRF9CWV9DTE9VRE5BVElWRUFQUExJQ0FUSU9OIHsgLy8gMC4ubiB0byAwLi5tDQoNCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7DQogICAgICAgIGtleSBpZDsNCg0KICAgICAgICBsZWFmLWxpc3QgcmVhbGlzZWQtYnktY2xvdWROYXRpdmVBcHBsaWNhdGlvbiB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLVVQIEZ1bmN0aW9uIHJlYWxpc2VkIGJ5DQogICAgICAgICAgICAgICAgICAgICAgICBDbG91ZCBOYXRpdmUgQXBwbGljYXRpb24uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YVNpZGUgcmFubG9nZXJpdG9waW52OkdOQkNVVVBGdW5jdGlvbjsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGxlYWYtbGlzdCByZWFsaXNlZC1nbmJjdXVwRnVuY3Rpb24gew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkIE5hdGl2ZSBBcHBsaWNhdGlvbiByZWFsaXNlcw0KICAgICAgICAgICAgICAgICAgICAgICAgZ05vZGVCQ1VVUCBGdW5jdGlvbi4uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgcmFuY2xvdWRlcml0b3BpbnY6Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KICAgIH0NCn0=
+o-ran-smo-teiv-ran-equipment   2023-06-26      urn:rdns:o-ran:o-ran-smo-teiv-ran-equipment     RAN_EQUIPMENT   []      bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tZXF1aXBtZW50IHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpyZG5zOmNvbTplcmljc3Nvbjp0b3BpbnZtb2RlbDplcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktcmFuLWVxdWlwbWVudCI7CiAgICBwcmVmaXggcmFuZXF1aXBlcml0b3BpbnY7CgogICAgaW1wb3J0IGVyaWNzc29uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlOyB9CgogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy10eXBlcyB7cHJlZml4IHR5cGVzZXJpdG9waW52OyB9CgogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggeWV4dGVyaXRvcGludjsgfQoKCiAgICBpbXBvcnQgaWV0Zi1nZW8tbG9jYXRpb24gewogICAgICAgIHByZWZpeCBnZW87CiAgICAgICAgcmVmZXJlbmNlICJSRkMgOTE3OTogQSBZQU5HIEdyb3VwaW5nIGZvciBHZW9ncmFwaGljIExvY2F0aW9ucyI7CiAgICB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiUkFOIEVxdWlwbWVudCB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjMgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUKICAgIFJBTiBMb2dpY2FsIGRvbWFpbiwgd2hpY2ggcmVwcmVzZW50cyB0aGUgZnVuY3Rpb25hbCBjYXBhYmlsaXR5CiAgICBvZiB0aGUgZGVwbG95ZWQgUkFOIHRoYXQgYXJlIHJlbGV2YW50IHRvIHJBcHBzIHVzZSBjYXNlcy4iOwoKICAgIHJldmlzaW9uICIyMDIzLTEyLTEyIiB7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIHlleHRlOnZlcnNpb24gIjAiOwogICAgICAgIHlleHRlOnJlbGVhc2UgIjIiOwogICAgICAgIHlleHRlOmNvcnJlY3Rpb24gIjAiOwogICAgfQoKICAgIHlleHRlcml0b3BpbnY6ZG9tYWluIFJBTl9FUVVJUE1FTlQ7CgogICAgbGlzdCBBbnRlbm5hTW9kdWxlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gQW50ZW5uYSBNb2R1bGUgcmVwcmVzZW50cyB0aGUKICAgICAgICAgICAgICAgICAgICBwaHlzaWNhbCBhc3BlY3Qgb2YgYW4gYW50ZW5uYS4iOwoKICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBmZG4gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoaXMgRnVsbCBEaXN0aW5ndWlzaGVkIE5hbWUgKEZETikgaWRlbnRpZmllcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gaW5zdGFuY2Ugb2YgdGhlIEFudGVubmFTdWJVbml0IE1PLiBJdCBjb250YWlucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50ZW5uYVN1YlVuaXQuIjsKICAgICAgICAgICAgICAgIHR5cGUgdHlwZXNlcml0b3BpbnY6XzNHUFBfRkROX1R5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgYW50ZW5uYU1vZGVsTnVtYmVyIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJWZW5kb3Itc3BlY2lmaWMgYW50ZW5uYSBtb2RlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllci4gVGhpcyBhdHRyaWJ1dGUgaXMgcGFydCBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgQUlTRyB2MyBBREIgU3RhbmRhcmQgYW5kIGhhcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm8gb3BlcmF0aW9uYWwgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBtZWNoYW5pY2FsQW50ZW5uYUJlYXJpbmcgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgYmVhcmluZyBvbiBhbnRlbm5hIHN1YnVuaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlIGFudGVubmEgdW5pdCBpcyBpbnN0YWxsZWQuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG1lY2hhbmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGZpeGVkIGFudGVubmEgdGlsdCBvZiB0aGUgaW5zdGFsbGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lZCBhcyB0aGUgaW5jbGluYXRpb24gb2YgdGhlIGFudGVubmEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgcmVzcGVjdCB0byB0aGUgdmVydGljYWwgcGxhbmUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdCBpcyBhIHNpZ25lZCB2YWx1ZS4gUG9zaXRpdmUgaW5kaWNhdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dudGlsdCwgYW5kIG5lZ2F0aXZlIGluZGljYXRlcyB1cHRpbHQuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIHBvc2l0aW9uV2l0aGluU2VjdG9yIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIHVuaXQgcG9zaXRpb24gd2l0aGluIHNlY3Rvci4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgYXR0cmlidXRlIGlzIHBhcnQgb2YgQUlTRyB2MyBBREIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkIGFuZCBoYXMgbm8gb3BlcmF0aW9uYWwgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiB0b3RhbFRpbHQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRvdGFsIGFudGVubmEgZWxldmF0aW9uIGluY2x1ZGluZyB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbGxlZCB0aWx0IGFuZCB0aGUgdGlsdCBhcHBsaWVkIGJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgUmVtb3RlIEVsZWN0cmljYWwgVGlsdCAoUkVUKS4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZWxlY3RyaWNhbEFudGVubmFUaWx0IHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFbGVjdHJpY2FsbHktY29udHJvbGxlZCB0aWx0IG9mIG1haW4gYmVhbSBtYXhpbXVtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIHJlc3BlY3QgdG8gZGlyZWN0aW9uIG9ydGhvZ29uYWwgdG8gYW50ZW5uYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCBheGlzIChzZWUgM0dQUCBUUyAyNS40NjYpLiBWYWx1ZSBpcyBzaWduZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aWx0IGRvd24gaXMgcG9zaXRpdmUsIHRpbHQgdXAgaXMgbmVnYXRpdmUuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgQW50ZW5uYUJlYW1XaWR0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGFuZ3VsYXIgc3BhbiBvZiB0aGUgbWFpbiBsb2JlIG9mIHRoZSBhbnRlbm5hIHJhZGlhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiBpbiB0aGUgaG9yaXpvbnRhbCBwbGFuZS4gTWVhc3VyZWQgaW4gZGVncmVlcy4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZHVwbGV4VHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdG9yIG9mIEVVdHJhbkNlbGwgdHlwZSwgRkREIG9yIFRERCI7CiAgICAgICAgICAgICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICAgICAgICAgICAgICBlbnVtIHR5cGUxIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgMDsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gInR5cGUxIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpTT1VSQ0VfSURTOwogICAgICAgIH0KICAgIH0KCiAgICB5ZXh0ZXJpdG9waW52OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBBTlRFTk5BTU9EVUxFX1VTRVNfQU5URU5OQU1PRFVMRSB7IC8vIFNhbWUgZW50aXR5ICgwLi4xIHRvIDAuLjEpCgogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHVzZWQtYnktYW50ZW5uYU1vZHVsZSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIE1vZHVsZSByZWFsaXNlZCBieSBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmFTaWRlIHJhbmVxdWlwZXJpdG9waW52OkFudGVubmFNb2R1bGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgIH0KCiAgICAgICAgbGVhZi1saXN0IHVzZWQtYW50ZW5uYU1vZHVsZSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIE1vZHVsZSByZWFsaXNlcyBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmJTaWRlIHJhbmVxdWlwZXJpdG9waW52OkFudGVubmFNb2R1bGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgIH0KICAgIH0KfQ==
+o-ran-smo-teiv-ran-oam-to-cloud        2023-10-24      urn:rdns:o-ran:o-ran-smo-teiv-ran-oam-to-cloud  RAN_OAM_TO_CLOUD        ["o-ran-smo-teiv-ran-oam", "o-ran-smo-teiv-ran-cloud"]  bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tb2FtLXRvLWNsb3VkIHsNCiAgICB5YW5nLXZlcnNpb24gMS4xOw0KICAgIG5hbWVzcGFjZSAidXJuOnJkbnM6Y29tOmVyaWNzc29uOnRvcGludm1vZGVsOmVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tb2FtLXRvLWNsb3VkIjsNCiAgICBwcmVmaXggcmFub2FtdG9jbG91ZGVyaXRvcGludjsNCg0KICAgIGltcG9ydCBlcmljc3Nvbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCB5ZXh0ZTsgfQ0KDQogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy10eXBlcyB7cHJlZml4IHR5cGVzZXJpdG9waW52OyB9DQoNCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCB5ZXh0ZXJpdG9waW52OyB9DQoNCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LXJhbi1vYW0ge3ByZWZpeCByYW5vYW1lcml0b3BpbnY7IH0NCg0KICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktcmFuLWNsb3VkIHtwcmVmaXggcmFuY2xvdWRlcml0b3BpbnY7IH0NCg0KICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOw0KICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOw0KICAgIGRlc2NyaXB0aW9uIA0KICAgICJSQU4gTyZNIHRvIENsb3VkIHRvcG9sb2d5IG1vZGVsLg0KDQogICAgQ29weXJpZ2h0IChjKSAyMDIzIEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KICAgIA0KICAgIFRoaXMgbW9kZWwgY29udGFpbnMgdGhlIFJBTiBPJk0gdG8gQ2xvdWQgdG9wb2xvZ3kgcmVsYXRpb25zIjsNCg0KICAgIHJldmlzaW9uICIyMDIzLTEwLTI0IiB7DQogICAgICAgIGRlc2NyaXB0aW9uDQogICAgICAgICJJbml0aWFsIHJldmlzaW9uLiI7DQogICAgICAgIHlleHRlOnZlcnNpb24gIjAiOw0KICAgICAgICB5ZXh0ZTpyZWxlYXNlICIxIjsNCiAgICAgICAgeWV4dGU6Y29ycmVjdGlvbiAiMSI7DQogICAgfQ0KDQogICAgeWV4dGVyaXRvcGludjpkb21haW4gUkFOX09BTV9UT19DTE9VRDsNCg0KICAgIHlleHRlcml0b3BpbnY6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX0RFUExPWUVEX0FTX0NMT1VETkFUSVZFU1lTVEVNIHsgIC8vIDAuLjEgdG8gMQ0KDQogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZiBkZXBsb3llZC1hcy1jbG91ZE5hdGl2ZVN5c3RlbSB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IGRlcGxveWVkIGFzIENsb3VkIE5hdGl2ZSBTeXN0ZW0uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YVNpZGUgcmFub2FtZXJpdG9waW52Ok1hbmFnZWRFbGVtZW50Ow0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICB9DQoNCiAgICAgICAgbGVhZiBkZXBsb3llZC1tYW5hZ2VkRWxlbWVudCB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQ2xvdWQgTmF0aXZlIFN5c3RlbSBkZXBsb3lzIE1hbmFnZWQgRWxlbWVudC4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjpiU2lkZSByYW5jbG91ZGVyaXRvcGludjpDbG91ZE5hdGl2ZVN5c3RlbTsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgICAgIG1hbmRhdG9yeSB0cnVlOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfUkVBTElTRURfQllfQ0xPVUROQVRJVkVBUFBMSUNBVElPTiB7IC8vIDEgdG8gMS4ubg0KDQogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IHJlYWxpc2VkLWJ5LWNsb3VkTmF0aXZlQXBwbGljYXRpb24gew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIk1hbmFnZWQgRWxlbWVudCByZWFsaXNlZCBieSBDbG91ZCANCiAgICAgICAgICAgICAgICAgICAgICAgIE5hdGl2ZSBBcHBsaWNhdGlvbi4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSByYW5vYW1lcml0b3BpbnY6TWFuYWdlZEVsZW1lbnQ7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgICAgICBtaW4tZWxlbWVudHMgMTsNCiAgICAgICAgfQ0KDQogICAgICAgIGxlYWYgcmVhbGlzZWQtbWFuYWdlZEVsZW1lbnQgew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIkNsb3VkIE5hdGl2ZSBBcHBsaWNhdGlvbiByZWFsaXNlcyANCiAgICAgICAgICAgICAgICAgICAgICAgIE1hbmFnZWQgRWxlbWVudC4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjpiU2lkZSByYW5jbG91ZGVyaXRvcGludjpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOw0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7DQogICAgICAgIH0JDQogICAgfQ0KfQ==
+o-ran-smo-teiv-ran-oam-to-logical      2023-10-24      urn:rdns:o-ran:o-ran-smo-teiv-ran-oam-to-logical        RAN_OAM_TO_LOGICAL      ["o-ran-smo-teiv-ran-oam", "o-ran-smo-teiv-ran-logical"]        bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tb2FtLXRvLWxvZ2ljYWwgew0KICAgIHlhbmctdmVyc2lvbiAxLjE7DQogICAgbmFtZXNwYWNlICJ1cm46cmRuczpjb206ZXJpY3Nzb246dG9waW52bW9kZWw6ZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LXJhbi1vYW0tdG8tbG9naWNhbCI7DQogICAgcHJlZml4IHJhbm9hbXRvbG9nZXJpdG9waW52Ow0KDQogICAgaW1wb3J0IGVyaWNzc29uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlOyB9DQoNCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggdHlwZXNlcml0b3BpbnY7IH0NCg0KICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlcml0b3BpbnY7IH0NCg0KICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktcmFuLW9hbSB7cHJlZml4IHJhbm9hbWVyaXRvcGludjsgfQ0KDQogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbCB7cHJlZml4IHJhbmxvZ2VyaXRvcGludjsgfQ0KDQoNCiAgICBvcmdhbml6YXRpb24gIkVyaWNzc29uIEFCIjsNCiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsNCiAgICBkZXNjcmlwdGlvbg0KICAgICJSQU4gTyZNIHRvIExvZ2ljYWwgdG9wb2xvZ3kgbW9kZWwuDQoNCiAgICBDb3B5cmlnaHQgKGMpIDIwMjMgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQogICAgDQogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIE8mTSB0byBMb2dpY2FsIHRvcG9sb2d5IHJlbGF0aW9ucyI7DQoNCiAgICByZXZpc2lvbiAiMjAyMy0xMC0yNCIgew0KICAgICAgICBkZXNjcmlwdGlvbg0KICAgICAgICAiSW5pdGlhbCByZXZpc2lvbi4iOw0KICAgICAgICB5ZXh0ZTp2ZXJzaW9uICIwIjsNCiAgICAgICAgeWV4dGU6cmVsZWFzZSAiMSI7DQogICAgICAgIHlleHRlOmNvcnJlY3Rpb24gIjEiOw0KICAgIH0NCg0KICAgIHlleHRlcml0b3BpbnY6ZG9tYWluIFJBTl9PQU1fVE9fTE9HSUNBTDsNCg0KICAgIHlleHRlcml0b3BpbnY6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX01BTkFHRVNfRU5PREVCRlVOQ1RJT04geyAgIC8vIDEgdG8gMC4ubg0KDQogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZW5vZGViRnVuY3Rpb24gew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gIk1hbmFnZWQgRWxlbWVudCBtYW5hZ2VzIGVOb2RlQiBGdW5jdGlvbi4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSByYW5vYW1lcml0b3BpbnY6TWFuYWdlZEVsZW1lbnQ7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgIH0NCg0KICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgew0KICAgICAgICAgICAgZGVzY3JpcHRpb24gImVOb2RlQiBGdW5jdGlvbiBtYW5hZ2VkIGJ5IE1hbmFnZWQgRWxlbWVudC4iOw0KICAgICAgICAgICAgeWV4dGVyaXRvcGludjpiU2lkZSByYW5sb2dlcml0b3BpbnY6RU5vZGVCRnVuY3Rpb247DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIHlleHRlcml0b3BpbnY6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX01BTkFHRVNfR05CRFVGVU5DVElPTiB7ICAgIC8vIDEgdG8gMC4ubg0KDQogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZ25iZHVGdW5jdGlvbiB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IG1hbmFnZXMgZ05vZGVCLURVIEZ1bmN0aW9uLiI7DQogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmFTaWRlIHJhbm9hbWVyaXRvcGludjpNYW5hZ2VkRWxlbWVudDsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGxlYWYgbWFuYWdlZC1ieS1tYW5hZ2VkRWxlbWVudCB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7DQogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmJTaWRlIHJhbmxvZ2VyaXRvcGludjpHTkJEVUZ1bmN0aW9uOw0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7DQogICAgICAgIH0NCiAgICB9DQogICAgDQogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVUNQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4NCg0KICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsNCiAgICAgICAga2V5IGlkOw0KDQogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1Y3BGdW5jdGlvbiB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IG1hbmFnZXMgZ05vZGVCLUNVLUNQIEZ1bmN0aW9uLiI7DQogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmFTaWRlIHJhbm9hbWVyaXRvcGludjpNYW5hZ2VkRWxlbWVudDsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGxlYWYgbWFuYWdlZC1ieS1tYW5hZ2VkRWxlbWVudCB7DQogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLUNQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7DQogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmJTaWRlIHJhbmxvZ2VyaXRvcGludjpHTkJDVUNQRnVuY3Rpb247DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsNCiAgICAgICAgfQkNCiAgICB9DQoNCiAgICB5ZXh0ZXJpdG9waW52OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBNQU5BR0VERUxFTUVOVF9NQU5BR0VTX0dOQkNVVVBGVU5DVElPTiB7ICAgIC8vIDEgdG8gMC4ubg0KDQogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZ25iY3V1cEZ1bmN0aW9uIHsNCiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtVVAgRnVuY3Rpb24uIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YVNpZGUgcmFub2FtZXJpdG9waW52Ok1hbmFnZWRFbGVtZW50Ow0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgICB9DQoNCiAgICAgICAgbGVhZiBtYW5hZ2VkLWJ5LW1hbmFnZWRFbGVtZW50IHsNCiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItQ1UtVVAgRnVuY3Rpb24gbWFuYWdlZCBieSBNYW5hZ2VkIEVsZW1lbnQuIjsNCiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgcmFubG9nZXJpdG9waW52OkdOQkNVVVBGdW5jdGlvbjsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICAgICAgIG1hbmRhdG9yeSB0cnVlOw0KICAgICAgICB9DQogICAgfQ0KfQ==
+o-ran-smo-teiv-ran-cloud       2023-06-26      urn:rdns:o-ran:o-ran-smo-teiv-ran-cloud RAN_CLOUD       []      bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tY2xvdWQgewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOnJkbnM6Y29tOmVyaWNzc29uOnRvcGludm1vZGVsOmVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tY2xvdWQiOwogICAgcHJlZml4IHJhbmNsb3VkZXJpdG9waW52OwoKICAgIGltcG9ydCBlcmljc3Nvbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCB5ZXh0ZTsgfQoKICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCB0eXBlc2VyaXRvcGludjsgfQoKICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlcml0b3BpbnY7IH0KCiAgICBpbXBvcnQgaWV0Zi1nZW8tbG9jYXRpb24gewogICAgICAgIHByZWZpeCBnZW87CiAgICAgICAgcmVmZXJlbmNlICJSRkMgOTE3OTogQSBZQU5HIEdyb3VwaW5nIGZvciBHZW9ncmFwaGljIExvY2F0aW9ucyI7CiAgICB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiUkFOIENsb3VkIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIENMT1VEIGRvbWFpbiwgd2hpY2ggY29tcHJpc2VzIGNsb3VkIGluZnJhc3RydWNlIGFuZAogICAgZGVwbG95bWVudCBhc3BlY3RzIHRoYXQgY2FuIGJlIHVzZWQgaW4gdGhlIHRvcG9sb2d5IG1vZGVsLiI7CgogICAgcmV2aXNpb24gIjIwMjMtMDYtMjYiIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgeWV4dGU6dmVyc2lvbiAiMCI7CiAgICAgICAgeWV4dGU6cmVsZWFzZSAiMSI7CiAgICAgICAgeWV4dGU6Y29ycmVjdGlvbiAiMCI7CiAgICB9CgogICAgeWV4dGVyaXRvcGludjpkb21haW4gUkFOX0NMT1VEOwoKICAgIGxpc3QgQ2xvdWRTaXRlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyB0aGUgaW5mcmFzdHJ1Y3R1cmUgdGhhdAogICAgICAgICAgICAgICAgICAgIGhvc3RzIHRoZSBDbG91ZCBOYXRpdmUgQXBwbGljYXRpb25zLiI7CgogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIG5hbWUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5hbWUgb2YgQ2xvdWQgU2l0ZSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdXNlcyBnZW86Z2VvLWxvY2F0aW9uOwogICAgICAgIH0KICAgIH0KfQ==
+o-ran-smo-teiv-ran-logical-to-equipment        2023-10-24      urn:rdns:o-ran:-ran-logical-to-equipment        RAN_LOGICAL_TO_EQUIPMENT        ["o-ran-smo-teiv-ran-logical", "o-ran-smo-teiv-ran-equipment"]  bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tZXF1aXBtZW50LXRvLWxvZ2ljYWwgewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOnJkbnM6Y29tOmVyaWNzc29uOnRvcGludm1vZGVsOmVyaWNzc29uLXRvcG9sb2d5YW5kaW52ZW50b3J5LXJhbi1lcXVpcG1lbnQtdG8tbG9naWNhbCI7CiAgICBwcmVmaXggcmFubG9ndG9lcXVpcGVyaXRvcGludjsKCiAgICBpbXBvcnQgZXJpY3Nzb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggeWV4dGU7IH0KCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggdHlwZXNlcml0b3BpbnY7IH0KCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCB5ZXh0ZXJpdG9waW52OyB9CgogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbCB7cHJlZml4IHJhbmxvZ2VyaXRvcGludjsgfQoKICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktcmFuLWVxdWlwbWVudCB7cHJlZml4IHJhbmVxdWlwZXJpdG9waW52OyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiUkFOIExvZ2ljYWwgdG8gRXF1aXBtZW50IHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSBSQU4gTG9naWNhbCB0byBFcXVpcG1lbnQgdG9wb2xvZ3kKICAgIGVudGl0aWVzIGFuZCByZWxhdGlvbnMuIjsKCiAgICByZXZpc2lvbiAiMjAyMy0xMi0xMiIgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICB5ZXh0ZTp2ZXJzaW9uICIwIjsKICAgICAgICB5ZXh0ZTpyZWxlYXNlICIyIjsKICAgICAgICB5ZXh0ZTpjb3JyZWN0aW9uICIwIjsKICAgIH0KCiAgICB5ZXh0ZXJpdG9waW52OmRvbWFpbiBFUVVJUE1FTlRfVE9fUkFOX0xPR0lDQUw7CgogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgQU5URU5OQU1PRFVMRV9TRVJWRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLm0KCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3Qgc2VydmljZWQtYW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHNlcnZpY2VkIGJ5IHRoaXMgQW50ZW5uYSBNb2R1bGUuIjsKICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSByYW5lcXVpcGVyaXRvcGludjpBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1hbnRlbm5hTW9kdWxlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIHNlcnZlcyB0aGlzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmJTaWRlIHJhbmxvZ2VyaXRvcGludjpBbnRlbm5hQ2FwYWJpbGl0eTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KfQo=
+o-ran-smo-teiv-ran-logical     2023-11-03      urn:rdns:o-ran:o-ran-smo-teiv-ran-logical       RAN_LOGICAL     []      bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tbG9naWNhbCB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46cmRuczpjb206ZXJpY3Nzb246dG9waW52bW9kZWw6ZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LXJhbi1sb2dpY2FsIjsKICAgIHByZWZpeCByYW5sb2dlcml0b3BpbnY7CgogICAgaW1wb3J0IGVyaWNzc29uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlOyB9CgogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy10eXBlcyB7cHJlZml4IHR5cGVzZXJpdG9waW52OyB9CgogICAgaW1wb3J0IGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1jb21tb24teWFuZy1leHRlbnNpb25zIHtwcmVmaXggeWV4dGVyaXRvcGludjsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiBMb2dpY2FsIHRvcG9sb2d5IG1vZGVsLgoKICAgIENvcHlyaWdodCAoYykgMjAyMyBFcmljc3NvbiBBQi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBUaGlzIG1vZGVsIGNvbnRhaW5zIHRoZSB0b3BvbG9neSBlbnRpdGllcyBhbmQgcmVsYXRpb25zIGluIHRoZQogICAgUkFOIExvZ2ljYWwgZG9tYWluLCB3aGljaCByZXByZXNlbnRzIHRoZSBmdW5jdGlvbmFsIGNhcGFiaWxpdHkKICAgIG9mIHRoZSBkZXBsb3llZCBSQU4gdGhhdCBhcmUgcmVsZXZhbnQgdG8gckFwcHMgdXNlIGNhc2VzLiI7CgogICAgcmV2aXNpb24gIjIwMjMtMTItMTIiIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgeWV4dGU6dmVyc2lvbiAiMCI7CiAgICAgICAgeWV4dGU6cmVsZWFzZSAiMyI7CiAgICAgICAgeWV4dGU6Y29ycmVjdGlvbiAiMCI7CiAgICB9CgogICAgeWV4dGVyaXRvcGludjpkb21haW4gUkFOX0xPR0lDQUw7CgogICAgZ3JvdXBpbmcgUExNTklkIHsKICAgICAgICBsZWFmIG1jYyB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTW9iaWxlIENvdW50cnkgQ29kZSAoTUNDKSBpZGVudGlmaWVzIHVuaXF1ZWx5CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWljaWxlIGNvdW50cnkgb2YgbW9iaWxlIHN1YnNjcmliZXIuCgogICAgICAgICAgICAgICAgICAgICAgICBNQ0MgY29uc2lzdHMgb2YgdGhyZWUgZGVjaW1hbCBkaWdpdHMuIFRoZSBmaXJzdCBkaWdpdAogICAgICAgICAgICAgICAgICAgICAgICBvZiBNQ0MgaWRlbnRpZmllcyBnZW9ncmFwaGljIHJlZ2lvbi4gKFZhbHVlcyAxIGFuZCA4CiAgICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBmaXJzdCBkaWdpdCBhcmUgbm90IGFsbG93ZWQuKQogICAgICAgICAgICAgICAgICAgICAgICBBcyBkZWZhdWx0IHZhbHVlLCB1c2UgMDAxLgogICAgICAgICAgICAgICAgICAgICAgICBBbGxvd2VkIHZhbHVlczogWzAyMzQ1Njc5XVswLTldWzAtOV0KCiAgICAgICAgICAgICAgICAgICAgICAgIFNwZWNpZmljYXRpb246IDNHUFAgVFMgMjguNTQxCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbGlkIHZhbHVlczogXlswMjM0NTY3OV1bMC05XVswLTldJCI7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBtbmMgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIE1vYmlsZSBOZXR3b3JrIENvZGUgKE1OQykgaWRlbnRpZmllcyBob21lIFBMTU4KICAgICAgICAgICAgICAgICAgICAgICAgb2YgbW9iaWxlIHN1YnNjcmlwdGlvbi4KCiAgICAgICAgICAgICAgICAgICAgICAgIE1OQyBjb25zaXN0cyBvZiB0d28gb3IgdGhyZWUgZGVjaW1hbCBkaWdpdHMuIEZvcgogICAgICAgICAgICAgICAgICAgICAgICBleGFtcGxlLCBNTkMgb2YgMDAxIGlzIG5vdCBzYW1lIGFzIE1OQyBvZiAwMS4KICAgICAgICAgICAgICAgICAgICAgICAgQXMgZGVmYXVsdCB2YWx1ZSwgdXNlIDAxLgogICAgICAgICAgICAgICAgICAgICAgICBBbGxvd2VkIHZhbHVlczogWzAtOV1bMC05XVswLTldfFswLTldWzAtOV0KCiAgICAgICAgICAgICAgICAgICAgICAgIFNwZWNpZmljYXRpb246IDNHUFAgVFMgMjguNTQxCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbGlkIHZhbHVlczogXigoWzAtOV1bMC05XVswLTldKXwoWzAtOV1bMC05XSkpJCI7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEVOb2RlQkZ1bmN0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gRXZvbHZlZCBOb2RlIEIgKGVOb2RlQikgaXMgdGhlIG9ubHkgbWFuZGF0b3J5CiAgICAgICAgICAgICAgICAgICAgbm9kZSBpbiB0aGUgcmFkaW8gYWNjZXNzIG5ldHdvcmsgKFJBTikgb2YgTG9uZy1UZXJtCiAgICAgICAgICAgICAgICAgICAgRXZvbHV0aW9uIChMVEUpLiBUaGUgZU5vZGVCIGlzIGEgY29tcGxleCBiYXNlCiAgICAgICAgICAgICAgICAgICAgc3RhdGlvbiB0aGF0IGhhbmRsZXMgcmFkaW8gY29tbXVuaWNhdGlvbnMKICAgICAgICAgICAgICAgICAgICBpbiB0aGUgY2VsbCBhbmQgY2FycmllcyBvdXQgcmFkaW8gcmVzb3VyY2UKICAgICAgICAgICAgICAgICAgICBtYW5hZ2VtZW50IGFuZCBoYW5kb3ZlciBkZWNpc2lvbnMuIFVubGlrZSAyLzNHCiAgICAgICAgICAgICAgICAgICAgd2lyZWxlc3MgUkFOLCB0aGVyZSBpcyBubyBjZW50cmFsaXplZCByYWRpbyBuZXR3b3JrCiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlciBpbiBMVEUuIEl0IGlzIHRoZSBoYXJkd2FyZSB0aGF0IGlzIGNvbm5lY3RlZAogICAgICAgICAgICAgICAgICAgIHRvIHRoZSBtb2JpbGUgcGhvbmUgbmV0d29yayB0aGF0IGNvbW11bmljYXRlcwogICAgICAgICAgICAgICAgICAgIGRpcmVjdGx5IHdpdGggbW9iaWxlIGhhbmRzZXRzIChVc2VyIEVxdWlwbWVudCksIGxpa2UgYSBiYXNlCiAgICAgICAgICAgICAgICAgICAgdHJhbnNjZWl2ZXIgc3RhdGlvbiAoQlRTKSBpbiBHU00gbmV0d29ya3MuIFRoaXMgc2ltcGxpZmllcwogICAgICAgICAgICAgICAgICAgIHRoZSBhcmNoaXRlY3R1cmUgYW5kIGFsbG93cyBsb3dlciByZXNwb25zZSB0aW1lcy4iOwoKICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKCiAgICAgICAgICAgIGxlYWYgZU5CSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgSUQgdGhhdCBmb3JtcyBwYXJ0IG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgQ2VsbCBHbG9iYWwgSWRlbnRpdHksIGFuZCBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxzbyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIG92ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBTMSBpbnRlcmZhY2UiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgICAgICBkZWZhdWx0IDExOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGR1cGxleFR5cGUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkluZGljYXRvciBvZiBFVXRyYW5DZWxsIHR5cGUsIEZERCBvciBUREQiOwogICAgICAgICAgICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgZW51bSB0ZGQgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAxOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVEREIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBlTm9kZUJQbG1uSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgRU5vZGVCIFB1YmxpYyBMYW5kIE1vYmlsZSBOZXR3b3JrCiAgICAgICAgICAgICAgICAoUExNTikgSUQgdGhhdCBmb3JtcyBwYXJ0IG9mIHRoZSBFTm9kZUIKICAgICAgICAgICAgICAgIEdsb2JhbCBJRCB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIG92ZXIKICAgICAgICAgICAgICAgIHRoZSBTMSBpbnRlcmZhY2UuIE5vdGU6IFRoZSB2YWx1ZSAoTUNDPTAwMSwgTU5DPTAxKQogICAgICAgICAgICAgICAgaW5kaWNhdGVzIHRoYXQgdGhlIFBMTU4gaXMgbm90IGluaXRpYXRlZC4KICAgICAgICAgICAgICAgIFRoZSB2YWx1ZSBjYW4gbm90IGJlIHVzZWQgYXMgYSB2YWxpZCBQTE1OIElkZW50aXR5LiI7CgogICAgICAgICAgICAgICAgbGVhZiBtY2MgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTUNDIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlZCBpbiB0aGUgcmFkaW8gbmV0d29yay4iOwogICAgICAgICAgICAgICAgICAgIHR5cGUgaW50MzIgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZSAwLi45OTk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGVhZiBtbmMgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTU5DIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlZCBpbiB0aGUgcmFkaW8gbmV0d29yay4iOwogICAgICAgICAgICAgICAgICAgIHR5cGUgaW50MzIgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZSAwLi45OTk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGVhZiBtbmNMZW5ndGggewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgbGVuZ3RoIG9mIHRoZSBNTkMgcGFydCBvZiBhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUExNTiBpZGVudGl0eSB1c2VkIGluIHRoZSByYWRpbyBuZXR3b3JrLiI7CiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnQzMiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlIDIuLjM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6U09VUkNFX0lEUzsKICAgICAgICB9CiAgICB9CiAgICBsaXN0IEFudGVubmFDYXBhYmlsaXR5IHsKICAgICAgICBkZXNjcmlwdGlvbiAiVGhpcyBNTyBzZXJ2ZXMgYXMgYSBtYXBwaW5nIGJldHdlZW4gdGhlIGNlbGwKICAgICAgICAgICAgICAgICAgICBhbmQgdGhlIFJCUyBlcXVpcG1lbnQgdXNlZCB0byBwcm92aWRlIGNvdmVyYWdlCiAgICAgICAgICAgICAgICAgICAgaW4gYSBjZXJ0YWluIGdlb2dyYXBoaWNhbCBhcmVhLiBUaGUgTU8gYWxzbwogICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzIHRoZSBtYXhpbXVtIG91dHB1dCBwb3dlciBvZiB0aGUgc2VjdG9yLiI7CgogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmLWxpc3QgZVV0cmFuRnFCYW5kcyB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGlzdCBvZiBMVEUgZnJlcXVlbmN5IGJhbmRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IGFzc29jaWF0ZWQgaGFyZHdhcmUgc3VwcG9ydHMiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYtbGlzdCBnZXJhbkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgR0VSQU4gZnJlcXVlbmN5IGJhbmRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCBhc3NvY2lhdGVkIGhhcmR3YXJlIHN1cHBvcnRzIjsKICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgblJGcUJhbmRzIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMaXN0IG9mIE5SIGZyZXF1ZW5jeSBiYW5kcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2NpYXRlZCBoYXJkd2FyZSBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQogICAgICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlNPVVJDRV9JRFM7CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTFRFU2VjdG9yQ2FycmllciB7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBMVEUgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZQogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgZm9yIGRlZmluaW5nIHRoZSBsb2dpY2FsIGNoYXJhY3RlcmlzdGljcwogICAgICAgICAgICAgICAgICAgIG9mIGEgY2FycmllciAoY2VsbCkgaW4gYSBzZWN0b3IuIEEgc2VjdG9yIGlzIGEgY292ZXJhZ2UKICAgICAgICAgICAgICAgICAgICBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbiBoYXZpbmcKICAgICAgICAgICAgICAgICAgICBpdHMgb3duIGFudGVubmFzLCByYWRpbyBwb3J0cywgYW5kIGNvbnRyb2wgY2hhbm5lbHMuCiAgICAgICAgICAgICAgICAgICAgVGhlIGNvbmNlcHQgb2Ygc2VjdG9ycyB3YXMgZGV2ZWxvcGVkIHRvIGltcHJvdmUgY28tY2hhbm5lbAogICAgICAgICAgICAgICAgICAgIGludGVyZmVyZW5jZSBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zCiAgICAgICAgICAgICAgICAgICAgdXNlIHRocmVlIHNlY3RvciBjZWxscy4iOwoKICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBzZWN0b3JDYXJyaWVyVHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzZWN0b3IgY2FycmllcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxsZWQgYnkgTU8gU2VjdG9yQ2FycmllciBpcyBhIGRpZ2l0YWwgc2VjdG9yLiI7CiAgICAgICAgICAgICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICAgICAgICAgICAgICBlbnVtIG5vcm1hbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTm90IGEgZGlnaXRhbCBzZWN0b3IiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbnVtIGxlZnRfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAxOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVmdCBkaWdpdGFsIHNlY3RvciBmb3IgMkRTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSByaWdodF9kaWdpdGFsX3NlY3RvciB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDI7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJSaWdodCBkaWdpdGFsIHNlY3RvciBmb3IgMkRTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBsZWZ0X2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDM7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMZWZ0IGRpZ2l0YWwgc2VjdG9yIGZvciAzRFMiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbnVtIHJpZ2h0X2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJSaWdodCBkaWdpdGFsIHNlY3RvciBmb3IgM0RTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBtaWRkbGVfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA1OwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWlkZGxlIGRpZ2l0YWwgc2VjdG9yIGZvciAzRFMiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlNvdXJjZUlkZW50aWZpZXJzR3JwOwoKICAgICAgICB9CiAgICB9CgogICAgbGlzdCBOUlNlY3RvckNhcnJpZXIgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTlIgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzCiAgICAgICAgICAgICAgICAgICAgdGhlIGF0dHJpYnV0ZXMgZm9yIGRlZmluaW5nIHRoZSBsb2dpY2FsCiAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVyaXN0aWNzIG9mIGEgY2FycmllciAoY2VsbCkgaW4gYQogICAgICAgICAgICAgICAgICAgIHNlY3Rvci4gQSBzZWN0b3IgaXMgYSBjb3ZlcmFnZSBhcmVhIGFzc29jaWF0ZWQKICAgICAgICAgICAgICAgICAgICB3aXRoIGEgYmFzZSBzdGF0aW9uIGhhdmluZyBpdHMgb3duIGFudGVubmFzLAogICAgICAgICAgICAgICAgICAgIHJhZGlvIHBvcnRzLCBhbmQgY29udHJvbCBjaGFubmVscy4gVGhlIGNvbmNlcHQKICAgICAgICAgICAgICAgICAgICBvZiBzZWN0b3JzIHdhcyBkZXZlbG9wZWQgdG8gaW1wcm92ZSBjby1jaGFubmVsCiAgICAgICAgICAgICAgICAgICAgaW50ZXJmZXJlbmNlIGluIGNlbGx1bGFyIHN5c3RlbXMsIGFuZCBtb3N0IHdpcmVsZXNzCiAgICAgICAgICAgICAgICAgICAgc3lzdGVtcyB1c2UgdGhyZWUgc2VjdG9yIGNlbGxzLiI7CgogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGFyZmNuREwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIEFic29sdXRlIFJhZGlvIEZyZXF1ZW5jeSBDaGFubmVsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1iZXIgKE5SLUFSRkNOKSBmb3IgZG93bmxpbmsiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgYXJmY25VTCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQWJzb2x1dGUgUmFkaW8gZnJlcXVlbmN5IENoYW5uZWwgTnVtYmVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTlItQVJGQ04pIGZvciB1cGxpbmsuIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGZyZXF1ZW5jeURMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJSRiBSZWZlcmVuY2UgRnJlcXVlbmN5IG9mIGRvd25saW5rIGNoYW5uZWwiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZnJlcXVlbmN5VUwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlJGIFJlZmVyZW5jZSBGcmVxdWVuY3kgb2YgdXBsaW5rIGNoYW5uZWwiOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpTb3VyY2VJZGVudGlmaWVyc0dycDsKICAgICAgICB9CiAgICB9CgogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTFRFU0VDVE9SQ0FSUklFUl9VU0VTX0FOVEVOTkFDQVBBQklMSVRZIHsgLy8gMC4uMSB0byAwLi4xCgogICAgICAgIHVzZXMgdHlwZXNlcml0b3BpbnY6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZiB1c2VkLWFudGVubmFDYXBhYmlsaXR5IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxURSBTZWN0b3IgQ2FycmllciB1c2VzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmFTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgdXNlZC1ieS1sdGVTZWN0b3JDYXJyaWVyIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgQ3BhYmlsaXR5IHVzZWQgYnkgTFRFIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgQW50ZW5uYUNhcGFiaWxpdHk7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBwcm92aWRlZC1sdGVTZWN0b3JDYXJyaWVyIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImVOb2RlQiBGdW5jdGlvbiBwcm92aWRlcyBMVEUgU2VjdG9yIENhcnJpZXIuIjsKICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSBFTm9kZUJGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBwcm92aWRlZC1ieS1lbm9kZWJGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMVEUgU2VjdG9yIENhcnJpZXIgcHJvdmlkZWQgYnkgZU5vZGVCIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgTFRFU2VjdG9yQ2FycmllcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgeWV4dGVyaXRvcGludjpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTlJTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmIHVzZWQtYW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgU2VjdG9yIENhcnJpZXIgdXNlcyBBbnRlbm5hIENhcGFiaWxpdHkuIjsKICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSBOUlNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYtbGlzdCB1c2VkLWJ5LW5yU2VjdG9yQ2FycmllciB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIENhcGFiaWxpdHkgdXNlZCBieSBOUiBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICB5ZXh0ZXJpdG9waW52OmJTaWRlIEFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIHlleHRlcml0b3BpbnY6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIEFOVEVOTkFDQVBBQklMSVRZX1JFQUxJU0VEX0JZX0FOVEVOTkFDQVBBQklMSVRZIHsgLy8gU2FtZSBlbnRpdHkgKDAuLm4gdG8gMC4ubSkKCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcmVhbGlzZWQtYnktYW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIENhcGFiaWxpdHkgcmVhbGlzZWQgYnkgQW50ZW5uYSBDYXBhYmlsaXR5LiI7CiAgICAgICAgICAgICAgICAgICAgeWV4dGVyaXRvcGludjphU2lkZSByYW5sb2dlcml0b3BpbnY6QW50ZW5uYUNhcGFiaWxpdHk7CiAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgcmVhbGlzZWQtYW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHJlYWxpc2VzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgIHlleHRlcml0b3BpbnY6YlNpZGUgcmFubG9nZXJpdG9waW52OkFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICB9CiAgICB9Cn0=
+o-ran-smo-teiv-ran-oam 2023-06-26      urn:rdns:o-ran:o-ran-smo-teiv-ran-oam   RAN_OAM []      bW9kdWxlIGVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tb2FtIHsNCiAgICB5YW5nLXZlcnNpb24gMS4xOw0KICAgIG5hbWVzcGFjZSAidXJuOnJkbnM6Y29tOmVyaWNzc29uOnRvcGludm1vZGVsOmVyaWNzc29uLXByZS1yMS10b3BvbG9neWFuZGludmVudG9yeS1yYW4tb2FtIjsNCiAgICBwcmVmaXggcmFub2FtZXJpdG9waW52Ow0KDQogICAgaW1wb3J0IGVyaWNzc29uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlOyB9DQoNCiAgICBpbXBvcnQgZXJpY3Nzb24tcHJlLXIxLXRvcG9sb2d5YW5kaW52ZW50b3J5LWNvbW1vbi15YW5nLXR5cGVzIHtwcmVmaXggdHlwZXNlcml0b3BpbnY7IH0NCg0KICAgIGltcG9ydCBlcmljc3Nvbi1wcmUtcjEtdG9wb2xvZ3lhbmRpbnZlbnRvcnktY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IHlleHRlcml0b3BpbnY7IH0NCg0KICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOw0KICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOw0KICAgIGRlc2NyaXB0aW9uIA0KICAgICJSQU4gTyZNIHRvcG9sb2d5IG1vZGVsLg0KDQogICAgQ29weXJpZ2h0IChjKSAyMDIzIEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KICAgIA0KICAgIFRoaXMgbW9kZWwgY29udGFpbnMgdGhlIHRvcG9sb2d5IGVudGl0aWVzIGFuZCByZWxhdGlvbnMgaW4gdGhlIA0KICAgIFJBTiBPJk0gZG9tYWluLCB3aGljaCBhcmUgaW50ZW5kZWQgdG8gcmVwcmVzZW50IG1hbmFnZW1lbnQgc3lzdGVtcyANCiAgICBhbmQgbWFuYWdlbWVudCBpbnRlcmZhY2VzLiI7DQoNCiAgICByZXZpc2lvbiAiMjAyMy0wNi0yNiIgew0KICAgICAgICBkZXNjcmlwdGlvbg0KICAgICAgICAiSW5pdGlhbCByZXZpc2lvbi4iOw0KICAgICAgICB5ZXh0ZTp2ZXJzaW9uICIwIjsNCiAgICAgICAgeWV4dGU6cmVsZWFzZSAiMSI7DQogICAgICAgIHlleHRlOmNvcnJlY3Rpb24gIjAiOw0KICAgIH0NCg0KICAgIHlleHRlcml0b3BpbnY6ZG9tYWluIFJBTl9PQU07DQogICAgICAgIA0KICAgIGxpc3QgTWFuYWdlZEVsZW1lbnQgew0KICAgICAgICBkZXNjcmlwdGlvbiANCiAgICAgICAgIkEgTWFuYWdlZCBFbGVtZW50IChNRSkgaXMgYSBub2RlIGludG8gYSB0ZWxlY29tbXVuaWNhdGlvbiBuZXR3b3JrIA0KICAgICAgICBwcm92aWRpbmcgc3VwcG9ydCBhbmQvb3Igc2VydmljZSB0byBzdWJzY3JpYmVycy4gQW4gTUUgY29tbXVuaWNhdGVzIA0KICAgICAgICB3aXRoIGEgbWFuYWdlciBhcHBsaWNhdGlvbiAoZGlyZWN0bHkgb3IgaW5kaXJlY3RseSkgb3ZlciBvbmUgb3IgbW9yZSANCiAgICAgICAgaW50ZXJmYWNlcyBmb3IgdGhlIHB1cnBvc2Ugb2YgYmVpbmcgbW9uaXRvcmVkIGFuZC9vciBjb250cm9sbGVkLiI7DQoNCiAgICAgICAgdXNlcyB0eXBlc2VyaXRvcGludjpUb3BfR3JwX1R5cGU7DQogICAgICAgIGtleSBpZDsNCg0KICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7DQogICAgICAgICAgICBsZWFmIGZkbiB7DQogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoaXMgRnVsbCBEaXN0aW5ndWlzaGVkIE5hbWUgKEZETikgaWRlbnRpZmllcyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBvZiB0aGUgTWFuYWdlZEVsZW1lbnQgTU8uIEl0IGNvbnRhaW5zDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGZ1bGwgcGF0aCBmcm9tIHRoZSBTdWJuZXR3b3JrIHRvIHRoZSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYW5hZ2VkRWxlbWVudC4iOw0KICAgICAgICAgICAgICAgIHR5cGUgdHlwZXNlcml0b3BpbnY6XzNHUFBfRkROX1R5cGU7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGNvbnRhaW5lciBjbUlkIHsNCiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzZXJpdG9waW52OkNNX0lEOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KfQ==
 \.
 
-COPY ties_model.entity_info("name", "moduleReferenceName") FROM stdin;
-ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt       o-ran-smo-teiv-oam
-ManagedElement o-ran-smo-teiv-oam
-NodeCluster    o-ran-smo-teiv-cloud
-CloudNativeSystem      o-ran-smo-teiv-cloud
-CloudNativeApplication o-ran-smo-teiv-cloud
-CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm       o-ran-smo-teiv-cloud
-CloudSite      o-ran-smo-teiv-cloud
-Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee       o-ran-smo-teiv-cloud
-CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn       o-ran-smo-teiv-cloud
-Namespace      o-ran-smo-teiv-cloud
-Sector o-ran-smo-teiv-ran
-GNBCUUPFunction        o-ran-smo-teiv-ran
-ENodeBFunction o-ran-smo-teiv-ran
-NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU       o-ran-smo-teiv-ran
-NRCellDU       o-ran-smo-teiv-ran
-LTESectorCarrier       o-ran-smo-teiv-ran
-GNBDUFunction  o-ran-smo-teiv-ran
-NRCellCU       o-ran-smo-teiv-ran
-GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn       o-ran-smo-teiv-ran
-AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee       o-ran-smo-teiv-equipment
-ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE       o-ran-smo-teiv-equipment
-EUtranCell     o-ran-smo-teiv-ran
-GNBCUCPFunction        o-ran-smo-teiv-ran
-NRSectorCarrier        o-ran-smo-teiv-ran
-AntennaCapability      o-ran-smo-teiv-ran
-TestEntityB    o-ran-smo-teiv-ran
-TestEntityA    o-ran-smo-teiv-ran
-Site   o-ran-smo-teiv-equipment
-AntennaModule  o-ran-smo-teiv-equipment
-PhysicalNetworkAppliance       o-ran-smo-teiv-equipment
+COPY ties_model.module_reference("name", "namespace", "domain", "includedModules", "revision", "content") FROM stdin;
+_3gpp-common-yang-extensions   urn:3gpp:sa5:_3gpp-common-yang-extensions       \N      []      2019-06-23      bW9kdWxlIF8zZ3BwLWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgewogIHlhbmctdmVyc2lvbiAxLjE7CiAgbmFtZXNwYWNlIHVybjozZ3BwOnNhNTpfM2dwcC1jb21tb24teWFuZy1leHRlbnNpb25zIDsKICBwcmVmaXggeWV4dDNncHAgOwoKICBvcmdhbml6YXRpb24gIjNHUFAgU0E1IjsKICBkZXNjcmlwdGlvbiAiVGhlIG1vZHVsZSBkZWZpbmVzIFlBTkcgZXh0ZW5zaW9ucyBuZWVkZWQKICAgIDNHUFAgWUFORyBtb2RlbGluZy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTkgM0dQUC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAgICBFeHRlbnNpb25zIE1VU1QgYmUgZGVmaW5lZCB3aXRoIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlIGluIHRoZQogICAgZGVzY3JpcHRpb24gc3RhdGVtZW50OgogICAgICAgIC0gV2hhdCBpcyB0aGlzIHN0YXRlbWVudC4KICAgICAgICAtIE5ld2xpbmUsCiAgICAgICAgLSBUaGlzIHN0YXRlbWVudCBjYW4gYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlIHh4eCBzdGF0ZW1lbnRzIHdpdGgKICAgICAgICBjYXJkaW5hbGl0eSB4Li55LgogICAgICAgIC0gVGhpcyBzdGF0ZW1lbnQgY2FuIGhhdmUgdGhlIGZvbGxvd2luZyBzdWJzdGF0ZW1lbnRzIHdpdGgKICAgICAgICBjYXJkaW5hbGl0eSB4Li55LgogICAgICAgIC0gTmV3bGluZQogICAgICAgIC0gSXMgY2hhbmdpbmcgdGhpcyBzdGF0ZW1lbnQgYW4gZWRpdG9yaWFsLCBCQyhiYWNrd2FyZHMgY29tcGF0aWJsZSkKICAgICAgICBvciBOQkMobm9uLUJDKSBjaGFuZ2U/CiAgICAgICAgLSBOZXdsaW5lLgogICAgICAgIC0gVGhlIGFyZ3VtZW50IGl0cyBtZWFuaW5nIGFuZCB0eXBlLiBQcmVmZXJhYmx5IHVzZSBZQU5HIHR5cGVzIGFuZAogICAgICAgICAgY29uc3RyYWludHMgdG8gZGVmaW5lIHRoZSBhcmd1bWVudCdzIHR5cGUuCgogICAgQW55IGV4dGVuc2lvbiBzdGF0ZW1lbnQgY2FuIGJlIGFkZGVkIHdpdGggYQogICAgZGV2aWF0aW9uL2RldmlhdGUgYWRkIHN0YXRlbWVudC4gSW4gdGhpcyBjYXNlIHRoZSByZXN0cmljdGlvbiBhYm91dAogICAgdGhlIHBhcmVudCBzdGF0ZW1lbnQgb2YgdGhlIGV4dGVuc2lvbiBTSEFMTCBiZSBldmFsdWF0ZWQgYmFzZWQgb24gdGhlCiAgICB0YXJnZXQgb2YgdGhlIGRldmlhdGlvbiBzdGF0ZW1lbnQuCgogICAgU3VwcG9ydCBmb3IgdGhpcyBtb2R1bGUgZG9lcyBub3QgbWVhbiB0aGF0IGEgWUFORyBzZXJ2ZXIgaW1wbGVtZW50cwogICAgc3VwcG9ydCBmb3IgZWFjaCBvZiB0aGVzZSBleHRlbnNpb25zLgogICAgSW1wbGVtZW50ZXJzIG9mIGVhY2ggc3BlY2lmaWMgbW9kdWxlIHVzaW5nIGFuIGV4dGVuc2lvbnMgTVVTVCBjaGVjawogICAgaWYgdGhlIHNlcnZlciBpbXBsZW1lbnRzIHN1cHBvcnQgZm9yIHRoZSB1c2VkIGV4dGVuc2lvbi4KICAgIE5vdGU6IG1vZHVsZXMgdXNlIG1hbnkgZXh0ZW5zaW9ucyB3aGljaCBpbmRpdmlkdWFsCiAgICBpbXBsZW1lbnRhdGlvbnMgTUFZIG9yIE1BWSBOT1Qgc3VwcG9ydC4KICAgIElmIHN1cHBvcnQgZm9yIGFuIGV4dGVuc2lvbiBpcyBtaXNzaW5nIHRoZSBleHRlbnNpb24gc3RhdGVtZW50IG5lZWRzCiAgICBpbmRpdmlkdWFsIGhhbmRsaW5nIG9yIGl0IFNIT1VMRCBiZSByZW1vdmVkIGZyb20gdGhlIG1vZHVsZSB1c2luZwogICAgdGhlIGV4dGVuc2lvbiBlLmcuIHdpdGggYSBkZXZpYXRpb24uCiAgICAgICAgICAiOwoKICByZXZpc2lvbiAiMjAxOS0wNi0yMyIgewogICAgZGVzY3JpcHRpb24gIkluaXRpYWwgdmVyc2lvbiI7CiAgfQoKICBleHRlbnNpb24gaW5WYXJpYW50IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgICJJbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgZm9yIHRoZSBkYXRhIG5vZGUgY2FuIG9ubHkgYmUgc2V0IHdoZW4gaXRzCiAgICAgIHBhcmVudCBkYXRhIG5vZGUgaXMgYmVpbmcgY3JlYXRlZC4gVG8gY2hhbmdlIHRoZSB2YWx1ZSBhZnRlciB0aGF0LCB0aGUKICAgICAgcGFyZW50IGRhdGEgbm9kZSBtdXN0IGJlIGRlbGV0ZWQgYW5kIHJlY3JlYXRlZCB3aXRoIHRoZSBkYXRhIG5vZGUKICAgICAgaGF2aW5nIHRoZSBuZXcgdmFsdWUuCgogICAgICBJdCBpcyB1bm5lY2Vzc2FyeSB0byB1c2UgYW5kIE1VU1QgTk9UIGJlIHVzZWQgZm9yIGtleSBsZWFmcy4KCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgbGVhZiwgbGVhZi1saXN0LCBsaXN0CiAgICAgIHN0YXRlbWVudHMgdGhhdCBpcyBjb25maWc9dHJ1ZS4KICAgICAgWmVybyBvciBvbmUgaW5WYXJpYW50IHN0YXRlbWVudCBpcyBhbGxvd2VkIHBlciBwYXJlbnQgc3RhdGVtZW50LgogICAgICBOTyBzdWJzdGF0ZW1lbnRzIGFyZSBhbGxvd2VkLgoKICAgICAgQWRkaW5nIHRoaXMgc3RhdGVtZW50IGlzIGFuIE5CQyBjaGFuZ2UsIHJlbW92aW5nIGl0IGlzIEJDLiI7CiAgfQoKICBleHRlbnNpb24gaW5pdGlhbC12YWx1ZSB7CiAgICBkZXNjcmlwdGlvbiAiU3BlY2lmaWVzIGEgdmFsdWUgdGhhdCB0aGUgc3lzdGVtIHdpbGwgc2V0IGZvciBhIGxlYWYKICAgICAgbGVhZi1saXN0IGlmIGEgdmFsdWUgaXMgbm90IHNwZWNpZmllZCBmb3IgaXQgd2hlbiBpdHMgcGFyZW50IGxpc3QKICAgICAgb3IgY29udGFpbmVyIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSBoYXMgbm8gZWZmZWN0IGluIGFueSBvdGhlcgogICAgICBtb2RpZmljYXRpb24gZS5nLiBjaGFuZ2luZyBvciByZW1vdmluZyB0aGUgdmFsdWUuCgogICAgICBUaGUgZGVzY3JpcHRpb24gc3RhdGVtZW50IG9mIHRoZSBwYXJlbnQgc3RhdGVtZW50IFNIT1VMRCBjb250YWluCiAgICAgIHRoZSBsYWJlbCAnSW5pdGlhbC12YWx1ZTogJyBmb2xsb3dlZCBieSB0aGUgdGV4dCBmcm9tIHRoZSBhcmd1bWVudC4KCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgbGVhZiBvciBsZWFmLWxpc3QuCiAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBOT1QgYmUgcHJlc2VudCBpZiB0aGUgbGVhZiBvciB0aGUgbGVhZi1saXN0CiAgICAgIGhhcyBhIGRlZmF1bHQgc3RhdGVtZW50IG9yIHRoZSB0eXBlIHVzZWQgZm9yIHRoZSBkYXRhIG5vZGUKICAgICAgaGFzIGEgZGVmYXVsdCB2YWx1ZS4KICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIE5PVCBiZSB1c2VkIGZvciBjb25maWc9ZmFsc2UgZGF0YSBvciBpbiBhbgogICAgICBhY3Rpb24sIHJwYyBvciBub3RpZmljYXRpb24uCiAgICAgIFplcm8gb3Igb25lIGluaXRpYWwtdmFsdWUgc3RhdGVtZW50cyBhcmUgYWxsb3dlZCBmb3IgYSBsZWFmIHBhcmVudAogICAgICBzdGF0ZW1lbnQuIFplcm8gb3IgbW9yZSBpbml0aWFsLXZhbHVlIHN0YXRlbWVudHMgYXJlIGFsbG93ZWQgZm9yIGEKICAgICAgbGVhZi1saXN0IHBhcmVudCBzdGF0ZW1lbnQuIElmIHRoZSBsZWFmLWxpc3QgaXMgb3JkZXJlZC1ieSB1c2VyLCB0aGUKICAgICAgaW5pdGlhbCB2YWx1ZXMgYXJlIHN0b3JlZCBpbiB0aGUgb3JkZXIgdGhleSBhcHBlYXIgaW4gdGhlIFlBTkcgZGVmaW5pdGlvbi4KICAgICAgTk8gc3Vic3RhdGVtZW50cyBhcmUgYWxsb3dlZC4KCiAgICAgIEFsd2F5cyBjb25zaWRlciB1c2luZyBhIFlBTkctZGVmYXVsdCBzdGF0ZW1lbnQgaW5zdGVhZC4KCiAgICAgIE1vZGlmaWNhdGlvbiBvZiB0aGUgaW5pdGlhbC12YWx1ZSBpcyBhIG5vbi1iYWNrd2FyZHMtY29tcGF0aWJsZSBjaGFuZ2UuCgogICAgICBUaGUgYXJndW1lbnQgc3BlY2lmaWVzIGEgc2luZ2xlIGluaXRpYWwgdmFsdWUgZm9yIGEgbGVhZiBvciBsZWFmLWxpc3QuCiAgICAgIFRoZSB2YWx1ZSBNVVNUIGJlIHBhcnQgb2YgdGhlIHZhbHVlc3BhY2Ugb2YgdGhlIGxlYWYvbGVhZi1saXN0LgogICAgICBJdCBmb2xsb3dzIHRoZSBzYW1lIHJ1bGVzIGFzIHRoZSBhcmd1bWVudCBvZiB0aGUgZGVmYXVsdCBzdGF0ZW1lbnQuIjsKCiAgICBhcmd1bWVudCAiaW5pdGlhbC12YWx1ZSI7CiAgfQp9Cg==
+_3gpp-common-yang-types        urn:3gpp:sa5:_3gpp-common-yang-types    \N      []      2023-11-06      bW9kdWxlIF8zZ3BwLWNvbW1vbi15YW5nLXR5cGVzIHsKICB5YW5nLXZlcnNpb24gMS4xOwogIG5hbWVzcGFjZSAidXJuOjNncHA6c2E1Ol8zZ3BwLWNvbW1vbi15YW5nLXR5cGVzIjsKICBwcmVmaXggInR5cGVzM2dwcCI7CgogIGltcG9ydCBpZXRmLWluZXQtdHlwZXMgeyBwcmVmaXggaW5ldDsgfQogIGltcG9ydCBpZXRmLXlhbmctdHlwZXMgeyBwcmVmaXggeWFuZzsgfQogIGltcG9ydCBfM2dwcC1jb21tb24teWFuZy1leHRlbnNpb25zIHsgcHJlZml4IHlleHQzZ3BwOyB9CgogIG9yZ2FuaXphdGlvbiAiM0dQUCBTQTUiOwogIGNvbnRhY3QgImh0dHBzOi8vd3d3LjNncHAub3JnL0R5bmFSZXBvcnQvVFNHLVdHLS1TNS0tb2ZmaWNpYWxzLmh0bT9JdGVtaWQ9NDY0IjsKICBkZXNjcmlwdGlvbiAiVGhlIG1vZGVsIGRlZmluZXMgYSBZQU5HIG1hcHBpbmcgb2YgdGhlIHRvcCBsZXZlbAogICAgaW5mb3JtYXRpb24gY2xhc3NlcyB1c2VkIGZvciBtYW5hZ2VtZW50IG9mIDVHIG5ldHdvcmtzIGFuZAogICAgbmV0d29yayBzbGljaW5nLgogICAgQ29weXJpZ2h0IDIwMjMsIDNHUFAgT3JnYW5pemF0aW9uYWwgUGFydG5lcnMgKEFSSUIsIEFUSVMsIENDU0EsIEVUU0ksIFRTRFNJLAogICAgVFRBLCBUVEMpLiBBbGwgcmlnaHRzIHJlc2VydmVkLiI7CiAgcmVmZXJlbmNlICIzR1BQIFRTIDI4LjYyMyI7CgogIHJldmlzaW9uIDIwMjMtMTEtMDYgeyByZWZlcmVuY2UgQ1ItMDMwNTsgfQogIHJldmlzaW9uIDIwMjMtMDktMTggeyByZWZlcmVuY2UgQ1ItMDI3MSA7IH0KICByZXZpc2lvbiAyMDIzLTA4LTA5IHsgcmVmZXJlbmNlIENSLTAyNjY7IH0KICByZXZpc2lvbiAyMDIzLTA1LTEwIHsgcmVmZXJlbmNlIENSLTAyNTA7IH0KICByZXZpc2lvbiAyMDIzLTAyLTE0IHsgcmVmZXJlbmNlIENSLTAyMzQ7IH0KICByZXZpc2lvbiAyMDIyLTExLTA0IHsgcmVmZXJlbmNlICJDUi0wMTk0IjsgfQogIHJldmlzaW9uIDIwMjItMTAtMjQgeyByZWZlcmVuY2UgQ1ItMDE5NjsgIH0KICByZXZpc2lvbiAyMDIyLTA3LTI2IHsgcmVmZXJlbmNlICJDUi0wMTgwIiA7IH0KICByZXZpc2lvbiAyMDIyLTAyLTA5IHsgcmVmZXJlbmNlICJDUi0wMTQ0IjsgfQogIHJldmlzaW9uIDIwMjEtMTEtMDEgeyByZWZlcmVuY2UgIkNSLTAxNDEiOyB9CgogIHJldmlzaW9uIDIwMjEtMDktMzAgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIExvbmdpdHVkZSwgTGF0aXR1ZGUsIFRlbnRoT2ZEZWdyZWVzLCBPbk9mZi4iOwogICAgcmVmZXJlbmNlICJDUi0wMTM4IjsKICB9CgogIHJldmlzaW9uIDIwMjAtMTEtMDYgewogICAgZGVzY3JpcHRpb24gIlJlbW92ZWQgaW5jb3JyZWN0IFMtTlNTQUkgZGVmaW5pdGlvbnMuIjsKICAgIHJlZmVyZW5jZSAiQ1ItMDExOCI7CiAgfQoKICByZXZpc2lvbiAyMDIwLTAzLTEwIHsKICAgIGRlc2NyaXB0aW9uICJSZW1vdmVkIGZhdWx0eSB3aGVuIHN0YXRlbWVudHMuIjsKICAgIHJlZmVyZW5jZSAiU1AtMjAwMjI5IjsKICB9CgogIHJldmlzaW9uIDIwMTktMTAtMjUgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIE1hbmFnZWRORlByb2ZpbGUuIjsKICAgIHJlZmVyZW5jZSAiUzUtMTk0NDU3IjsKICB9CgogIHJldmlzaW9uIDIwMTktMTAtMTYgewogICAgZGVzY3JpcHRpb24gIkFkZGVkIFNBUCBhbmQgdXNhZ2VTdGF0ZS4iOwogICAgcmVmZXJlbmNlICJTNS0xOTM1MTgiOwogIH0KCiAgcmV2aXNpb24gMjAxOS0wNi0yMyB7CiAgICByZWZlcmVuY2UgICJJbml0aWFsIHZlcnNpb24uIjsKICB9CgogIHR5cGVkZWYgRW5hYmxlZERpc2FibGVkIHsKICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICBlbnVtIERJU0FCTEVEIDsKICAgICAgZW51bSBFTkFCTEVEIDsKICAgIH0KICB9CgogIGdyb3VwaW5nIG5hbWVWYWx1ZVBhaXIgewogICAgbGVhZiBuYW1lIHsgdHlwZSBzdHJpbmc7IH0KICAgIGxlYWYgdmFsdWUgeyB0eXBlIHN0cmluZzsgfQogIH0KCiAgZ3JvdXBpbmcgUHJvY2Vzc01vbml0b3JHcnAgewogICAgZGVzY3JpcHRpb24gIlByb3ZpZGVzIGF0dHJpYnV0ZXMgdG8gbW9uaXRvciB0aGUgcHJvZ3Jlc3Mgb2YgcHJvY2Vzc2VzCiAgICAgIHdpdGggc3BlY2lmaWMgcHVycG9zZSBhbmQgbGltaXRlZCBsaWZldGltZSBydW5uaW5nIG9uIE1uUyBwcm9kdWNlcnMuCiAgICAgIEl0IG1heSBiZSB1c2VkIGFzIGRhdGEgdHlwZSBmb3IgZGVkaWNhdGVkIHByb2dyZXNzIG1vbml0b3IgYXR0cmlidXRlcwogICAgICB3aGVuIHNwZWNpZnlpbmcgdGhlIG1hbmFnZW1lbnQgcmVwcmVzZW50YXRpb24gb2YgdGhlc2UgcHJvY2Vzc2VzLgogICAgICBUaGUgYXR0cmlidXRlcyBpbiB0aGlzIGNsYXVzZSBhcmUgZGVmaW5lZCBpbiBhIGdlbmVyaWMgd2F5LgogICAgICBGb3Igc29tZSBhdHRyaWJ1dGVzIHNwZWNpYWxpc2F0aW9ucyBtYXkgYmUgcHJvdmlkZWQgd2hlbiBzcGVjaWZ5aW5nIGEKICAgICAgY29uY3JldGUgcHJvY2VzcyByZXByZXNlbnRhdGlvbi4KCiAgICAgIElmIGEgbWFuYWdlbWVudCBvcGVyYXRpb24gb24gc29tZSBJT0NzIHRyaWdnZXJzIGFuIGFzc29jaWF0ZWQKICAgICAgYXN5bmNocm9ub3VzIHByb2Nlc3MgKHdob3NlIHByb2dyZXNzIHNoYWxsIGJlIG1vbml0b3JlZCksIHRoaXMgc2hvdWxkCiAgICAgIGFsc28gcmVzdWx0IGluIGNyZWF0aW5nIGFuIGF0dHJpYnV0ZSBuYW1lZCAncHJvY2Vzc01vbml0b3InIChvZiB0eXBlCiAgICAgICdQcm9jZXNzTW9uaXRvcicpIGluIHRoZXNlIElPQyhzKS4gVGhlIHByb2Nlc3NNb25pdG9yIGF0dHJpYnV0ZSBtYXkgYmUKICAgICAgYWNjb21wYW5pZWQgYnkgdXNlLWNhc2Ugc3BlY2lmaWMgYWRkaXRpb25hbCBkYXRhIGl0ZW1zLgoKICAgICAgVGhlIHByb2dyZXNzIG9mIHRoZSBwcm9jZXNzIGlzIGRlc2NyaWJlZCBieSB0aGUgJ3N0YXR1cycgYW5kCiAgICAgICdwcm9ncmVzc1BlcmNlbnRhZ2UnIGF0dHJpYnV0ZXMuIEFkZGl0aW9uYWwgdGV4dHVhbCBxdWFsaWZpY2F0aW9ucyBmb3IKICAgICAgdGhlICdzdGF0dXMnIGF0dHJpYnV0ZSBtYXkgYmUgcHJvdmlkZWQgYnkgdGhlICdwcm9ncmVzc1N0YXRlSW5mbycgYW5kCiAgICAgICdyZXN1bHRTdGF0ZUluZm8nIGF0dHJpYnV0ZXMuCgogICAgICBXaGVuIHRoZSBwcm9jZXNzIGlzIGluc3RhbnRpYXRlZCwgdGhlICdzdGF0dXMnIGlzIHNldCB0byAnTk9UX1JVTk5JTkcnCiAgICAgIGFuZCB0aGUgJ3Byb2dyZXNzUGVyY2VudGFnZScgdG8gJzAnLiBUaGUgTW5TIHByb2R1Y2VyIGRlY2lkZXMgd2hlbiB0bwogICAgICBzdGFydCBleGVjdXRpbmcgdGhlIHByb2Nlc3MgYW5kIHRvIHRyYW5zaXRpb24gaW50byB0aGUgJ1JVTk5JTkcnIHN0YXRlLgogICAgICBUaGlzIHRpbWUgaXMgY2FwdHVyZWQgaW4gdGhlICdzdGFydFRpbWUnIGF0dHJpYnV0ZS4gQWx0ZXJuYXRpdmVseSwgdGhlCiAgICAgIHByb2Nlc3MgbWF5IHN0YXJ0IHRvIGV4ZWN1dGUgZGlyZWN0bHkgdXBvbiBpdHMgaW5zdGFudGlhdGlvbi4gT25lCiAgICAgIGFsdGVybmF0aXZlIG11c3QgYmUgc2VsZWN0ZWQgd2hlbiB1c2luZyB0aGlzIGRhdGEgdHlwZS4KCiAgICAgIER1cmluZyB0aGUgJ1JVTk5JTkcnIHN0YXRlIHRoZSAncHJvZ3Jlc3NQZXJjZW50YWdlJyBhdHRyaWJ1dGUgbWF5IGJlCiAgICAgIHJlcGVhdGVkbHkgdXBkYXRlZC4gVGhlIGV4YWN0IHNlbWFudGljIG9mIHRoaXMgYXR0cmlidXRlIGlzIHN1YmplY3QgdG8KICAgICAgZnVydGhlciBzcGVjaWFsaXNhdGlvbi4gVGhlICdwcm9ncmVzc0luZm8nIGF0dHJpYnV0ZSBtYXkgYmUgdXNlZCB0bwogICAgICBwcm92aWRlIGFkZGl0aW9uYWwgdGV4dHVhbCBpbmZvcm1hdGlvbiBpbiB0aGUgJ05PVF9SVU5OSU5HJywgJ0NBTkNFTExJTkcnCiAgICAgIGFuZCAnUlVOTklORycgc3RhdGVzLiBGdXJ0aGVyIHNwZWNpYWxpc2F0aW9uIG9mCiAgICAgICdwcm9ncmVzc1N0YXRlSW5mbycgbWF5IGJlIHByb3ZpZGVkIHdoZXJlIHRoaXMgZGF0YSB0eXBlIGlzCiAgICAgIHVzZWQuCgogICAgICBVcG9uIHN1Y2Nlc3NmdWwgY29tcGxldGlvbiBvZiB0aGUgcHJvY2VzcywgdGhlICdzdGF0dXMnIGF0dHJpYnV0ZSBpcyBzZXQKICAgICAgdG8gJ0ZJTklTSEVEJywgdGhlICdwcm9ncmVzc1BlcmNlbnRhZ2UnIHRvIDEwMCUuIFRoZSB0aW1lIGlzIGNhcHR1cmVkIGluCiAgICAgIHRoZSAnZW5kVGltZScgYXR0cmlidXRlLiBBZGRpdGlvbmFsIHRleHR1YWwgaW5mb3JtYXRpb24gbWF5IGJlIHByb3ZpZGVkCiAgICAgIGluIHRoZSAncmVzdWx0U3RhdGVJbmZvJyBhdHRyaWJ1dGUuIFRoZSB0eXBlIG9mCiAgICAgICdyZXN1bHRTdGF0ZUluZm8nIGluIHRoaXMgZGF0YSB0eXBlIGRlZmluaXRpb24gaXMgJ1N0cmluZycuCiAgICAgIEZ1cnRoZXIgc3BlY2lhbGlzYXRpb24gb2YgJ3Jlc3VsdFN0YXRlSW5mbycgbWF5IGJlIHByb3ZpZGVkCiAgICAgIHdoZXJlIHRoaXMgZGF0YSB0eXBlIGlzIHVzZWQuCgogICAgICBJbiBjYXNlIHRoZSBwcm9jZXNzIGZhaWxzIHRvIGNvbXBsZXRlIHN1Y2Nlc3NmdWxseSwgdGhlICdzdGF0dXMnCiAgICAgIGF0dHJpYnV0ZSBpcyBzZXQgdG8gJ0ZBSUxFRCcgb3IgJ1BBUlRJQUxMWV9GQUlMRUQnLCB0aGUgY3VycmVudCB2YWx1ZSBvZgogICAgICAncHJvZ3Jlc3NQZXJjZW50YWdlJyBpcyBmcm96ZW4sIGFuZCB0aGUgdGltZSBjYXB0dXJlZCBpbiAnZW5kVGltZScuIFRoZQogICAgICAncmVzdWx0U3RhdGVJbmZvJyBzcGVjaWZpZXMgdGhlIHJlYXNvbiBmb3IgdGhlIGZhaWx1cmUuCiAgICAgIFNwZWNpZmljIGZhaWx1cmUgcmVhc29ucyBtYXkgYmUgc3BlY2lmaWVkIHdoZXJlIHRoZSBkYXRhIHR5cGUgZGVmaW5lZCBpbgogICAgICB0aGlzIGNsYXVzZSBpcyB1c2VkLiBUaGUgZXhhY3Qgc2VtYW50aWMgb2YgZmFpbHVyZSBtYXkgYmUgc3ViamVjdCBmb3IKICAgICAgZnVydGhlciBzcGVjaWFsaXNhdGlvbiBhcyB3ZWxsLgoKICAgICAgSW4gY2FzZSB0aGUgcHJvY2VzcyBpcyBjYW5jZWxsZWQsIHRoZSAnc3RhdHVzJyBhdHRyaWJ1dGUgaXMgZmlyc3Qgc2V0IHRvCiAgICAgICdDQU5DRUxMSU5HJyBhbmQgd2hlbiB0aGUgcHJvY2VzcyBpcyByZWFsbHkgY2FuY2VsbGVkIHRoZW4gdG8gJ0NBTkNFTExFRCcuCiAgICAgIFRoZSB0cmFuc2l0aW9uIHRvICdDQU5DRUxMRUQnIGlzIGNhcHR1cmVkIGluIHRoZSAnZW5kVGltZScgYXR0cmlidXRlLgogICAgICBUaGUgdmFsdWUgb2YgJ3Byb2dyZXNzUGVyY2VudGFnZScgaXMgZnJvemVuLiBBZGRpdGlvbmFsIHRleHR1YWwKICAgICAgaW5mb3JtYXRpb24gbWF5IGJlIHByb3ZpZGVkIGluIHRoZSAncmVzdWx0U3RhdGVJbmZvJyBhdHRyaWJ1dGUuCgogICAgICBUaGUgJ3Jlc3VsdFN0YXRlSW5mbycgYXR0cmlidXRlIGlzIHByb3ZpZGVkIG9ubHkgZm9yIGFkZGl0aW9uYWwgdGV4dHVhbAogICAgICBxdWFsaWZpY2F0aW9uIG9mIHRoZSBzdGF0ZXMgJ0ZJTklTSEVEJywgJ0ZBSUxFRCcsICdQQVJUSUFMTFlfRkFJTEVEJyBvcgogICAgICAnQ0FOQ0VMTEVEJy4gSXQgc2hhbGwgbm90IGJlIHVzZWQgZm9yIG1ha2luZyB0aGUgb3V0Y29tZSwgdGhhdCB0aGUKICAgICAgcHJvY2VzcyBtYXkgcHJvZHVjZSBpbiBjYXNlIG9mIHN1Y2Nlc3MsIGF2YWlsYWJsZS4KCiAgICAgIFRoZSBwcm9jZXNzIG1heSBoYXZlIHRvIGJlIGNvbXBsZXRlZCB3aXRoaW4gYSBjZXJ0YWluIHRpbWUgYWZ0ZXIgaXRzCiAgICAgIGNyZWF0aW9uLCBmb3IgZXhhbXBsZSBiZWNhdXNlIHJlcXVpcmVkIGRhdGEgbWF5IG5vdCBiZSBhdmFpbGFibGUgYW55CiAgICAgIG1vcmUgYWZ0ZXIgYSBjZXJ0YWluIHRpbWUsIG9yIHRoZSBwcm9jZXNzIG91dGNvbWUgaXMgbmVlZGVkIHVudGlsIGEKICAgICAgY2VydGFpbiB0aW1lIGFuZCB3aGVuIG5vdCBwcm92aWRlZCBieSB0aGlzIHRpbWUgaXMgbm90IG5lZWRlZCBhbnkgbW9yZS4KICAgICAgVGhlIHRpbWUgdW50aWwgdGhlIE1uUyBwcm9kdWNlciBhdXRvbWF0aWNhbGx5IGNhbmNlbHMgdGhlIHByb2Nlc3MgaXMKICAgICAgaW5kaWNhdGVkIGJ5IHRoZSAndGltZXInIGF0dHJpYnV0ZS4iOwoKICAgIGxlYWYgaWQgewogICAgICB0eXBlIHN0cmluZzsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIGRlc2NyaXB0aW9uICJJZCBvZiB0aGUgcHJvY2Vzcy4gSXQgaXMgdW5pcXVlIHdpdGhpbiBhIHNpbmdsZQogICAgICAgIG11bHRpdmFsdWUgYXR0cmlidXRlIG9mIHR5cGUgUHJvY2Vzc01vbml0b3IuIjsKICAgIH0KCiAgICBsZWFmIHN0YXR1cyB7CiAgICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICAgIGVudW0gTk9UX1NUQVJURUQgOwogICAgICAgIGVudW0gUlVOTklORyA7CiAgICAgICAgZW51bSBDQU5DRUxMSU5HIDsKICAgICAgICBlbnVtIEZJTklTSEVEIDsKICAgICAgICBlbnVtIEZBSUxFRCA7CiAgICAgICAgZW51bSBQQVJUSUFMTFlfRkFJTEVEIDsKICAgICAgICBlbnVtIENBTkNFTExFRCA7CiAgICAgIH0KICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZWZhdWx0ICBSVU5OSU5HOwogICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyB0aGUgc3RhdHVzIG9mIHRoZSBhc3NvY2lhdGVkIHByb2Nlc3MsCiAgICAgICAgd2hldGhlciBpdCBmYWlscywgc3VjY2VlZHMgZXRjLgogICAgICAgIEl0IGRvZXMgbm90IHJlcHJlc2VudCB0aGUgcmV0dXJuZWQgdmFsdWVzIG9mIGEgc3VjY2Vzc2Z1bGx5IGZpbmlzaGVkCiAgICAgICAgcHJvY2Vzcy4gIjsKICAgIH0KCiAgICBsZWFmIHByb2dyZXNzUGVyY2VudGFnZSB7CiAgICAgIHR5cGUgdWludDggewogICAgICAgIHJhbmdlIDAuLjEwMDsKICAgICAgfQogICAgICBjb25maWcgZmFsc2U7CiAgICAgIGRlc2NyaXB0aW9uICJQcm9ncmVzcyBvZiB0aGUgYXNzb2NpYXRlZCBwcm9jZXNzIGFzIHBlcmNlbnRhZ2UiOwogICAgfQoKICAgIGxlYWYtbGlzdCBwcm9ncmVzc1N0YXRlSW5mbyB7CiAgICAgIHR5cGUgc3RyaW5nOwogICAgICBjb25maWcgZmFsc2U7CiAgICAgIGRlc2NyaXB0aW9uICJBZGRpdGlvbmFsIHRleHR1YWwgcXVhbGlmaWNhdGlvbiBvZiB0aGUgc3RhdGVzCiAgICAgICAgJ05PVF9TVEFSVEVEJywgJ0NBTkNFTExJTkcnIGFuZCAnUlVOTklORycuCgogICAgICAgIEZvciBzcGVjaWZpYyBwcm9jZXNzZXMsIHNwZWNpZmljIHdlbGwtZGVmaW5lZCBzdHJpbmdzIChlLmcuIHN0cmluZwogICAgICAgIHBhdHRlcm5zIG9yIGVudW1zKSBtYXkgYmUgZGVmaW5lZCBhcyBhIHNwZWNpYWxpc2F0aW9uLiI7CiAgICB9CgogICAgbGVhZiByZXN1bHRTdGF0ZUluZm8gewogICAgICB0eXBlIHN0cmluZzsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZXNjcmlwdGlvbiAiQWRkaXRpb25hbCB0ZXh0dWFsIHF1YWxpZmljYXRpb24gb2YgdGhlIHN0YXRlcwogICAgICAgICdGSU5JU0hFRCcsICdGQUlMRUQnLCAnUEFSVElBTExZX0ZBSUxFRCBhbmQgJ0NBTkNFTExFRCcuCiAgICAgICAgRm9yIGV4YW1wbGUsIGluIHRoZSAnRkFJTEVEJyBvciAnUEFSVElBTExZX0ZBSUxFRCcgc3RhdGUgdGhpcwogICAgICAgIGF0dHJpYnV0ZSBtYXkgYmUgdXNlZCB0byBwcm92aWRlIGVycm9yIHJlYXNvbnMuCgogICAgICAgIFRoaXMgYXR0cmlidXRlIHNoYWxsIG5vdCBiZSB1c2VkIHRvIG1ha2UgdGhlIG91dGNvbWUgb2YgdGhlIHByb2Nlc3MKICAgICAgICBhdmFpbGFibGUgZm9yIHJldHJpZXZhbCwgaWYgYW55LiBGb3IgdGhpcyBwdXJwb3NlLCBkZWRpY2F0ZWQKICAgICAgICBhdHRyaWJ1dGVzIHNoYWxsIGJlIHNwZWNpZmllZCB3aGVuIHNwZWNpZnlpbmcgdGhlIHJlcHJlc2VudGF0aW9uIG9mCiAgICAgICAgYSBzcGVjaWZpYyBwcm9jZXNzLgoKICAgICAgICBGb3Igc3BlY2lmaWMgcHJvY2Vzc2VzLCBzcGVjaWZpYyB3ZWxsLWRlZmluZWQgc3RyaW5ncyAoZS5nLiBzdHJpbmcKICAgICAgICBwYXR0ZXJucyBvciBlbnVtcykgbWF5IGJlIGRlZmluZWQgYXMgYSBzcGVjaWFsaXNhdGlvbi4iOwogICAgfQoKICAgIGxlYWYgc3RhcnRUaW1lIHsKICAgICAgdHlwZSB5YW5nOmRhdGUtYW5kLXRpbWU7CiAgICAgIGNvbmZpZyBmYWxzZTsKICAgICAgZGVzY3JpcHRpb24gIlN0YXJ0IHRpbWUgb2YgdGhlIGFzc29jaWF0ZWQgcHJvY2VzcywgaS5lLiB0aGUgdGltZSB3aGVuIHRoZQogICAgICAgIHN0YXR1cyBjaGFuZ2VkIGZyb20gJ05PVF9TVEFSVEVEJyB0byAnUlVOTklORycuIjsKICAgIH0KCiAgICBsZWFmIGVuZFRpbWUgewogICAgICB0eXBlIHlhbmc6ZGF0ZS1hbmQtdGltZTsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBkZXNjcmlwdGlvbiAiRGF0ZSBhbmQgdGltZSB3aGVuIHN0YXR1cyBjaGFuZ2VkIHRvICdTVUNDRVNTJywgJ0NBTkNFTExFRCcsCiAgICAgICAgJ0ZBSUxFRCcgb3IgJ1BBUlRJQUxMWV9GQUlMRUQnLgoKICAgICAgICBJZiB0aGUgdGltZSBpcyBpbiB0aGUgZnV0dXJlLCBpdCBpcyB0aGUgZXN0aW1hdGVkIHRpbWUKICAgICAgICB0aGUgcHJvY2VzcyB3aWxsIGVuZC4iOwogICAgfQoKICAgIGxlYWYgdGltZXIgewogICAgICB0eXBlIHVpbnQzMjsKICAgICAgdW5pdHMgbWludXRlczsKICAgICAgZGVzY3JpcHRpb24gIlRpbWUgdW50aWwgdGhlIGFzc29jaWF0ZWQgcHJvY2VzcyBpcyBhdXRvbWF0aWNhbGx5IGNhbmNlbGxlZC4KICAgICAgICBJZiBzZXQsIHRoZSBzeXN0ZW0gZGVjcmVhc2VzIHRoZSB0aW1lciB3aXRoIHRpbWUuIFdoZW4gaXQgcmVhY2hlcyB6ZXJvCiAgICAgICAgdGhlIGNhbmNlbGxhdGlvbiBvZiB0aGUgYXNzb2NpYXRlZCBwcm9jZXNzIGlzIGluaXRpYXRlZCBieSB0aGUKICAgICAgICBNblNfUHJvZHVjZXIuCiAgICAgICAgSWYgbm90IHNldCwgdGhlcmUgaXMgbm8gdGltZSBsaW1pdCBmb3IgdGhlIHByb2Nlc3MuCgogICAgICAgIE9uY2UgdGhlIHRpbWVyIGlzIHNldCwgdGhlIGNvbnN1bWVyIGNhbiBub3QgY2hhbmdlIGl0IGFueW1vcmUuCiAgICAgICAgSWYgdGhlIGNvbnN1bWVyIGhhcyBub3Qgc2V0IHRoZSB0aW1lciB0aGUgTW5TIFByb2R1Y2VyIG1heSBzZXQgaXQuIjsKICAgICAgeWV4dDNncHA6bm90Tm90aWZ5YWJsZTsKICAgIH0KICB9CgogIHR5cGVkZWYgVGVudGhPZkRlZ3JlZXMgewogICAgdHlwZSB1aW50MTYgewogICAgICByYW5nZSAwLi4zNjAwOwogICAgfQogICAgdW5pdHMgIjAuMSBkZWdyZWVzIjsKICAgIGRlc2NyaXB0aW9uICJBIHNpbmdsZSBpbnRlZ3JhbCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIGFuIGFuZ2xlIGluIGRlZ3JlZXMKICAgICAgYmV0d2VlbiAwIGFuZCAzNjAgd2l0aCBhIHJlc29sdXRpb24gb2YgMC4xIGRlZ3JlZXMuIjsKICB9CgogIHR5cGVkZWYgTGF0aXR1ZGUgewogICAgdHlwZSBkZWNpbWFsNjQgewogICAgICBmcmFjdGlvbi1kaWdpdHMgNDsKICAgICAgcmFuZ2UgIi05MC4wMDAwLi4rOTAuMDAwMCI7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiTGF0aXR1ZGUgdmFsdWVzIjsKICB9CgogIHR5cGVkZWYgTG9uZ2l0dWRlIHsKICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgZnJhY3Rpb24tZGlnaXRzIDQ7CiAgICAgIHJhbmdlICItMTgwLjAwMDAuLisxODAuMDAwMCI7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiTG9uZ2l0dWRlIHZhbHVlcyI7CiAgfQoKICB0eXBlZGVmIEFsdGl0dWRlICB7CiAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgIGZyYWN0aW9uLWRpZ2l0cyA2OwogICAgfQogICAgdW5pdHMgIm1ldGVycyI7CiAgICBkZXNjcmlwdGlvbgogICAgICAiSGVpZ2h0IGZyb20gYSByZWZlcmVuY2UgMCB2YWx1ZS4iOwogIH0KCiAgZ3JvdXBpbmcgR2VvZ3JhcGhpY2FsQ29vcmRpbmF0ZXMgewogICAgZGVzY3JpcHRpb24gIlRoaXMgZGF0YXR5cGUgcmVwcmVzZW50cyB0aGUgZ2VvZ3JhcGhpY2FsIGNvb3JkaW5hdGVzIjsKICAgIHJlZmVyZW5jZSAiI0dQUCBUUyAyOC41NTggY2xhdXNlIDYuMy44IjsKCiAgICBsZWFmIGxhdGl0dWRlIHsKICAgICAgdHlwZSBMYXRpdHVkZTsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CgogICAgbGVhZiBsb25naXR1ZGUgewogICAgICB0eXBlIExvbmdpdHVkZTsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CgogICAgbGVhZiBhbHRpdHVkZSB7CiAgICAgIHR5cGUgQWx0aXR1ZGU7CiAgICB9CgogIH0KCiAgdHlwZWRlZiBPbk9mZiB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBPTjsKICAgICAgZW51bSBPRkY7CiAgICB9CiAgfQoKICAvLyBncm91cGluZyBNYW5hZ2VkTkZQcm9maWxlIHdpbGwgYmUgcmVtb3ZlZCBhcyBpdCBpcwogIC8vICBiZWluZyBtb3ZlZCB0byBfM2dwcC01Z2MtbnJtLW5mcHJvZmlsZQogIGdyb3VwaW5nIE1hbmFnZWRORlByb2ZpbGUgewogICAgZGVzY3JpcHRpb24gIkRlZmluZXMgcHJvZmlsZSBmb3IgbWFuYWdlZCBORiI7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuNTAxIjsKCiAgICBsZWFmIGlkeCB7IHR5cGUgdWludDMyIDsgfQoKICAgIGxlYWYgbmZJbnN0YW5jZUlEIHsKICAgICAgY29uZmlnIGZhbHNlOwogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSB5YW5nOnV1aWQgOwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBwcm9maWxlIGZvciBtYW5hZ2VkIE5GLgogICAgICAgIFRoZSBmb3JtYXQgb2YgdGhlIE5GIEluc3RhbmNlIElEIHNoYWxsIGJlIGEKICAgICAgICBVbml2ZXJzYWxseSBVbmlxdWUgSWRlbnRpZmllciAoVVVJRCkgdmVyc2lvbiA0LAogICAgICAgIGFzIGRlc2NyaWJlZCBpbiBJRVRGIFJGQyA0MTIyICIgOwogICAgICB5ZXh0M2dwcDppblZhcmlhbnQ7CiAgICB9CgogICAgbGVhZi1saXN0IG5mVHlwZSB7CiAgICAgIGNvbmZpZyBmYWxzZTsKICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgIHR5cGUgTmZUeXBlOwogICAgICBkZXNjcmlwdGlvbiAiVHlwZSBvZiB0aGUgTmV0d29yayBGdW5jdGlvbiIgOwogICAgfQoKICAgIGxlYWYgaG9zdEFkZHIgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSBpbmV0Omhvc3QgOwogICAgICBkZXNjcmlwdGlvbiAiSG9zdCBhZGRyZXNzIG9mIGEgTkYiOwogICAgfQoKICAgIGxlYWYgYXV0aHpJbmZvIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBORiBTcGVjaWZpYyBTZXJ2aWNlIGF1dGhvcml6YXRpb24KICAgICAgICBpbmZvcm1hdGlvbi4gSXQgc2hhbGwgaW5jbHVkZSB0aGUgTkYgdHlwZSAocykgYW5kIE5GIHJlYWxtcy9vcmlnaW5zCiAgICAgICAgYWxsb3dlZCB0byBjb25zdW1lIE5GIFNlcnZpY2Uocykgb2YgTkYgU2VydmljZSBQcm9kdWNlci4iOwogICAgICByZWZlcmVuY2UgIlNlZSBUUyAyMy41MDEiIDsKICAgIH0KCiAgICBsZWFmIGxvY2F0aW9uIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiSW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvY2F0aW9uIG9mIHRoZSBORiBpbnN0YW5jZQogICAgICAgIChlLmcuIGdlb2dyYXBoaWMgbG9jYXRpb24sIGRhdGEgY2VudGVyKSBkZWZpbmVkIGJ5IG9wZXJhdG9yIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmIGNhcGFjaXR5IHsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIHR5cGUgdWludDE2IDsKICAgICAgZGVzY3JpcHRpb24gIlRoaXMgcGFyYW1ldGVyIGRlZmluZXMgc3RhdGljIGNhcGFjaXR5IGluZm9ybWF0aW9uCiAgICAgICAgaW4gdGhlIHJhbmdlIG9mIDAtNjU1MzUsIGV4cHJlc3NlZCBhcyBhIHdlaWdodCByZWxhdGl2ZSB0byBvdGhlcgogICAgICAgIE5GIGluc3RhbmNlcyBvZiB0aGUgc2FtZSB0eXBlOyBpZiBjYXBhY2l0eSBpcyBhbHNvIHByZXNlbnQgaW4gdGhlCiAgICAgICAgbmZTZXJ2aWNlTGlzdCBwYXJhbWV0ZXJzLCB0aG9zZSB3aWxsIGhhdmUgcHJlY2VkZW5jZSBvdmVyIHRoaXMgdmFsdWUuIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmIG5GU3J2R3JvdXBJZCB7CiAgICAgIHR5cGUgc3RyaW5nIDsKICAgICAgZGVzY3JpcHRpb24gIlRoaXMgcGFyYW1ldGVyIGRlZmluZXMgaWRlbnRpdHkgb2YgdGhlIGdyb3VwIHRoYXQgaXMKICAgICAgICBzZXJ2ZWQgYnkgdGhlIE5GIGluc3RhbmNlLgogICAgICAgIE1heSBiZSBjb25maWcgZmFsc2Ugb3IgdHJ1ZSBkZXBlbmRpbmcgb24gdGhlIE1hbmFnZWRGdW5jdGlvbi4KICAgICAgICBDb25maWc9dHJ1ZSBmb3IgVWRyaW5mby4gQ29uZmlnPWZhbHNlIGZvciBVZG1JbmZvIGFuZCBBdXNmSW5mby4KICAgICAgICBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IFVETSBvciBBVVNGIG9yIFVEUi4gIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmLWxpc3Qgc3VwcG9ydGVkRGF0YVNldElkcyB7CiAgICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICAgIGVudW0gU1VCU0NSSVBUSU9OOwogICAgICAgIGVudW0gUE9MSUNZOwogICAgICAgIGVudW0gRVhQT1NVUkU7CiAgICAgICAgZW51bSBBUFBMSUNBVElPTjsKICAgICAgfQogICAgICBkZXNjcmlwdGlvbiAiTGlzdCBvZiBzdXBwb3J0ZWQgZGF0YSBzZXRzIGluIHRoZSBVRFIgaW5zdGFuY2UuCiAgICAgICAgTWF5IGJlIHByZXNlbnQgaWYgLi4vbmZUeXBlID0gVURSIjsKICAgICAgcmVmZXJlbmNlICJUUyAyOS41MTAiIDsKICAgIH0KCiAgICBsZWFmLWxpc3Qgc21mU2VydmluZ0FyZWFzIHsKICAgICAgdHlwZSBzdHJpbmcgOwogICAgICBkZXNjcmlwdGlvbiAiRGVmaW5lcyB0aGUgU01GIHNlcnZpY2UgYXJlYShzKSB0aGUgVVBGIGNhbiBzZXJ2ZS4KICAgICAgICBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IFVQRiI7CiAgICAgIHJlZmVyZW5jZSAiVFMgMjkuNTEwIiA7CiAgICB9CgogICAgbGVhZiBwcmlvcml0eSB7CiAgICAgIHR5cGUgdWludDE2OwogICAgICBkZXNjcmlwdGlvbiAiVGhpcyBwYXJhbWV0ZXIgZGVmaW5lcyBQcmlvcml0eSAocmVsYXRpdmUgdG8gb3RoZXIgTkZzCiAgICAgICAgb2YgdGhlIHNhbWUgdHlwZSkgaW4gdGhlIHJhbmdlIG9mIDAtNjU1MzUsIHRvIGJlIHVzZWQgZm9yIE5GIHNlbGVjdGlvbjsKICAgICAgICBsb3dlciB2YWx1ZXMgaW5kaWNhdGUgYSBoaWdoZXIgcHJpb3JpdHkuIElmIHByaW9yaXR5IGlzIGFsc28gcHJlc2VudAogICAgICAgIGluIHRoZSBuZlNlcnZpY2VMaXN0IHBhcmFtZXRlcnMsIHRob3NlIHdpbGwgaGF2ZSBwcmVjZWRlbmNlIG92ZXIKICAgICAgICB0aGlzIHZhbHVlLiBTaGFsbCBiZSBwcmVzZW50IGlmIC4uL25mVHlwZSA9IEFNRiAiOwogICAgICByZWZlcmVuY2UgIlRTIDI5LjUxMCIgOwogICAgfQogIH0KCiAgdHlwZWRlZiB1c2FnZVN0YXRlIHsKICAgIHR5cGUgZW51bWVyYXRpb24gewogICAgICBlbnVtIElETEU7CiAgICAgIGVudW0gQUNUSVZFOwogICAgICBlbnVtIEJVU1k7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiSXQgZGVzY3JpYmVzIHdoZXRoZXIgb3Igbm90IHRoZSByZXNvdXJjZSBpcyBhY3RpdmVseSBpbgogICAgICB1c2UgYXQgYSBzcGVjaWZpYyBpbnN0YW50LCBhbmQgaWYgc28sIHdoZXRoZXIgb3Igbm90IGl0IGhhcyBzcGFyZQogICAgICBjYXBhY2l0eSBmb3IgYWRkaXRpb25hbCB1c2VycyBhdCB0aGF0IGluc3RhbnQuIFRoZSB2YWx1ZSBpcyBSRUFELU9OTFkuIjsKICAgIHJlZmVyZW5jZSAiSVRVIFQgUmVjb21tZW5kYXRpb24gWC43MzEiOwogIH0KCiAgZ3JvdXBpbmcgU0FQR3JwIHsKICAgIGxlYWYgaG9zdCB7CiAgICAgIHR5cGUgaW5ldDpob3N0OwogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgIH0KICAgIGxlYWYgcG9ydCB7CiAgICAgIHR5cGUgaW5ldDpwb3J0LW51bWJlcjsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICB9CiAgICBkZXNjcmlwdGlvbiAiU2VydmljZSBhY2Nlc3MgcG9pbnQuIjsKICAgIHJlZmVyZW5jZSAiVFMgMjguNjIyIjsKICB9CgogIHR5cGVkZWYgTWNjIHsKICAgIGRlc2NyaXB0aW9uICJUaGUgbW9iaWxlIGNvdW50cnkgY29kZSBjb25zaXN0cyBvZiB0aHJlZSBkZWNpbWFsIGRpZ2l0cywKICAgICAgVGhlIGZpcnN0IGRpZ2l0IG9mIHRoZSBtb2JpbGUgY291bnRyeSBjb2RlIGlkZW50aWZpZXMgdGhlIGdlb2dyYXBoaWMKICAgICAgcmVnaW9uICh0aGUgZGlnaXRzIDEgYW5kIDggYXJlIG5vdCB1c2VkKToiOwogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMDItNzldWzAtOV1bMC05XSc7CiAgICB9CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuMDAzIHN1YmNsYXVzZSAyLjIgYW5kIDEyLjEiOwogIH0KCiAgdHlwZWRlZiBNbmMgewogICAgZGVzY3JpcHRpb24gIlRoZSBtb2JpbGUgbmV0d29yayBjb2RlIGNvbnNpc3RzIG9mIHR3byBvciB0aHJlZQogICAgICBkZWNpbWFsIGRpZ2l0cyAoZm9yIGV4YW1wbGU6IE1OQyBvZiAwMDEgaXMgbm90IHRoZSBzYW1lIGFzIE1OQyBvZiAwMSkiOwogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMC05XVswLTldWzAtOV18WzAtOV1bMC05XSc7CiAgICB9CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjMuMDAzIHN1YmNsYXVzZSAyLjIgYW5kIDEyLjEiOwogIH0KCiAgZ3JvdXBpbmcgUExNTklkIHsKICAgIGxlYWYgbWNjIHsKICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIHR5cGUgTWNjOwogICAgfQogICAgbGVhZiBtbmMgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgdHlwZSBNbmM7CiAgICB9CiAgICByZWZlcmVuY2UgIlRTIDM4LjQxMyBjbGF1c2UgOS4zLjMuNSI7CiAgfQoKICB0eXBlZGVmIE5jaSB7CiAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbCBJZGVudGl0eS4gVGhlIE5DSSBzaGFsbCBiZSBvZiBmaXhlZCBsZW5ndGggb2YgMzYgYml0cwogICAgICBhbmQgc2hhbGwgYmUgY29kZWQgdXNpbmcgZnVsbCBoZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbi4KICAgICAgVGhlIGV4YWN0IGNvZGluZyBvZiB0aGUgTkNJIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBlYWNoIFBMTU4gb3BlcmF0b3IiOwogICAgcmVmZXJlbmNlICJUUyAyMy4wMDMiOwogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggMzY7CiAgICAgICAgcGF0dGVybiAnWzAxXSsnOwogICAgICB9CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggOTsKICAgICAgICBwYXR0ZXJuICdbYS1mQS1GMC05XSonOwogICAgICB9CiAgICB9CiAgfQoKICB0eXBlZGVmIE9wZXJhdGlvbmFsU3RhdGUgewogICAgcmVmZXJlbmNlICIzR1BQIFRTIDI4LjYyNSBhbmQgSVRVLVQgWC43MzEiOwogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gRElTQUJMRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyB0b3RhbGx5IGlub3BlcmFibGUuIjsKICAgICAgfQoKICAgICAgZW51bSBFTkFCTEVEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgcGFydGlhbGx5IG9yIGZ1bGx5IG9wZXJhYmxlLiI7CiAgICAgIH0KCiAgICB9CiAgfQoKICB0eXBlZGVmIEJhc2ljQWRtaW5pc3RyYXRpdmVTdGF0ZSB7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjguNjI1IGFuZCBJVFUtVCBYLjczMSI7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBMT0NLRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyBhZG1pbmlzdHJhdGl2ZWx5IHByb2hpYml0ZWQgZnJvbSBwZXJmb3JtaW5nCiAgICAgICAgICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4iOwogICAgICB9CgogICAgICBlbnVtIFVOTE9DS0VEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgYWRtaW5pc3RyYXRpdmVseSBwZXJtaXR0ZWQgdG8gcGVyZm9ybQogICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4gVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBpdHMgaW5oZXJlbnQKICAgICAgICAgIG9wZXJhYmlsaXR5LiI7CiAgICAgIH0KICAgIH0KICB9CgogIHR5cGVkZWYgQWRtaW5pc3RyYXRpdmVTdGF0ZSB7CiAgICByZWZlcmVuY2UgIjNHUFAgVFMgMjguNjI1IGFuZCBJVFUtVCBYLjczMSI7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBMT0NLRUQgewogICAgICAgIHZhbHVlIDA7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSByZXNvdXJjZSBpcyBhZG1pbmlzdHJhdGl2ZWx5IHByb2hpYml0ZWQgZnJvbSBwZXJmb3JtaW5nCiAgICAgICAgICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4iOwogICAgICB9CgogICAgICBlbnVtIFVOTE9DS0VEIHsKICAgICAgICB2YWx1ZSAxOwogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgcmVzb3VyY2UgaXMgYWRtaW5pc3RyYXRpdmVseSBwZXJtaXR0ZWQgdG8gcGVyZm9ybQogICAgICAgICAgc2VydmljZXMgZm9yIGl0cyB1c2Vycy4gVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBpdHMgaW5oZXJlbnQKICAgICAgICAgIG9wZXJhYmlsaXR5LiI7CiAgICAgIH0KCiAgICAgIGVudW0gU0hVVFRJTkdET1dOIHsKICAgICAgICB2YWx1ZSAyOwogICAgICAgIGRlc2NyaXB0aW9uICJVc2Ugb2YgdGhlIHJlc291cmNlIGlzIGFkbWluaXN0cmF0aXZlbHkgcGVybWl0dGVkIHRvCiAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZXMgb2YgdXNlIG9ubHkuIFdoaWxlIHRoZSBzeXN0ZW0gcmVtYWlucyBpbgogICAgICAgICAgdGhlIHNodXR0aW5nIGRvd24gc3RhdGUgdGhlIG1hbmFnZXIgb3IgdGhlIG1hbmFnZWQgZWxlbWVudAogICAgICAgICAgbWF5IGF0IGFueSB0aW1lIGNhdXNlIHRoZSByZXNvdXJjZSB0byB0cmFuc2l0aW9uIHRvIHRoZQogICAgICAgICAgbG9ja2VkIHN0YXRlLiI7CiAgICAgIH0KICAgIH0KICB9CgogIHR5cGVkZWYgQXZhaWxhYmlsaXR5U3RhdHVzIHsKICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICBlbnVtIElOX1RFU1Q7CiAgICAgICAgICBlbnVtIEZBSUxFRDsKICAgICAgICAgIGVudW0gUE9XRVJfT0ZGOwogICAgICAgICAgZW51bSBPRkZfTElORTsKICAgICAgICAgIGVudW0gT0ZGX0RVVFk7CiAgICAgICAgICBlbnVtIERFUEVOREVOQ1k7CiAgICAgICAgICBlbnVtIERFR1JBREVEOwogICAgICAgICAgZW51bSBOT1RfSU5TVEFMTEVEOwogICAgICAgICAgZW51bSBMT0dfRlVMTDsKICAgICAgIH0KICB9CgogIHR5cGVkZWYgQ2VsbFN0YXRlIHsKICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgZW51bSBJRExFOwogICAgICAgIGVudW0gSU5BQ1RJVkU7CiAgICAgICAgZW51bSBBQ1RJVkU7CiAgICAgfQogIH0KCiAgdHlwZWRlZiBOcnBjaSB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uICJQaHlzaWNhbCBDZWxsIElkZW50aXR5IChQQ0kpIG9mIHRoZSBOUiBjZWxsLiI7CiAgICByZWZlcmVuY2UgIlRTIDM2LjIxMSBzdWJjbGF1c2UgNi4xMSI7CiAgfQoKICB0eXBlZGVmIFRhYyB7CiAgICB0eXBlIGludDMyIHsKICAgICAgcmFuZ2UgMC4uMTY3NzcyMTUgOwogICAgfQogICAgZGVzY3JpcHRpb24gIlRyYWNraW5nIEFyZWEgQ29kZSI7CiAgICByZWZlcmVuY2UgIlRTIDIzLjAwMyBjbGF1c2UgMTkuNC4yLjMiOwogIH0KCiAgZ3JvdXBpbmcgVGFpR3JwIHsKICAgIGRlc2NyaXB0aW9uICJUaGlzIDw8ZGF0YVR5cGU+PiBkZWZpbmVzIGEgVHJhY2tpbmcgQXJlYSBJZGVudGl0eSAoVEFJKQogICAgICBhcyBzcGVjaWZpZWQgaW4gY2xhdXNlIDI4LjYgb2YgVFMgMjMuMDAzLCBjbGF1c2UgOC4yIG9mIFRTIDM4LjMwMAogICAgICBhbmQgY2xhdXNlIDkuMy4zLjExIG9mIFRTIDM4LjQxMy4gSXQgaXMgY29tcG9zZWQgb2YgdGhlIFBMTU4KICAgICAgaWRlbnRpZmllciAoUExNTi1JZCwgd2hpY2ggaXMgY29tcG9zZWQgb2YgdGhlIE1DQyBhbmQgTU5DKSBhbmQKICAgICAgdGhlIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKS4gIjsKICAgIGxpc3QgcGxtbklkIHsKICAgICAgZGVzY3JpcHRpb24gIlBMTU4gSWRlbnRpdHkuIjsKICAgICAgbWluLWVsZW1lbnRzIDE7CiAgICAgIG1heC1lbGVtZW50cyAxOwogICAgICBrZXkgIm1jYyBtbmMiOwogICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICB9CgogICAgbGVhZiB0YWMgeyB0eXBlIFRhYzsgfQogIH0KCiAgZ3JvdXBpbmcgR2VvQ29vcmRpbmF0ZUdycCB7CiAgICBkZXNjcmlwdGlvbiAiR2VvZ3JhcGhpY2FsIGxvY2F0aW9uIG9uIGVhcnRoIjsKICAgIGxlYWYgbGF0aXR1ZGUgewogICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDQ7CiAgICAgICAgcmFuZ2UgLTkwLi45MCA7CiAgICAgIH0KICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgIGRlc2NyaXB0aW9uICJMYXRpdHVkZSBiYXNlZCBvbiBXb3JsZCBHZW9kZXRpYyBTeXN0ZW0gKDE5ODQgdmVyc2lvbikKICAgICAgICBnbG9iYWwgcmVmZXJlbmNlIGZyYW1lIChXR1MgODQpLiBQb3NpdGl2ZSB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUKICAgICAgICBub3J0aGVybiBoZW1pc3BoZXJlLiI7CiAgICAgIH0KCiAgICBsZWFmIGxvbmdpdHVkZSB7CiAgICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNDsKICAgICAgICByYW5nZSAtMTgwLi4xODAgOwogICAgICB9CiAgICAgIG1hbmRhdG9yeSB0cnVlOwogICAgICBkZXNjcmlwdGlvbiAiTG9uZ2l0dWRlIGJhc2VkIG9uIFdvcmxkIEdlb2RldGljIFN5c3RlbSAoMTk4NCB2ZXJzaW9uKQogICAgICAgIGdsb2JhbCByZWZlcmVuY2UgZnJhbWUgKFdHUyA4NCkuIFBvc2l0aXZlIHZhbHVlcyBjb3JyZXNwb25kIHRvCiAgICAgICAgZGVncmVlcyBlYXN0IG9mIDAgZGVncmVlcyBsb25naXR1ZGUuIjsKICAgIH0KICB9CgogIGdyb3VwaW5nIEdlb0FyZWFHcnAgewogICAgZGVzY3JpcHRpb24gIlRoaXMgZGF0YSB0eXBlIGRlZmluZXMgYSBnZW9ncmFwaGljYWwgYXJlYS4KICAgICAgVGhlIGdlby1hcmVhIGlzIGRlZmluZWQgdXNpbmcgYSBjb252ZXggcG9seWdvbiBpbiB0aGUgYXR0cmlidXRlCiAgICAgICdjb252ZXhHZW9Qb2x5Z29uJy4iOwoKICAgIGxpc3QgY29udmV4R2VvUG9seWdvbiB7CiAgICAgIGRlc2NyaXB0aW9uICJTcGVjaWZpZXMgdGhlIGdlb2dyYXBoaWNhbCBhcmVhIHdpdGggYSBjb252ZXggcG9seWdvbi4KICAgICAgICBUaGUgY29udmV4IHBvbHlnb24gaXMgc3BlY2lmaWVkIGJ5IGl0cyBjb3JuZXJzLiI7CiAgICAgICAga2V5ICJsYXRpdHVkZSBsb25naXR1ZGUiOwogICAgICBtaW4tZWxlbWVudHMgMzsKICAgICAgb3JkZXJlZC1ieSB1c2VyOwoKICAgICAgdXNlcyBHZW9Db29yZGluYXRlR3JwOwogICAgfQogIH0KCiAgdHlwZWRlZiBBbWZSZWdpb25JZCB7CiAgICB0eXBlIHVuaW9uIHsKICAgICAgdHlwZSB1aW50OCA7CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggODsKICAgICAgICBwYXR0ZXJuICdbMDFdKic7CiAgICAgIH0KICAgIH0KICAgIHJlZmVyZW5jZSAiY2xhdXNlIDIuMTAuMSBvZiAzR1BQIFRTIDIzLjAwMyI7CiAgfQoKICB0eXBlZGVmIEFtZlNldElkIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIHVpbnQxNiB7CiAgICAgICAgcmFuZ2UgJzAuLjEwMjMnOwogICAgICB9CiAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICBsZW5ndGggODsKICAgICAgICBwYXR0ZXJuICdbMDFdKic7CiAgICAgIH0KICAgIH0KICAgIHJlZmVyZW5jZSAiY2xhdXNlIDIuMTAuMSBvZiAzR1BQIFRTIDIzLjAwMyI7CiAgfQoKICB0eXBlZGVmIEFtZlBvaW50ZXIgewogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgdWludDggewogICAgICAgIHJhbmdlICcwLi42Myc7CiAgICAgIH0KICAgICAgdHlwZSBzdHJpbmcgewogICAgICAgIGxlbmd0aCA2OwogICAgICAgIHBhdHRlcm4gJ1swMV0qJzsKICAgICAgfQogICAgfQogICAgcmVmZXJlbmNlICJjbGF1c2UgMi4xMC4xIG9mIDNHUFAgVFMgMjMuMDAzIjsKICB9CgogIGdyb3VwaW5nIEFtZklkZW50aWZpZXIgewogICAgbGVhZiBhbWZSZWdpb25JZCB7CiAgICAgIHR5cGUgQW1mUmVnaW9uSWQ7CiAgICB9CiAgICBsZWFmIGFtZlNldElkIHsKICAgICAgdHlwZSBBbWZTZXRJZDsKICAgIH0KICAgIGxlYWYgYW1mUG9pbnRlciB7CiAgICAgIHR5cGUgQW1mUG9pbnRlcjsKICAgIH0KICAgIGRlc2NyaXB0aW9uICJUaGUgQU1GSSBpcyBjb25zdHJ1Y3RlZCBmcm9tIGFuIEFNRiBSZWdpb24gSUQsCiAgICAgIGFuIEFNRiBTZXQgSUQgYW5kIGFuIEFNRiBQb2ludGVyLgogICAgICBUaGUgQU1GIFJlZ2lvbiBJRCBpZGVudGlmaWVzIHRoZSByZWdpb24sCiAgICAgIHRoZSBBTUYgU2V0IElEIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIEFNRiBTZXQgd2l0aGluIHRoZSBBTUYgUmVnaW9uLCBhbmQKICAgICAgdGhlIEFNRiBQb2ludGVyIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIEFNRiB3aXRoaW4gdGhlIEFNRiBTZXQuICI7CiAgfQoKLy8gdHlwZSBkZWZpbml0aW9ucyBlc3BlY2lhbGx5IGZvciBjb3JlIE5GcwoKICB0eXBlZGVmIE5mVHlwZSB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBOUkY7CiAgICAgIGVudW0gVURNOwogICAgICBlbnVtIEFNRjsKICAgICAgZW51bSBTTUY7CiAgICAgIGVudW0gQVVTRjsKICAgICAgZW51bSBORUY7CiAgICAgIGVudW0gUENGOwogICAgICBlbnVtIFNNU0Y7CiAgICAgIGVudW0gTlNTRjsKICAgICAgZW51bSBVRFI7CiAgICAgIGVudW0gTE1GOwogICAgICBlbnVtIEdNTEM7CiAgICAgIGVudW0gNUdfRUlSOwogICAgICBlbnVtIFNFUFA7CiAgICAgIGVudW0gVVBGOwogICAgICBlbnVtIE4zSVdGOwogICAgICBlbnVtIEFGOwogICAgICBlbnVtIFVEU0Y7CiAgICAgIGVudW0gQlNGOwogICAgICBlbnVtIENIRjsKICAgIH0KICB9CgogIHR5cGVkZWYgTm90aWZpY2F0aW9uVHlwZSB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBOMV9NRVNTQUdFUzsKICAgICAgZW51bSBOMl9JTkZPUk1BVElPTjsKICAgICAgZW51bSBMT0NBVElPTl9OT1RJRklDQVRJT047CiAgICB9CiAgfQoKICB0eXBlZGVmIExvYWQgewogICAgZGVzY3JpcHRpb24gIkxhdGVzdCBrbm93biBsb2FkIGluZm9ybWF0aW9uIG9mIHRoZSBORiwgcGVyY2VudGFnZSAiOwogICAgdHlwZSB1aW50OCB7CiAgICAgIHJhbmdlIDAuLjEwMDsKICAgIH0KICB9CgogIHR5cGVkZWYgTjFNZXNzYWdlQ2xhc3MgewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gNUdNTTsKICAgICAgZW51bSBTTTsKICAgICAgZW51bSBMUFA7CiAgICAgIGVudW0gU01TOwogICAgfQogIH0KCiAgdHlwZWRlZiBOMkluZm9ybWF0aW9uQ2xhc3MgewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gU007CiAgICAgIGVudW0gTlJQUEE7CiAgICAgIGVudW0gUFdTOwogICAgICBlbnVtIFBXU19CQ0FMOwogICAgICBlbnVtIFBXU19SRjsKICAgIH0KICB9CgogIGdyb3VwaW5nIERlZmF1bHROb3RpZmljYXRpb25TdWJzY3JpcHRpb24gewoKICAgIGxlYWYgbm90aWZpY2F0aW9uVHlwZSB7CiAgICAgIHR5cGUgTm90aWZpY2F0aW9uVHlwZTsKICAgIH0KCiAgICBsZWFmIGNhbGxiYWNrVXJpIHsKICAgICAgdHlwZSBpbmV0OnVyaTsKICAgIH0KCiAgICBsZWFmIG4xTWVzc2FnZUNsYXNzIHsKICAgICAgdHlwZSBOMU1lc3NhZ2VDbGFzczsKICAgIH0KCiAgICBsZWFmIG4ySW5mb3JtYXRpb25DbGFzcyB7CiAgICAgIHR5cGUgTjJJbmZvcm1hdGlvbkNsYXNzOwogICAgfQogIH0KCiAgZ3JvdXBpbmcgSXB2NEFkZHJlc3NSYW5nZSB7CiAgbGVhZiBzdGFydCB7CiAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzOwogICAgfQogIGxlYWYgZW5kIHsKICAgIHR5cGUgaW5ldDppcHY0LWFkZHJlc3M7CiAgICB9CiAgfQoKICBncm91cGluZyBJcHY2UHJlZml4UmFuZ2UgewogIGxlYWYgc3RhcnQgewogICAgdHlwZSBpbmV0OmlwdjYtcHJlZml4OwogICAgfQogIGxlYWYgZW5kIHsKICAgIHR5cGUgaW5ldDppcHY2LXByZWZpeDsKICAgIH0KICB9CgogIHR5cGVkZWYgTnNpSWQgewogICAgdHlwZSBzdHJpbmc7CiAgfQoKICB0eXBlZGVmIFVlTW9iaWxpdHlMZXZlbCB7CiAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgZW51bSBTVEFUSU9OQVJZOwogICAgICBlbnVtIE5PTUFESUM7CiAgICAgIGVudW0gUkVTVFJJQ1RFRF9NT0JJTElUWTsKICAgICAgZW51bSBGVUxMWV9NT0JJTElUWTsKICAgIH0KICB9CgogIHR5cGVkZWYgUmVzb3VyY2VTaGFyaW5nTGV2ZWwgewogICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICBlbnVtIFNIQVJFRDsKICAgICAgICBlbnVtIE5PVF9TSEFSRUQ7CiAgICAgIH0KICB9CgogIHR5cGVkZWYgVHhEaXJlY3Rpb24gewogICAgICB0eXBlIGVudW1lcmF0aW9uIHsKICAgICAgICBlbnVtIERMOwogICAgICAgIGVudW0gVUw7CiAgICAgICAgZW51bSBETF9BTkRfVUw7CiAgICAgIH0KICB9CgogIGdyb3VwaW5nIEFkZHJlc3NXaXRoVmxhbiB7CiAgICBsZWFmIGlwQWRkcmVzcyB7CiAgICAgIHR5cGUgaW5ldDppcC1hZGRyZXNzOwogICAgfQogICAgbGVhZiB2bGFuSWQgewogICAgICAgdHlwZSB1aW50MTY7CiAgICB9CiAgfQoKICAvKiBEaXN0aW5ndWlzaGVkTmFtZSBwYXR0ZXJuIGlzIGJ1aWx0IHVwIGJhc2VkIG9uIHRoZQogICAgRUJORiBpbiAzMi4zMDAgY2xhdXNlIDcuMyAgRUJORiBvZiBETiBTdHJpbmcgUmVwcmVzZW50YXRpb24KCiAgICBsZWFmIEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vICBTYW1lIHBhdHRlcm4gYXMgTG9jYWxETgogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPygsW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKj0oW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pKic7CiAgICB9IH0KCiAgICBsZWFmIGZ1bGxMb2NhbEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIExvY2FsUkROICwgeyBSRE5TZXBhcmF0b3IgLCBMb2NhbFJETiB9ICAgIFJETlNlcGFyYXRvciBpcyBhIHNpbmdsZSAsIG5vIHNwYWNlIG9yIFxSIGFsbG93ZWQgICBNZS5teWtleT0xIGFsbG93ZWQKICAgICAgLy8gIChmdWxsTG9jYWxSRE4pKCwoZnVsbExvY2FsUkROKSkqCiAgICAgIHBhdHRlcm4gJygoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKikpPSgoW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pKSgsKChbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qfChbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qXC5bYS16XVteLD0rPD4jO1xcIlxyXG4qLl0qKSk9KChbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykpKSonOwogICAgfSB9CgogICAgbGVhZiBMb2NhbEROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIExvY2FsUkROICwgeyBSRE5TZXBhcmF0b3IgLCBMb2NhbFJETiB9ICAgIFJETlNlcGFyYXRvciBpcyBhIHNpbmdsZSAsIG5vIHNwYWNlIG9yIFxSIGFsbG93ZWQKICAgICAgLy8gIExvY2FsUkROKCxMb2NhbFJETikqCiAgICAgIHBhdHRlcm4gJ1tBLVpdW14sPSs8PiM7XFwiXHJcbiouXSo9KFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/KCxbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykqJzsKICAgIH0gfQoKICAgIGxlYWYgZnVsbExvY2FsUkROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIHNhbWUgYXMgZnVsbExvY2FsRE5BdHRyaWJ1dGVUeXBlQW5kVmFsdWUKICAgICAgcGF0dGVybiAnKFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSp8KFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSpcLlthLXpdW14sPSs8PiM7XFwiXHJcbiouXSopKT0oKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/KSc7CiAgICB9IH0KCiAgICBsZWFmIExvY2FsUkROIHsgdHlwZSBzdHJpbmcgeyAgIC8vIHNhbWUgYXMgTG9jYWxETkF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPyc7CiAgICB9IH0KCiAgICBsZWFmIGZ1bGxMb2NhbEROQXR0cmlidXRlVHlwZUFuZFZhbHVlIHsgdHlwZSBzdHJpbmcgeyAvLyBMb2NhbEROQXR0cmlidXRlVHlwZSAsIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZVNlcGFyYXRvciAsIFJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICAvLyBwYXR0ZXJuIExvY2FsRE5BdHRyaWJ1dGVUeXBlPVJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICBwYXR0ZXJuICcoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKikpPSgoW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSooW14sPSs8PiM7XFwiXHJcbiogXXwoXFxbYS1mQS1GMC05XXsyfSkpKT8pJzsKICAgIH0gfQoKICAgICAgLy8gbGltaXRhdGlvbjogTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlbm90IHN1cHBvcnRlZCBNZS5teWtleT0xCiAgICBsZWFmIExvY2FsRE5BdHRyaWJ1dGVUeXBlQW5kVmFsdWUgeyB0eXBlIHN0cmluZyB7CiAgICAgIC8vIGVibmYxICAgICAgICAgIExvY2FsRE5BdHRyaWJ1dGVUeXBlICwgQXR0cmlidXRlVHlwZUFuZFZhbHVlU2VwYXJhdG9yICwgUmVndWxhckF0dHJpYnV0ZVZhbHVlCiAgICAgIC8vIGVibmYyLWxpbWl0ZWQgIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlICwgQXR0cmlidXRlVHlwZUFuZFZhbHVlU2VwYXJhdG9yICwgUmVndWxhckF0dHJpYnV0ZVZhbHVlCiAgICAgIC8vIHBhdHRlcm4gICAgICAgIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlPVJlZ3VsYXJBdHRyaWJ1dGVWYWx1ZQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qPShbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKihbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPyc7CiAgICB9IH0KCiAgICBsZWFmIExvY2FsRE5BdHRyaWJ1dGVUeXBlIHsgdHlwZSBzdHJpbmcgeyAgIC8vIE5hbWVPZkNsYXNzV2l0aElkQXR0cmlidXRlIHwgTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlICBSRE5TZXBhcmF0b3IgaXMgYSBzaW5nbGUgLCBubyBzcGFjZSBvciBcUiBhbGxvd2VkCiAgICAgIC8vICBOYW1lT2ZDbGFzc1dpdGhJZEF0dHJpYnV0ZXxOYW1lc09mQ2xhc3NBbmROYW1pbmdBdHRyaWJ1dGUKICAgICAgcGF0dGVybiAnW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKnwoW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKlwuW2Etel1bXiw9Kzw+IztcXCJcclxuKi5dKiknOwogICAgfSB9CgogICAgbGVhZiBSZWd1bGFyQXR0cmlidXRlVmFsdWUgeyB0eXBlIHN0cmluZyB7ICAgICAgIC8vICggQXR0cmlidXRlVmFsdWVDaGFyIC0gU3BhY2VDaGFyICkgLCBbIHsgQXR0cmlidXRlVmFsdWVDaGFyIH0gLCAoIEF0dHJpYnV0ZVZhbHVlQ2hhciAtIFNwYWNlQ2hhciApIF0KICAgICAgcGF0dGVybiAnKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSgoW14sPSs8PiM7XFwiXHJcbipdfChcXFthLWZBLUYwLTldezJ9KSkqKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/JyA7CiAgICB9IH0KCiAgICBsZWFmIE5hbWVzT2ZDbGFzc0FuZE5hbWluZ0F0dHJpYnV0ZSAgeyB0eXBlIHN0cmluZyB7ICAvLyBDbGFzc05hbWUgLCBDbGFzc05hbWluZ0F0dHJpYnV0ZVNlcGFyYXRvciAsIE5hbWluZ0F0dHJpYnV0ZU5hbWUKICAgICAgLy8gcGF0dGVybjogQ2xhc3NOYW1lXC5OYW1pbmdBdHRyaWJ1dGVOYW1lCiAgICAgIHBhdHRlcm4gJ1tBLVpdW14sPSs8PiM7XFwiXHJcbiouXSpcLlthLXpdW14sPSs8PiM7XFwiXHJcbiouXSonIDsKICAgIH0gfQoKICAgIGxlYWYgcmVzdHJpY3RpdmVDbGFzc05hbWUgeyB0eXBlIHN0cmluZyB7ICAgICAvLwogICAgICBwYXR0ZXJuICdbYS16QS1aXVthLXpBLVowLTktX10qJyA7CiAgICB9IH0KCiAgICBsZWFmIENsYXNzTmFtZSB7IHR5cGUgc3RyaW5nIHsgICAgIC8vIENhcGl0YWxMZXR0ZXJDaGFyICwgeyBMb2NhbEROQXR0cmlidXRlVHlwZUNoYXIgfQogICAgICBwYXR0ZXJuICdbQS1aXVteLD0rPD4jO1xcIlxyXG4qLl0qJyA7CiAgICB9IH0KCiAgICBsZWFmIE5hbWluZ0F0dHJpYnV0ZU5hbWUgeyB0eXBlIHN0cmluZyB7ICAgLy8gU21hbGxMZXR0ZXJDaGFyICwgeyBMb2NhbEROQXR0cmlidXRlVHlwZUNoYXIgfQogICAgICBwYXR0ZXJuICdbYS16XVteLD0rPD4jO1xcIlxyXG4qLl0qJyA7CiAgICB9IH0KCiAgKi8KICB0eXBlZGVmIERpc3Rpbmd1aXNoZWROYW1lIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnW0EtWl1bXiw9Kzw+IztcXCJcclxuKi5dKj0oW14sPSs8PiM7XFwiXHJcbiogXXwnCiAgICAgICsgJyhcXFthLWZBLUYwLTldezJ9KSkoKFteLD0rPD4jO1xcIlxyXG4qXXwoXFxbYS1mQS1GMC05XXsyfSkpKicKICAgICAgKyAnKFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKSk/JwogICAgICArICcoLFtBLVpdW14sPSs8PiM7XFwiXHJcbiouXSo9KFteLD0rPD4jO1xcIlxyXG4qIF18KFxcW2EtZkEtRjAtOV17Mn0pKScKICAgICAgKyAnKChbXiw9Kzw+IztcXCJcclxuKl18KFxcW2EtZkEtRjAtOV17Mn0pKSonCiAgICAgICsgJyhbXiw9Kzw+IztcXCJcclxuKiBdfChcXFthLWZBLUYwLTldezJ9KSkpPykqJzsKICAgIH0KICAgIGRlc2NyaXB0aW9uICJSZXByZXNlbnRzIHRoZSAzR1BQIHN0YW5kYXJkIGZvciBEaXN0aW5ndWlzaGVkTmFtZS4KCiAgICAgIExpbWl0YXRpb25zOgogICAgICAtIFJETlNlcGFyYXRvcjogZG9uJ3QgYWxsb3cgU3BhY2VDaGFyIG9yIENhcnJpYWdlUmV0dXJuQ2hhcgogICAgICAtIE51bGxETjogRGlzYWxsb3cgbnVsbEROIHRoYXQgaXMgdGhlIHNhbWUgYXMgbm90IHByb3ZpZGluZyBhIEROCiAgICAgIC0gTmFtZXNPZkNsYXNzQW5kTmFtaW5nQXR0cmlidXRlIGZvcm1hdCBub3QgYWxsb3dlZAogICAgICAgIChlZy4gTWFuYWdlZEVsZW1lbnQubXlrZXk9MzQ1NDM2KSI7CiAgICByZWZlcmVuY2UgICIzR1BQIFRTIDMyLjMwMCI7CiAgfQoKICB0eXBlZGVmIFFPZmZzZXRSYW5nZSAgewogICAgdHlwZSBpbnQ4IHsKICAgICAgcmFuZ2UgIi0yNCB8IC0yMiB8IC0yMCB8IC0xOCB8IC0xNiB8IC0xNCB8IC0xMiB8IC0xMCB8IC04IHwgLTYgfCAiICsKICAgICAgICAiIC01IHwgLTQgfCAtMyB8IC0yIHwgLTEgfCAwIHwgMSB8IDIgfCAzIHwgNCB8IDUgfCA2IHwgOCB8IDEwIHwgIiArCiAgICAgICAgIiAxMiB8IDE0IHwgMTYgfCAxOCB8IDIwIHwgMjIgfCAyNCI7CiAgICB9CiAgICB1bml0cyBkQjsKICB9CgogIGdyb3VwaW5nIFJlcG9ydGluZ0N0cmwgewogICAgY2hvaWNlIHJlcG9ydGluZ0N0cmwgewogICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgZGVzY3JpcHRpb24gIgogICAgICAgIFRoaXMgY2hvaWNlIGRlZmluZXMgdGhlIG1ldGhvZCBmb3IgcmVwb3J0aW5nIGNvbGxlY3RlZCBwZXJmb3JtYW5jZQogICAgICAgIG1ldHJpY3MgdG8gTW5TIGNvbnN1bWVycyBhcyB3ZWxsIGFzIHRoZSBwYXJhbWV0ZXJzIGZvciBjb25maWd1cmluZyB0aGUKICAgICAgICByZXBvcnRpbmcgZnVuY3Rpb24uIEl0IGlzIGEgY2hvaWNlIGJldHdlZW4gdGhlIGNvbnRyb2wgcGFyYW1ldGVyCiAgICAgICAgcmVxdWlyZWQgZm9yIHRoZSByZXBvcnRpbmcgbWV0aG9kcywgd2hvc2UgcHJlc2VuY2Ugc2VsZWN0cyB0aGUKICAgICAgICByZXBvcnRpbmcgbWV0aG9kIGFzIGZvbGxvd3M6CgogICAgICAgIC0gV2hlbiBvbmx5IHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGF0dHJpYnV0ZSBpcyBwcmVzZW50LCB0aGUgTW5TCiAgICAgICAgcHJvZHVjZXIgc2hhbGwgc3RvcmUgZmlsZXMgb24gdGhlIE1uUyBwcm9kdWNlciBhdCBhIGxvY2F0aW9uIHNlbGVjdGVkCiAgICAgICAgYnkgdGhlIE1uUyBwcm9kdWNlciBhbmQsIG9uIGNvbmRpdGlvbiB0aGF0IGFuIGFwcHJvcHJpYXRlIHN1YnNjcmlwdGlvbgogICAgICAgIGlzIGluIHBsYWNlLCBpbmZvcm0gdGhlIE1uUyBjb25zdW1lciBhYm91dCB0aGUgYXZhaWxhYmlsaXR5IG9mIG5ldwogICAgICAgIGZpbGVzIGFuZCB0aGUgZmlsZSBsb2NhdGlvbiB1c2luZyB0aGUgbm90aWZ5RmlsZVJlYWR5IG5vdGlmaWNhdGlvbi4KICAgICAgICBJbiBjYXNlIHRoZSBwcmVwYXJhdGlvbiBvZiBhIGZpbGUgZmFpbHMsICdub3RpZnlGaWxlUHJlcGFyYXRpb25FcnJvcicKICAgICAgICBzaGFsbCBiZSBzZW50IGluc3RlYWQuCgogICAgICAgIC0gV2hlbiB0aGUgJ2ZpbGVSZXBvcnRpbmdQZXJpb2QnIGFuZCAnbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcycKICAgICAgICBhdHRyaWJ1dGVzIGFyZSBwcmVzZW50LCB0aGVuIHRoZSBNblMgcHJvZHVjZXIgc2hhbGwgYmVoYXZlIGxpa2UKICAgICAgICBkZXNjcmliZWQgZm9yIHRoZSBjYXNlIHRoYXQgb25seSB0aGUgJ2ZpbGVSZXBvcnRpbmdQZXJpb2QnIGlzIHByZXNlbnQuCiAgICAgICAgSW4gYWRkaXRpb24sIHRoZSBNblMgcHJvZHVjZXIgc2hhbGwgY3JlYXRlIG9uIGJlaGFsZiBvZiB0aGUgTW5TCiAgICAgICAgY29uc3VtZXIgYSBzdWJzY3JpcHRpb24sIHVzaW5nICdOdGZTdWJzY3JpcHRpb25Db250cm9sJywgZm9yIHRoZQogICAgICAgIG5vdGlmaWNhdGlvbiB0eXBlcyAnbm90aWZ5TU9JQ3JlYXRpb24nIGFuZCAnbm90aWZ5TU9JRGVsZXRpb24nIHJlbGF0ZWQKICAgICAgICB0byB0aGUgJ0ZpbGUnIGluc3RhbmNlcyB0aGF0IHdpbGwgYmUgcHJvZHVjZWQgbGF0ZXIuIEluIGNhc2UgYW4gZXhpc3RpbmcKICAgICAgICBzdWJzY3JpcHRpb24gZG9lcyBhbHJlYWR5IGluY2x1ZGUgdGhlICdGaWxlJyBpbnN0YW5jZXMgdG8gYmUgcHJvZHVjZWQsCiAgICAgICAgbm8gbmV3IHN1YnNjcmlwdGlvbiBzaGFsbCBiZSBjcmVhdGVkLiBUaGUKICAgICAgICAnbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcycgYXR0cmlidXRlIGluIHRoZSBjcmVhdGVkCiAgICAgICAgJ050ZlN1YnNjcmlwdGlvbkNvbnRyb2wnIGluc3RhbmNlIHNoYWxsIGJlIHNldCB0byB0aGUgdmFsdWUgb2YgdGhlCiAgICAgICAgJ25vdGlmaWNhdGlvblJlY2lwaWVudEFkZHJlc3MnIGluIHRoZSByZWxhdGVkICdQZXJmTWV0cmljSm9iJy4gVGhpcwogICAgICAgIGZlYXR1cmUgaXMgY2FsbGVkIGltcGxpY2l0IG5vdGlmaWNhdGlvbiBzdWJzY3JpcHRpb24sIGFzIG9wcG9zZWQgdG8gdGhlCiAgICAgICAgY2FzZSB3aGVyZSB0aGUgTW5TIGNvbnN1bWVyIGNyZWF0ZXMgdGhlIHN1YnNjcmlwdGlvbiAoZXhwbGljaXQKICAgICAgICBub3RpZmljYXRpb24gc3Vic2NyaXB0aW9uKS4gV2hlbiB0aGUgcmVsYXRlZCAnUGVyZk1ldHJpY0pvYicgaXMKICAgICAgICBkZWxldGVkLCB0aGUgJ050ZlN1YnNjcmlwdGlvbkNvbnRyb2wnIGluc3RhbmNlIGNyZWF0ZWQgZHVlIHRvIHRoZQogICAgICAgIHJlcXVlc3QgZm9yIGltcGxpY2l0IHN1YnNjcmlwdGlvbiBzaGFsbCBiZSBkZWxldGVkIGFzIHdlbGwuCgogICAgICAgIC0gV2hlbiBvbmx5IHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGFuZCBmaWxlTG9jYXRpb24gYXR0cmlidXRlcyBhcmUKICAgICAgICBwcmVzZW50LCB0aGUgTW5TIHByb2R1Y2VyIHNoYWxsIHN0b3JlIHRoZSBmaWxlcyBvbiBhIE1uUyBjb25zdW1lciwgdGhhdAogICAgICAgIGNhbiBiZSBhbnkgZW50aXR5IHN1Y2ggYXMgYSBmaWxlIHNlcnZlciwgYXQgdGhlIGxvY2F0aW9uIHNwZWNpZmllZCBieQogICAgICAgIGZpbGVMb2NhdGlvbi4gTm8gbm90aWZpY2F0aW9uIGlzIGVtaXR0ZWQgYnkgdGhlIE1uUyBwcm9kdWNlci4KCiAgICAgICAgLSBXaGVuIG9ubHkgdGhlIHN0cmVhbVRhcmdldCBhdHRyaWJ1dGUgaXMgcHJlc2VudCwgdGhlIE1uUyBwcm9kdWNlcgogICAgICAgIHNoYWxsIHN0cmVhbSB0aGUgZGF0YSB0byB0aGUgbG9jYXRpb24gc3BlY2lmaWVkIGJ5IHN0cmVhbVRhcmdldC4KCiAgICAgICAgRm9yIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2RzIHRoZSBmaWxlUmVwb3J0aW5nUGVyaW9kIGF0dHJpYnV0ZQogICAgICAgIHNwZWNpZmllcyB0aGUgdGltZSB3aW5kb3cgZHVyaW5nIHdoaWNoIGNvbGxlY3RlZCBtZWFzdXJlbWVudHMgYXJlCiAgICAgICAgc3RvcmVkIGludG8gdGhlIHNhbWUgZmlsZSBiZWZvcmUgdGhlIGZpbGUgaXMgY2xvc2VkIGFuZCBhIG5ldyBmaWxlIGlzCiAgICAgICAgb3BlbmVkLiI7CgogICAgICBjYXNlIGZpbGUtYmFzZWQtcmVwb3J0aW5nIHsKICAgICAgICBsZWFmIGZpbGVSZXBvcnRpbmdQZXJpb2QgewogICAgICAgICAgdHlwZSB1aW50MzIgewogICAgICAgICAgICByYW5nZSAxLi5tYXg7CiAgICAgICAgICB9CiAgICAgICAgICB1bml0cyBtaW51dGVzOwogICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgICBkZXNjcmlwdGlvbiAiRm9yIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2QgdGhpcyBpcyB0aGUgdGltZQogICAgICAgICAgICB3aW5kb3cgZHVyaW5nIHdoaWNoIGNvbGxlY3RlZCBtZWFzdXJlbWVudHMgYXJlIHN0b3JlZCBpbnRvIHRoZSBzYW1lCiAgICAgICAgICAgIGZpbGUgYmVmb3JlIHRoZSBmaWxlIGlzIGNsb3NlZCBhbmQgYSBuZXcgZmlsZSBpcyBvcGVuZWQuCiAgICAgICAgICAgIFRoZSB0aW1lLXBlcmlvZCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgdGhlIGdyYW51bGFyaXR5UGVyaW9kLgoKICAgICAgICAgICAgQXBwbGljYWJsZSB3aGVuIHRoZSBmaWxlLWJhc2VkIHJlcG9ydGluZyBtZXRob2QgaXMgc3VwcG9ydGVkLiI7CiAgICAgICAgfQogICAgICAgIGNob2ljZSByZXBvcnRpbmctdGFyZ2V0IHsKICAgICAgICAgIGNhc2UgZmlsZS10YXJnZXQgewogICAgICAgICAgICBsZWFmIGZpbGVMb2NhdGlvbiB7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nIDsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFwcGxpY2FibGUgYW5kIG11c3QgYmUgcHJlc2VudCB3aGVuIHRoZSBmaWxlLWJhc2VkCiAgICAgICAgICAgICAgcmVwb3J0aW5nIG1ldGhvZCBpcyBzdXBwb3J0ZWQsIGFuZCB0aGUgZmlsZXMgYXJlIHN0b3JlZCBvbiB0aGUgTW5TCiAgICAgICAgICAgICAgY29uc3VtZXIuIjsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgY2FzZSBub3RpZmljYXRpb24tdGFyZ2V0IHsKICAgICAgICAgICAgbGVhZiBub3RpZmljYXRpb25SZWNpcGllbnRBZGRyZXNzIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNdXN0IGJlIHByZXNlbnQgd2hlbiB0aGUgbm90aWZpY2F0aW9uLWJhc2VkIHJlcG9ydGluZwogICAgICAgICAgICAgIG1ldGhvZCBpcyBzdXBwb3J0ZWQsIGFuZCB0aGUgdGhlIGZpbGVzIGFyZSBhdmFpbGFibGUgYXMKICAgICAgICAgICAgICBub3RpZmljYXRpb25zIGZvciB0aGUgTW5TIGNvbnN1bWVyIHRvIHN1YnNjcmliZSB0by4iOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgZGVzY3JpcHRpb24gIldoZW4gbmV0aWhlciBmaWxlTG9jYXRpb24gb3Igbm90aWZpY2F0aW9uUmVjaXBpZW50QWRkcmVzcwogICAgICAgICAgYXJlIHByZXNlbnQsIHRoZSBmaWxlcyBhcmUgc3RvcmVkIGFuZCBhdmFpbGFibGUgdG8gdGhlIE1uUyBjb25zdW1lcgogICAgICAgICAgaWYgdGhlIE1uUyBzdWJzY3JpYmVzIHRvIHRoZSBub3RpZnlGaWxlUmVhZHkgbm90aWZpY2F0aW9uLiI7CiAgICAgICAgfQogICAgICB9CgogICAgICBjYXNlIHN0cmVhbS1iYXNlZC1yZXBvcnRpbmcgewogICAgICAgIGxlYWYgc3RyZWFtVGFyZ2V0IHsKICAgICAgICAgIHR5cGUgc3RyaW5nOwogICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgICBkZXNjcmlwdGlvbiAiQXBwbGljYWJsZSB3aGVuIHN0cmVhbS1iYXNlZCByZXBvcnRpbmcgbWV0aG9kIGlzCiAgICAgICAgICAgIHN1cHBvcnRlZC4iOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQo=
+ietf-geo-location      urn:ietf:params:xml:ns:yang:ietf-geo-location   \N      []      2022-02-11      bW9kdWxlIGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjppZXRmOnBhcmFtczp4bWw6bnM6eWFuZzppZXRmLWdlby1sb2NhdGlvbiI7CiAgICBwcmVmaXggZ2VvOwogICAgaW1wb3J0IGlldGYteWFuZy10eXBlcyB7CiAgICBwcmVmaXggeWFuZzsKICAgIHJlZmVyZW5jZSAiUkZDIDY5OTE6IENvbW1vbiBZQU5HIERhdGEgVHlwZXMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbgogICAgIklFVEYgTkVUTU9EIFdvcmtpbmcgR3JvdXAgKE5FVE1PRCkiOwogICAgY29udGFjdAogICAgIldHIFdlYjogICA8aHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy93Zy9uZXRtb2QvPgogICAgV0cgTGlzdDogIDxtYWlsdG86bmV0bW9kQGlldGYub3JnPgoKICAgIEVkaXRvcjogICBDaHJpc3RpYW4gSG9wcHMKICAgICAgICAgICAgICAgIDxtYWlsdG86Y2hvcHBzQGNob3Bwcy5vcmc+IjsKCiAgICBkZXNjcmlwdGlvbgogICAgIlRoaXMgbW9kdWxlIGRlZmluZXMgYSBncm91cGluZyBvZiBhIGNvbnRhaW5lciBvYmplY3QgZm9yCiAgICBzcGVjaWZ5aW5nIGEgbG9jYXRpb24gb24gb3IgYXJvdW5kIGFuIGFzdHJvbm9taWNhbCBvYmplY3QgKGUuZy4sCiAgICAnZWFydGgnKS4KCiAgICBUaGUga2V5IHdvcmRzICdNVVNUJywgJ01VU1QgTk9UJywgJ1JFUVVJUkVEJywgJ1NIQUxMJywgJ1NIQUxMCiAgICBOT1QnLCAnU0hPVUxEJywgJ1NIT1VMRCBOT1QnLCAnUkVDT01NRU5ERUQnLCAnTk9UIFJFQ09NTUVOREVEJywKICAgICdNQVknLCBhbmQgJ09QVElPTkFMJyBpbiB0aGlzIGRvY3VtZW50IGFyZSB0byBiZSBpbnRlcnByZXRlZCBhcwogICAgZGVzY3JpYmVkIGluIEJDUCAxNCAoUkZDIDIxMTkpIChSRkMgODE3NCkgd2hlbiwgYW5kIG9ubHkgd2hlbiwKICAgIHRoZXkgYXBwZWFyIGluIGFsbCBjYXBpdGFscywgYXMgc2hvd24gaGVyZS4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjIgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3JtcywKICAgIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywKICAgIGFuZCBzdWJqZWN0IHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlCiAgICBSZXZpc2VkIEJTRCBMaWNlbnNlIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUKICAgIElFVEYgVHJ1c3QncyBMZWdhbCBQcm92aXNpb25zIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cHM6Ly90cnVzdGVlLmlldGYub3JnL2xpY2Vuc2UtaW5mbykuCgogICAgVGhpcyB2ZXJzaW9uIG9mIHRoaXMgWUFORyBtb2R1bGUgaXMgcGFydCBvZiBSRkMgOTE3OQogICAgKGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL2luZm8vcmZjOTE3OSk7IHNlZSB0aGUgUkZDIGl0c2VsZgogICAgZm9yIGZ1bGwgbGVnYWwgbm90aWNlcy4iOwoKICAgIHJldmlzaW9uIDIwMjItMDItMTEgewogICAgZGVzY3JpcHRpb24KICAgICAgICAiSW5pdGlhbCBSZXZpc2lvbiI7CiAgICByZWZlcmVuY2UKICAgICAgICAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIGZlYXR1cmUgYWx0ZXJuYXRlLXN5c3RlbXMgewogICAgZGVzY3JpcHRpb24KICAgICAgICAiVGhpcyBmZWF0dXJlIG1lYW5zIHRoZSBkZXZpY2Ugc3VwcG9ydHMgc3BlY2lmeWluZyBsb2NhdGlvbnMKICAgICAgICB1c2luZyBhbHRlcm5hdGUgc3lzdGVtcyBmb3IgcmVmZXJlbmNlIGZyYW1lcy4iOwogICAgfQoKICAgIGdyb3VwaW5nIGdlby1sb2NhdGlvbiB7CiAgICBkZXNjcmlwdGlvbgogICAgICAgICJHcm91cGluZyB0byBpZGVudGlmeSBhIGxvY2F0aW9uIG9uIGFuIGFzdHJvbm9taWNhbCBvYmplY3QuIjsKCiAgICBjb250YWluZXIgZ2VvLWxvY2F0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICJBIGxvY2F0aW9uIG9uIGFuIGFzdHJvbm9taWNhbCBib2R5IChlLmcuLCAnZWFydGgnKQogICAgICAgIHNvbWV3aGVyZSBpbiBhIHVuaXZlcnNlLiI7CgogICAgICAgIGNvbnRhaW5lciByZWZlcmVuY2UtZnJhbWUgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgRnJhbWUgb2YgUmVmZXJlbmNlIGZvciB0aGUgbG9jYXRpb24gdmFsdWVzLiI7CgogICAgICAgIGxlYWYgYWx0ZXJuYXRlLXN5c3RlbSB7CiAgICAgICAgICAgIGlmLWZlYXR1cmUgImFsdGVybmF0ZS1zeXN0ZW1zIjsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgc3lzdGVtIGluIHdoaWNoIHRoZSBhc3Ryb25vbWljYWwgYm9keSBhbmQKICAgICAgICAgICAgZ2VvZGV0aWMtZGF0dW0gaXMgZGVmaW5lZC4gIE5vcm1hbGx5LCB0aGlzIHZhbHVlIGlzIG5vdAogICAgICAgICAgICBwcmVzZW50IGFuZCB0aGUgc3lzdGVtIGlzIHRoZSBuYXR1cmFsIHVuaXZlcnNlOyBob3dldmVyLAogICAgICAgICAgICB3aGVuIHByZXNlbnQsIHRoaXMgdmFsdWUgYWxsb3dzIGZvciBzcGVjaWZ5aW5nIGFsdGVybmF0ZQogICAgICAgICAgICBzeXN0ZW1zIChlLmcuLCB2aXJ0dWFsIHJlYWxpdGllcykuICBBbiBhbHRlcm5hdGUtc3lzdGVtCiAgICAgICAgICAgIG1vZGlmaWVzIHRoZSBkZWZpbml0aW9uIChidXQgbm90IHRoZSB0eXBlKSBvZiB0aGUgb3RoZXIKICAgICAgICAgICAgdmFsdWVzIGluIHRoZSByZWZlcmVuY2UgZnJhbWUuIjsKICAgICAgICB9CiAgICAgICAgbGVhZiBhc3Ryb25vbWljYWwtYm9keSB7CiAgICAgICAgICAgIHR5cGUgc3RyaW5nIHsKICAgICAgICAgICAgcGF0dGVybiAnWyAtQFxbLVxeXy1+XSonOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQgImVhcnRoIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIkFuIGFzdHJvbm9taWNhbCBib2R5IGFzIG5hbWVkIGJ5IHRoZSBJbnRlcm5hdGlvbmFsCiAgICAgICAgICAgIEFzdHJvbm9taWNhbCBVbmlvbiAoSUFVKSBvciBhY2NvcmRpbmcgdG8gdGhlIGFsdGVybmF0ZQogICAgICAgICAgICBzeXN0ZW0gaWYgc3BlY2lmaWVkLiAgRXhhbXBsZXMgaW5jbHVkZSAnc3VuJyAob3VyIHN0YXIpLAogICAgICAgICAgICAnZWFydGgnIChvdXIgcGxhbmV0KSwgJ21vb24nIChvdXIgbW9vbiksICdlbmNlbGFkdXMnIChhCiAgICAgICAgICAgIG1vb24gb2YgU2F0dXJuKSwgJ2NlcmVzJyAoYW4gYXN0ZXJvaWQpLCBhbmQKICAgICAgICAgICAgJzY3cC9jaHVyeXVtb3YtZ2VyYXNpbWVua28gKGEgY29tZXQpLiAgVGhlIEFTQ0lJIHZhbHVlCiAgICAgICAgICAgIFNIT1VMRCBoYXZlIHVwcGVyY2FzZSBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlIGFuZCBub3QKICAgICAgICAgICAgaW5jbHVkZSBjb250cm9sIGNoYXJhY3RlcnMgKGkuZS4sIHZhbHVlcyAzMi4uNjQsIGFuZAogICAgICAgICAgICA5MS4uMTI2KS4gIEFueSBwcmVjZWRpbmcgJ3RoZScgaW4gdGhlIG5hbWUgU0hPVUxEIE5PVCBiZQogICAgICAgICAgICBpbmNsdWRlZC4iOwogICAgICAgICAgICByZWZlcmVuY2UKICAgICAgICAgICAgImh0dHBzOi8vd3d3LmlhdS5vcmcvIjsKICAgICAgICB9CiAgICAgICAgY29udGFpbmVyIGdlb2RldGljLXN5c3RlbSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgZ2VvZGV0aWMgc3lzdGVtIG9mIHRoZSBsb2NhdGlvbiBkYXRhLiI7CiAgICAgICAgICAgIGxlYWYgZ2VvZGV0aWMtZGF0dW0gewogICAgICAgICAgICB0eXBlIHN0cmluZyB7CiAgICAgICAgICAgICAgICBwYXR0ZXJuICdbIC1AXFstXF5fLX5dKic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJBIGdlb2RldGljLWRhdHVtIGRlZmluaW5nIHRoZSBtZWFuaW5nIG9mIGxhdGl0dWRlLAogICAgICAgICAgICAgICAgbG9uZ2l0dWRlLCBhbmQgaGVpZ2h0LiAgVGhlIGRlZmF1bHQgd2hlbiB0aGUKICAgICAgICAgICAgICAgIGFzdHJvbm9taWNhbCBib2R5IGlzICdlYXJ0aCcgaXMgJ3dncy04NCcsIHdoaWNoIGlzCiAgICAgICAgICAgICAgICB1c2VkIGJ5IHRoZSBHbG9iYWwgUG9zaXRpb25pbmcgU3lzdGVtIChHUFMpLiAgVGhlCiAgICAgICAgICAgICAgICBBU0NJSSB2YWx1ZSBTSE9VTEQgaGF2ZSB1cHBlcmNhc2UgY29udmVydGVkIHRvCiAgICAgICAgICAgICAgICBsb3dlcmNhc2UgYW5kIG5vdCBpbmNsdWRlIGNvbnRyb2wgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgKGkuZS4sIHZhbHVlcyAzMi4uNjQsIGFuZCA5MS4uMTI2KS4gIFRoZSBJQU5BIHJlZ2lzdHJ5CiAgICAgICAgICAgICAgICBmdXJ0aGVyIHJlc3RyaWN0cyB0aGUgdmFsdWUgYnkgY29udmVydGluZyBhbGwgc3BhY2VzCiAgICAgICAgICAgICAgICAoJyAnKSB0byBkYXNoZXMgKCctJykuCiAgICAgICAgICAgICAgICBUaGUgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIGdlb2RldGljLWRhdHVtIGluZGljYXRlcwogICAgICAgICAgICAgICAgaG93IGFjY3VyYXRlbHkgaXQgbW9kZWxzIHRoZSBhc3Ryb25vbWljYWwgYm9keSBpbgogICAgICAgICAgICAgICAgcXVlc3Rpb24sIGJvdGggZm9yIHRoZSAnaG9yaXpvbnRhbCcKICAgICAgICAgICAgICAgIGxhdGl0dWRlL2xvbmdpdHVkZSBjb29yZGluYXRlcyBhbmQgZm9yIGhlaWdodAogICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMuIjsKICAgICAgICAgICAgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMsCiAgICAgICAgICAgICAgICBTZWN0aW9uIDYuMSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGVhZiBjb29yZC1hY2N1cmFjeSB7CiAgICAgICAgICAgIHR5cGUgZGVjaW1hbDY0IHsKICAgICAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyA2OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGFjY3VyYWN5IG9mIHRoZSBsYXRpdHVkZS9sb25naXR1ZGUgcGFpciBmb3IKICAgICAgICAgICAgICAgIGVsbGlwc29pZGFsIGNvb3JkaW5hdGVzLCBvciB0aGUgWCwgWSwgYW5kIFogY29tcG9uZW50cwogICAgICAgICAgICAgICAgZm9yIENhcnRlc2lhbiBjb29yZGluYXRlcy4gIFdoZW4gY29vcmQtYWNjdXJhY3kgaXMKICAgICAgICAgICAgICAgIHNwZWNpZmllZCwgaXQgaW5kaWNhdGVzIGhvdyBwcmVjaXNlbHkgdGhlIGNvb3JkaW5hdGVzCiAgICAgICAgICAgICAgICBpbiB0aGUgYXNzb2NpYXRlZCBsaXN0IG9mIGxvY2F0aW9ucyBoYXZlIGJlZW4KICAgICAgICAgICAgICAgIGRldGVybWluZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBjb29yZGluYXRlIHN5c3RlbQogICAgICAgICAgICAgICAgZGVmaW5lZCBieSB0aGUgZ2VvZGV0aWMtZGF0dW0uICBGb3IgZXhhbXBsZSwgdGhlcmUKICAgICAgICAgICAgICAgIG1pZ2h0IGJlIHVuY2VydGFpbnR5IGR1ZSB0byBtZWFzdXJlbWVudCBlcnJvciBpZiBhbgogICAgICAgICAgICAgICAgZXhwZXJpbWVudGFsIG1lYXN1cmVtZW50IHdhcyBtYWRlIHRvIGRldGVybWluZSBlYWNoCiAgICAgICAgICAgICAgICBsb2NhdGlvbi4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlYWYgaGVpZ2h0LWFjY3VyYWN5IHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGFjY3VyYWN5IG9mIHRoZSBoZWlnaHQgdmFsdWUgZm9yIGVsbGlwc29pZGFsCiAgICAgICAgICAgICAgICBjb29yZGluYXRlczsgdGhpcyB2YWx1ZSBpcyBub3QgdXNlZCB3aXRoIENhcnRlc2lhbgogICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMuICBXaGVuIGhlaWdodC1hY2N1cmFjeSBpcyBzcGVjaWZpZWQsIGl0CiAgICAgICAgICAgICAgICBpbmRpY2F0ZXMgaG93IHByZWNpc2VseSB0aGUgaGVpZ2h0cyBpbiB0aGUKICAgICAgICAgICAgICAgIGFzc29jaWF0ZWQgbGlzdCBvZiBsb2NhdGlvbnMgaGF2ZSBiZWVuIGRldGVybWluZWQKICAgICAgICAgICAgICAgIHdpdGggcmVzcGVjdCB0byB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0gZGVmaW5lZCBieSB0aGUKICAgICAgICAgICAgICAgIGdlb2RldGljLWRhdHVtLiAgRm9yIGV4YW1wbGUsIHRoZXJlIG1pZ2h0IGJlCiAgICAgICAgICAgICAgICB1bmNlcnRhaW50eSBkdWUgdG8gbWVhc3VyZW1lbnQgZXJyb3IgaWYgYW4KICAgICAgICAgICAgICAgIGV4cGVyaW1lbnRhbCBtZWFzdXJlbWVudCB3YXMgbWFkZSB0byBkZXRlcm1pbmUgZWFjaAogICAgICAgICAgICAgICAgbG9jYXRpb24uIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2hvaWNlIGxvY2F0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhlIGxvY2F0aW9uIGRhdGEgZWl0aGVyIGluIGxhdGl0dWRlL2xvbmdpdHVkZSBvcgogICAgICAgICAgICBDYXJ0ZXNpYW4gdmFsdWVzIjsKICAgICAgICBjYXNlIGVsbGlwc29pZCB7CiAgICAgICAgICAgIGxlYWYgbGF0aXR1ZGUgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgImRlY2ltYWwgZGVncmVlcyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGxhdGl0dWRlIHZhbHVlIG9uIHRoZSBhc3Ryb25vbWljYWwgYm9keS4gIFRoZQogICAgICAgICAgICAgICAgZGVmaW5pdGlvbiBhbmQgcHJlY2lzaW9uIG9mIHRoaXMgbWVhc3VyZW1lbnQgaXMKICAgICAgICAgICAgICAgIGluZGljYXRlZCBieSB0aGUgcmVmZXJlbmNlLWZyYW1lLiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGVhZiBsb25naXR1ZGUgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgImRlY2ltYWwgZGVncmVlcyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiVGhlIGxvbmdpdHVkZSB2YWx1ZSBvbiB0aGUgYXN0cm9ub21pY2FsIGJvZHkuICBUaGUKICAgICAgICAgICAgICAgIGRlZmluaXRpb24gYW5kIHByZWNpc2lvbiBvZiB0aGlzIG1lYXN1cmVtZW50IGlzCiAgICAgICAgICAgICAgICBpbmRpY2F0ZWQgYnkgdGhlIHJlZmVyZW5jZS1mcmFtZS4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlYWYgaGVpZ2h0IHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICAgICAiSGVpZ2h0IGZyb20gYSByZWZlcmVuY2UgMCB2YWx1ZS4gIFRoZSBwcmVjaXNpb24gYW5kCiAgICAgICAgICAgICAgICAnMCcgdmFsdWUgaXMgZGVmaW5lZCBieSB0aGUgcmVmZXJlbmNlLWZyYW1lLiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2FzZSBjYXJ0ZXNpYW4gewogICAgICAgICAgICBsZWFmIHggewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWCB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWFmIHkgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWSB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWFmIHogewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgNjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgICAgICJUaGUgWiB2YWx1ZSBhcyBkZWZpbmVkIGJ5IHRoZSByZWZlcmVuY2UtZnJhbWUuIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29udGFpbmVyIHZlbG9jaXR5IHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiSWYgdGhlIG9iamVjdCBpcyBpbiBtb3Rpb24sIHRoZSB2ZWxvY2l0eSB2ZWN0b3IgZGVzY3JpYmVzCiAgICAgICAgICAgIHRoaXMgbW90aW9uIGF0IHRoZSB0aW1lIGdpdmVuIGJ5IHRoZSB0aW1lc3RhbXAuICBGb3IgYQogICAgICAgICAgICBmb3JtdWxhIHRvIGNvbnZlcnQgdGhlc2UgdmFsdWVzIHRvIHNwZWVkIGFuZCBoZWFkaW5nLCBzZWUKICAgICAgICAgICAgUkZDIDkxNzkuIjsKICAgICAgICByZWZlcmVuY2UKICAgICAgICAgICAgIlJGQyA5MTc5OiBBIFlBTkcgR3JvdXBpbmcgZm9yIEdlb2dyYXBoaWMgTG9jYXRpb25zIjsKCiAgICAgICAgbGVhZiB2LW5vcnRoIHsKICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjQgewogICAgICAgICAgICBmcmFjdGlvbi1kaWdpdHMgMTI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pdHMgIm1ldGVycyBwZXIgc2Vjb25kIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgInYtbm9ydGggaXMgdGhlIHJhdGUgb2YgY2hhbmdlIChpLmUuLCBzcGVlZCkgdG93YXJkcwogICAgICAgICAgICB0cnVlIG5vcnRoIGFzIGRlZmluZWQgYnkgdGhlIGdlb2RldGljLXN5c3RlbS4iOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB2LWVhc3QgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyAxMjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIHBlciBzZWNvbmQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAidi1lYXN0IGlzIHRoZSByYXRlIG9mIGNoYW5nZSAoaS5lLiwgc3BlZWQpIHBlcnBlbmRpY3VsYXIKICAgICAgICAgICAgdG8gdGhlIHJpZ2h0IG9mIHRydWUgbm9ydGggYXMgZGVmaW5lZCBieQogICAgICAgICAgICB0aGUgZ2VvZGV0aWMtc3lzdGVtLiI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHYtdXAgewogICAgICAgICAgICB0eXBlIGRlY2ltYWw2NCB7CiAgICAgICAgICAgIGZyYWN0aW9uLWRpZ2l0cyAxMjsKICAgICAgICAgICAgfQogICAgICAgICAgICB1bml0cyAibWV0ZXJzIHBlciBzZWNvbmQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAidi11cCBpcyB0aGUgcmF0ZSBvZiBjaGFuZ2UgKGkuZS4sIHNwZWVkKSBhd2F5IGZyb20gdGhlCiAgICAgICAgICAgIGNlbnRlciBvZiBtYXNzLiI7CiAgICAgICAgfQogICAgICAgIH0KICAgICAgICBsZWFmIHRpbWVzdGFtcCB7CiAgICAgICAgdHlwZSB5YW5nOmRhdGUtYW5kLXRpbWU7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIlJlZmVyZW5jZSB0aW1lIHdoZW4gbG9jYXRpb24gd2FzIHJlY29yZGVkLiI7CiAgICAgICAgfQogICAgICAgIGxlYWYgdmFsaWQtdW50aWwgewogICAgICAgIHR5cGUgeWFuZzpkYXRlLWFuZC10aW1lOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGUgdGltZXN0YW1wIGZvciB3aGljaCB0aGlzIGdlby1sb2NhdGlvbiBpcyB2YWxpZCB1bnRpbC4KICAgICAgICAgICAgSWYgdW5zcGVjaWZpZWQsIHRoZSBnZW8tbG9jYXRpb24gaGFzIG5vIHNwZWNpZmljCiAgICAgICAgICAgIGV4cGlyYXRpb24gdGltZS4iOwogICAgICAgIH0KICAgIH0KICAgIH0KfQo=
+ietf-inet-types        urn:ietf:params:xml:ns:yang:ietf-inet-types     \N      []      2013-07-15      bW9kdWxlIGlldGYtaW5ldC10eXBlcyB7CgogIG5hbWVzcGFjZSAidXJuOmlldGY6cGFyYW1zOnhtbDpuczp5YW5nOmlldGYtaW5ldC10eXBlcyI7CiAgcHJlZml4ICJpbmV0IjsKCiAgb3JnYW5pemF0aW9uCiAgICJJRVRGIE5FVE1PRCAoTkVUQ09ORiBEYXRhIE1vZGVsaW5nIExhbmd1YWdlKSBXb3JraW5nIEdyb3VwIjsKCiAgY29udGFjdAogICAiV0cgV2ViOiAgIDxodHRwOi8vdG9vbHMuaWV0Zi5vcmcvd2cvbmV0bW9kLz4KICAgIFdHIExpc3Q6ICA8bWFpbHRvOm5ldG1vZEBpZXRmLm9yZz4KCiAgICBXRyBDaGFpcjogRGF2aWQgS2Vzc2VucwogICAgICAgICAgICAgIDxtYWlsdG86ZGF2aWQua2Vzc2Vuc0Buc24uY29tPgoKICAgIFdHIENoYWlyOiBKdWVyZ2VuIFNjaG9lbndhZWxkZXIKICAgICAgICAgICAgICA8bWFpbHRvOmouc2Nob2Vud2FlbGRlckBqYWNvYnMtdW5pdmVyc2l0eS5kZT4KCiAgICBFZGl0b3I6ICAgSnVlcmdlbiBTY2hvZW53YWVsZGVyCiAgICAgICAgICAgICAgPG1haWx0bzpqLnNjaG9lbndhZWxkZXJAamFjb2JzLXVuaXZlcnNpdHkuZGU+IjsKCiAgZGVzY3JpcHRpb24KICAgIlRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgY29sbGVjdGlvbiBvZiBnZW5lcmFsbHkgdXNlZnVsIGRlcml2ZWQKICAgIFlBTkcgZGF0YSB0eXBlcyBmb3IgSW50ZXJuZXQgYWRkcmVzc2VzIGFuZCByZWxhdGVkIHRoaW5ncy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTMgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvcgogICAgd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywgYW5kIHN1YmplY3QKICAgIHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlIFNpbXBsaWZpZWQgQlNEIExpY2Vuc2UKICAgIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUgSUVURiBUcnVzdCdzIExlZ2FsIFByb3Zpc2lvbnMKICAgIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cDovL3RydXN0ZWUuaWV0Zi5vcmcvbGljZW5zZS1pbmZvKS4KCiAgICBUaGlzIHZlcnNpb24gb2YgdGhpcyBZQU5HIG1vZHVsZSBpcyBwYXJ0IG9mIFJGQyA2OTkxOyBzZWUKICAgIHRoZSBSRkMgaXRzZWxmIGZvciBmdWxsIGxlZ2FsIG5vdGljZXMuIjsKCiAgcmV2aXNpb24gMjAxMy0wNy0xNSB7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHJldmlzaW9uIGFkZHMgdGhlIGZvbGxvd2luZyBuZXcgZGF0YSB0eXBlczoKICAgICAgLSBpcC1hZGRyZXNzLW5vLXpvbmUKICAgICAgLSBpcHY0LWFkZHJlc3Mtbm8tem9uZQogICAgICAtIGlwdjYtYWRkcmVzcy1uby16b25lIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjk5MTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICByZXZpc2lvbiAyMDEwLTA5LTI0IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgIkluaXRpYWwgcmV2aXNpb24uIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjAyMTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgdHlwZXMgcmVsYXRlZCB0byBwcm90b2NvbCBmaWVsZHMgKioqLwoKICB0eXBlZGVmIGlwLXZlcnNpb24gewogICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgIGVudW0gdW5rbm93biB7CiAgICAgICAgdmFsdWUgIjAiOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICJBbiB1bmtub3duIG9yIHVuc3BlY2lmaWVkIHZlcnNpb24gb2YgdGhlIEludGVybmV0CiAgICAgICAgICBwcm90b2NvbC4iOwogICAgICB9CiAgICAgIGVudW0gaXB2NCB7CiAgICAgICAgdmFsdWUgIjEiOwogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICJUaGUgSVB2NCBwcm90b2NvbCBhcyBkZWZpbmVkIGluIFJGQyA3OTEuIjsKICAgICAgfQogICAgICBlbnVtIGlwdjYgewogICAgICAgIHZhbHVlICIyIjsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAiVGhlIElQdjYgcHJvdG9jb2wgYXMgZGVmaW5lZCBpbiBSRkMgMjQ2MC4iOwogICAgICB9CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHZhbHVlIHJlcHJlc2VudHMgdGhlIHZlcnNpb24gb2YgdGhlIElQIHByb3RvY29sLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIEluZXRWZXJzaW9uIHRleHR1YWwgY29udmVudGlvbiBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgIDc5MTogSW50ZXJuZXQgUHJvdG9jb2wKICAgICAgUkZDIDI0NjA6IEludGVybmV0IFByb3RvY29sLCBWZXJzaW9uIDYgKElQdjYpIFNwZWNpZmljYXRpb24KICAgICAgUkZDIDQwMDE6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIEludGVybmV0IE5ldHdvcmsgQWRkcmVzc2VzIjsKICB9CgogIHR5cGVkZWYgZHNjcCB7CiAgICB0eXBlIHVpbnQ4IHsKICAgICAgcmFuZ2UgIjAuLjYzIjsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBkc2NwIHR5cGUgcmVwcmVzZW50cyBhIERpZmZlcmVudGlhdGVkIFNlcnZpY2VzIENvZGUgUG9pbnQKICAgICAgdGhhdCBtYXkgYmUgdXNlZCBmb3IgbWFya2luZyBwYWNrZXRzIGluIGEgdHJhZmZpYyBzdHJlYW0uCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBEc2NwIHRleHR1YWwgY29udmVudGlvbiBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzI4OTogTWFuYWdlbWVudCBJbmZvcm1hdGlvbiBCYXNlIGZvciB0aGUgRGlmZmVyZW50aWF0ZWQKICAgICAgICAgICAgICAgIFNlcnZpY2VzIEFyY2hpdGVjdHVyZQogICAgICBSRkMgMjQ3NDogRGVmaW5pdGlvbiBvZiB0aGUgRGlmZmVyZW50aWF0ZWQgU2VydmljZXMgRmllbGQKICAgICAgICAgICAgICAgIChEUyBGaWVsZCkgaW4gdGhlIElQdjQgYW5kIElQdjYgSGVhZGVycwogICAgICBSRkMgMjc4MDogSUFOQSBBbGxvY2F0aW9uIEd1aWRlbGluZXMgRm9yIFZhbHVlcyBJbgogICAgICAgICAgICAgICAgdGhlIEludGVybmV0IFByb3RvY29sIGFuZCBSZWxhdGVkIEhlYWRlcnMiOwogIH0KCiAgdHlwZWRlZiBpcHY2LWZsb3ctbGFiZWwgewogICAgdHlwZSB1aW50MzIgewogICAgICByYW5nZSAiMC4uMTA0ODU3NSI7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXB2Ni1mbG93LWxhYmVsIHR5cGUgcmVwcmVzZW50cyB0aGUgZmxvdyBpZGVudGlmaWVyIG9yIEZsb3cKICAgICAgTGFiZWwgaW4gYW4gSVB2NiBwYWNrZXQgaGVhZGVyIHRoYXQgbWF5IGJlIHVzZWQgdG8KICAgICAgZGlzY3JpbWluYXRlIHRyYWZmaWMgZmxvd3MuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgSVB2NkZsb3dMYWJlbCB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDM1OTU6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIElQdjYgRmxvdyBMYWJlbAogICAgICBSRkMgMjQ2MDogSW50ZXJuZXQgUHJvdG9jb2wsIFZlcnNpb24gNiAoSVB2NikgU3BlY2lmaWNhdGlvbiI7CiAgfQoKICB0eXBlZGVmIHBvcnQtbnVtYmVyIHsKICAgIHR5cGUgdWludDE2IHsKICAgICAgcmFuZ2UgIjAuLjY1NTM1IjsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBwb3J0LW51bWJlciB0eXBlIHJlcHJlc2VudHMgYSAxNi1iaXQgcG9ydCBudW1iZXIgb2YgYW4KICAgICAgSW50ZXJuZXQgdHJhbnNwb3J0LWxheWVyIHByb3RvY29sIHN1Y2ggYXMgVURQLCBUQ1AsIERDQ1AsIG9yCiAgICAgIFNDVFAuICBQb3J0IG51bWJlcnMgYXJlIGFzc2lnbmVkIGJ5IElBTkEuICBBIGN1cnJlbnQgbGlzdCBvZgogICAgICBhbGwgYXNzaWdubWVudHMgaXMgYXZhaWxhYmxlIGZyb20gPGh0dHA6Ly93d3cuaWFuYS5vcmcvPi4KCiAgICAgIE5vdGUgdGhhdCB0aGUgcG9ydCBudW1iZXIgdmFsdWUgemVybyBpcyByZXNlcnZlZCBieSBJQU5BLiAgSW4KICAgICAgc2l0dWF0aW9ucyB3aGVyZSB0aGUgdmFsdWUgemVybyBkb2VzIG5vdCBtYWtlIHNlbnNlLCBpdCBjYW4KICAgICAgYmUgZXhjbHVkZWQgYnkgc3VidHlwaW5nIHRoZSBwb3J0LW51bWJlciB0eXBlLgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgSW5ldFBvcnROdW1iZXIgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAgNzY4OiBVc2VyIERhdGFncmFtIFByb3RvY29sCiAgICAgIFJGQyAgNzkzOiBUcmFuc21pc3Npb24gQ29udHJvbCBQcm90b2NvbAogICAgICBSRkMgNDk2MDogU3RyZWFtIENvbnRyb2wgVHJhbnNtaXNzaW9uIFByb3RvY29sCiAgICAgIFJGQyA0MzQwOiBEYXRhZ3JhbSBDb25nZXN0aW9uIENvbnRyb2wgUHJvdG9jb2wgKERDQ1ApCiAgICAgIFJGQyA0MDAxOiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBJbnRlcm5ldCBOZXR3b3JrIEFkZHJlc3NlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgdHlwZXMgcmVsYXRlZCB0byBhdXRvbm9tb3VzIHN5c3RlbXMgKioqLwoKICB0eXBlZGVmIGFzLW51bWJlciB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBhcy1udW1iZXIgdHlwZSByZXByZXNlbnRzIGF1dG9ub21vdXMgc3lzdGVtIG51bWJlcnMKICAgICAgd2hpY2ggaWRlbnRpZnkgYW4gQXV0b25vbW91cyBTeXN0ZW0gKEFTKS4gIEFuIEFTIGlzIGEgc2V0CiAgICAgIG9mIHJvdXRlcnMgdW5kZXIgYSBzaW5nbGUgdGVjaG5pY2FsIGFkbWluaXN0cmF0aW9uLCB1c2luZwogICAgICBhbiBpbnRlcmlvciBnYXRld2F5IHByb3RvY29sIGFuZCBjb21tb24gbWV0cmljcyB0byByb3V0ZQogICAgICBwYWNrZXRzIHdpdGhpbiB0aGUgQVMsIGFuZCB1c2luZyBhbiBleHRlcmlvciBnYXRld2F5CiAgICAgIHByb3RvY29sIHRvIHJvdXRlIHBhY2tldHMgdG8gb3RoZXIgQVNlcy4gIElBTkEgbWFpbnRhaW5zCiAgICAgIHRoZSBBUyBudW1iZXIgc3BhY2UgYW5kIGhhcyBkZWxlZ2F0ZWQgbGFyZ2UgcGFydHMgdG8gdGhlCiAgICAgIHJlZ2lvbmFsIHJlZ2lzdHJpZXMuCgogICAgICBBdXRvbm9tb3VzIHN5c3RlbSBudW1iZXJzIHdlcmUgb3JpZ2luYWxseSBsaW1pdGVkIHRvIDE2CiAgICAgIGJpdHMuICBCR1AgZXh0ZW5zaW9ucyBoYXZlIGVubGFyZ2VkIHRoZSBhdXRvbm9tb3VzIHN5c3RlbQogICAgICBudW1iZXIgc3BhY2UgdG8gMzIgYml0cy4gIFRoaXMgdHlwZSB0aGVyZWZvcmUgdXNlcyBhbiB1aW50MzIKICAgICAgYmFzZSB0eXBlIHdpdGhvdXQgYSByYW5nZSByZXN0cmljdGlvbiBpbiBvcmRlciB0byBzdXBwb3J0CiAgICAgIGEgbGFyZ2VyIGF1dG9ub21vdXMgc3lzdGVtIG51bWJlciBzcGFjZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBJbmV0QXV0b25vbW91c1N5c3RlbU51bWJlciB0ZXh0dWFsIGNvbnZlbnRpb24gb2YKICAgICAgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDE5MzA6IEd1aWRlbGluZXMgZm9yIGNyZWF0aW9uLCBzZWxlY3Rpb24sIGFuZCByZWdpc3RyYXRpb24KICAgICAgICAgICAgICAgIG9mIGFuIEF1dG9ub21vdXMgU3lzdGVtIChBUykKICAgICAgUkZDIDQyNzE6IEEgQm9yZGVyIEdhdGV3YXkgUHJvdG9jb2wgNCAoQkdQLTQpCiAgICAgIFJGQyA0MDAxOiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBJbnRlcm5ldCBOZXR3b3JrIEFkZHJlc3NlcwogICAgICBSRkMgNjc5MzogQkdQIFN1cHBvcnQgZm9yIEZvdXItT2N0ZXQgQXV0b25vbW91cyBTeXN0ZW0gKEFTKQogICAgICAgICAgICAgICAgTnVtYmVyIFNwYWNlIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiB0eXBlcyByZWxhdGVkIHRvIElQIGFkZHJlc3NlcyBhbmQgaG9zdG5hbWVzICoqKi8KCiAgdHlwZWRlZiBpcC1hZGRyZXNzIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzOwogICAgICB0eXBlIGluZXQ6aXB2Ni1hZGRyZXNzOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGlwLWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQIGFkZHJlc3MgYW5kIGlzIElQCiAgICAgIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24KICAgICAgaW1wbGllcyB0aGUgSVAgdmVyc2lvbi4gIFRoaXMgdHlwZSBzdXBwb3J0cyBzY29wZWQgYWRkcmVzc2VzCiAgICAgIGJ5IGFsbG93aW5nIHpvbmUgaWRlbnRpZmllcnMgaW4gdGhlIGFkZHJlc3MgZm9ybWF0LiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDQwMDc6IElQdjYgU2NvcGVkIEFkZHJlc3MgQXJjaGl0ZWN0dXJlIjsKICB9CgogIHR5cGVkZWYgaXB2NC1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybgogICAgICAgICcoKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcLil7M30nCiAgICAgICsgICcoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKScKICAgICAgKyAnKCVbXHB7Tn1ccHtMfV0rKT8nOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIlRoZSBpcHY0LWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQdjQgYWRkcmVzcyBpbgogICAgICAgZG90dGVkLXF1YWQgbm90YXRpb24uICBUaGUgSVB2NCBhZGRyZXNzIG1heSBpbmNsdWRlIGEgem9uZQogICAgICAgaW5kZXgsIHNlcGFyYXRlZCBieSBhICUgc2lnbi4KCiAgICAgICBUaGUgem9uZSBpbmRleCBpcyB1c2VkIHRvIGRpc2FtYmlndWF0ZSBpZGVudGljYWwgYWRkcmVzcwogICAgICAgdmFsdWVzLiAgRm9yIGxpbmstbG9jYWwgYWRkcmVzc2VzLCB0aGUgem9uZSBpbmRleCB3aWxsCiAgICAgICB0eXBpY2FsbHkgYmUgdGhlIGludGVyZmFjZSBpbmRleCBudW1iZXIgb3IgdGhlIG5hbWUgb2YgYW4KICAgICAgIGludGVyZmFjZS4gIElmIHRoZSB6b25lIGluZGV4IGlzIG5vdCBwcmVzZW50LCB0aGUgZGVmYXVsdAogICAgICAgem9uZSBvZiB0aGUgZGV2aWNlIHdpbGwgYmUgdXNlZC4KCiAgICAgICBUaGUgY2Fub25pY2FsIGZvcm1hdCBmb3IgdGhlIHpvbmUgaW5kZXggaXMgdGhlIG51bWVyaWNhbAogICAgICAgZm9ybWF0IjsKICB9CgogIHR5cGVkZWYgaXB2Ni1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKCg6fFswLTlhLWZBLUZdezAsNH0pOikoWzAtOWEtZkEtRl17MCw0fTopezAsNX0nCiAgICAgICAgICAgICsgJygoKFswLTlhLWZBLUZdezAsNH06KT8oOnxbMC05YS1mQS1GXXswLDR9KSl8JwogICAgICAgICAgICArICcoKCgyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV0/WzAtOV0pXC4pezN9JwogICAgICAgICAgICArICcoMjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldP1swLTldKSkpJwogICAgICAgICAgICArICcoJVtccHtOfVxwe0x9XSspPyc7CiAgICAgIHBhdHRlcm4gJygoW146XSs6KXs2fSgoW146XSs6W146XSspfCguKlwuLiopKSl8JwogICAgICAgICAgICArICcoKChbXjpdKzopKlteOl0rKT86OigoW146XSs6KSpbXjpdKyk/KScKICAgICAgICAgICAgKyAnKCUuKyk/JzsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBpcHY2LWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElQdjYgYWRkcmVzcyBpbiBmdWxsLAogICAgICBtaXhlZCwgc2hvcnRlbmVkLCBhbmQgc2hvcnRlbmVkLW1peGVkIG5vdGF0aW9uLiAgVGhlIElQdjYKICAgICAgYWRkcmVzcyBtYXkgaW5jbHVkZSBhIHpvbmUgaW5kZXgsIHNlcGFyYXRlZCBieSBhICUgc2lnbi4KCiAgICAgIFRoZSB6b25lIGluZGV4IGlzIHVzZWQgdG8gZGlzYW1iaWd1YXRlIGlkZW50aWNhbCBhZGRyZXNzCiAgICAgIHZhbHVlcy4gIEZvciBsaW5rLWxvY2FsIGFkZHJlc3NlcywgdGhlIHpvbmUgaW5kZXggd2lsbAogICAgICB0eXBpY2FsbHkgYmUgdGhlIGludGVyZmFjZSBpbmRleCBudW1iZXIgb3IgdGhlIG5hbWUgb2YgYW4KICAgICAgaW50ZXJmYWNlLiAgSWYgdGhlIHpvbmUgaW5kZXggaXMgbm90IHByZXNlbnQsIHRoZSBkZWZhdWx0CiAgICAgIHpvbmUgb2YgdGhlIGRldmljZSB3aWxsIGJlIHVzZWQuCgogICAgICBUaGUgY2Fub25pY2FsIGZvcm1hdCBvZiBJUHY2IGFkZHJlc3NlcyB1c2VzIHRoZSB0ZXh0dWFsCiAgICAgIHJlcHJlc2VudGF0aW9uIGRlZmluZWQgaW4gU2VjdGlvbiA0IG9mIFJGQyA1OTUyLiAgVGhlCiAgICAgIGNhbm9uaWNhbCBmb3JtYXQgZm9yIHRoZSB6b25lIGluZGV4IGlzIHRoZSBudW1lcmljYWwKICAgICAgZm9ybWF0IGFzIGRlc2NyaWJlZCBpbiBTZWN0aW9uIDExLjIgb2YgUkZDIDQwMDcuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDI5MTogSVAgVmVyc2lvbiA2IEFkZHJlc3NpbmcgQXJjaGl0ZWN0dXJlCiAgICAgIFJGQyA0MDA3OiBJUHY2IFNjb3BlZCBBZGRyZXNzIEFyY2hpdGVjdHVyZQogICAgICBSRkMgNTk1MjogQSBSZWNvbW1lbmRhdGlvbiBmb3IgSVB2NiBBZGRyZXNzIFRleHQKICAgICAgICAgICAgICAgIFJlcHJlc2VudGF0aW9uIjsKICB9CgogIHR5cGVkZWYgaXAtYWRkcmVzcy1uby16b25lIHsKICAgIHR5cGUgdW5pb24gewogICAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzLW5vLXpvbmU7CiAgICAgIHR5cGUgaW5ldDppcHY2LWFkZHJlc3Mtbm8tem9uZTsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBpcC1hZGRyZXNzLW5vLXpvbmUgdHlwZSByZXByZXNlbnRzIGFuIElQIGFkZHJlc3MgYW5kIGlzCiAgICAgIElQIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24KICAgICAgaW1wbGllcyB0aGUgSVAgdmVyc2lvbi4gIFRoaXMgdHlwZSBkb2VzIG5vdCBzdXBwb3J0IHNjb3BlZAogICAgICBhZGRyZXNzZXMgc2luY2UgaXQgZG9lcyBub3QgYWxsb3cgem9uZSBpZGVudGlmaWVycyBpbiB0aGUKICAgICAgYWRkcmVzcyBmb3JtYXQuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDAwNzogSVB2NiBTY29wZWQgQWRkcmVzcyBBcmNoaXRlY3R1cmUiOwogIH0KCiAgdHlwZWRlZiBpcHY0LWFkZHJlc3Mtbm8tem9uZSB7CiAgICB0eXBlIGluZXQ6aXB2NC1hZGRyZXNzIHsKICAgICAgcGF0dGVybiAnWzAtOVwuXSonOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIkFuIElQdjQgYWRkcmVzcyB3aXRob3V0IGEgem9uZSBpbmRleC4gIFRoaXMgdHlwZSwgZGVyaXZlZCBmcm9tCiAgICAgICBpcHY0LWFkZHJlc3MsIG1heSBiZSB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgdGhlIHpvbmUgaXMKICAgICAgIGtub3duIGZyb20gdGhlIGNvbnRleHQgYW5kIGhlbmNlIG5vIHpvbmUgaW5kZXggaXMgbmVlZGVkLiI7CiAgfQoKICB0eXBlZGVmIGlwdjYtYWRkcmVzcy1uby16b25lIHsKICAgIHR5cGUgaW5ldDppcHY2LWFkZHJlc3MgewogICAgICBwYXR0ZXJuICdbMC05YS1mQS1GOlwuXSonOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAgIkFuIElQdjYgYWRkcmVzcyB3aXRob3V0IGEgem9uZSBpbmRleC4gIFRoaXMgdHlwZSwgZGVyaXZlZCBmcm9tCiAgICAgICBpcHY2LWFkZHJlc3MsIG1heSBiZSB1c2VkIGluIHNpdHVhdGlvbnMgd2hlcmUgdGhlIHpvbmUgaXMKICAgICAgIGtub3duIGZyb20gdGhlIGNvbnRleHQgYW5kIGhlbmNlIG5vIHpvbmUgaW5kZXggaXMgbmVlZGVkLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDQyOTE6IElQIFZlcnNpb24gNiBBZGRyZXNzaW5nIEFyY2hpdGVjdHVyZQogICAgICBSRkMgNDAwNzogSVB2NiBTY29wZWQgQWRkcmVzcyBBcmNoaXRlY3R1cmUKICAgICAgUkZDIDU5NTI6IEEgUmVjb21tZW5kYXRpb24gZm9yIElQdjYgQWRkcmVzcyBUZXh0CiAgICAgICAgICAgICAgICBSZXByZXNlbnRhdGlvbiI7CiAgfQoKICB0eXBlZGVmIGlwLXByZWZpeCB7CiAgICB0eXBlIHVuaW9uIHsKICAgICAgdHlwZSBpbmV0OmlwdjQtcHJlZml4OwogICAgICB0eXBlIGluZXQ6aXB2Ni1wcmVmaXg7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXAtcHJlZml4IHR5cGUgcmVwcmVzZW50cyBhbiBJUCBwcmVmaXggYW5kIGlzIElQCiAgICAgIHZlcnNpb24gbmV1dHJhbC4gIFRoZSBmb3JtYXQgb2YgdGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb25zCiAgICAgIGltcGxpZXMgdGhlIElQIHZlcnNpb24uIjsKICB9CgogIHR5cGVkZWYgaXB2NC1wcmVmaXggewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuCiAgICAgICAgICcoKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSlcLil7M30nCiAgICAgICArICAnKFswLTldfFsxLTldWzAtOV18MVswLTldWzAtOV18MlswLTRdWzAtOV18MjVbMC01XSknCiAgICAgICArICcvKChbMC05XSl8KFsxLTJdWzAtOV0pfCgzWzAtMl0pKSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaXB2NC1wcmVmaXggdHlwZSByZXByZXNlbnRzIGFuIElQdjQgYWRkcmVzcyBwcmVmaXguCiAgICAgIFRoZSBwcmVmaXggbGVuZ3RoIGlzIGdpdmVuIGJ5IHRoZSBudW1iZXIgZm9sbG93aW5nIHRoZQogICAgICBzbGFzaCBjaGFyYWN0ZXIgYW5kIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDMyLgoKICAgICAgQSBwcmVmaXggbGVuZ3RoIHZhbHVlIG9mIG4gY29ycmVzcG9uZHMgdG8gYW4gSVAgYWRkcmVzcwogICAgICBtYXNrIHRoYXQgaGFzIG4gY29udGlndW91cyAxLWJpdHMgZnJvbSB0aGUgbW9zdAogICAgICBzaWduaWZpY2FudCBiaXQgKE1TQikgYW5kIGFsbCBvdGhlciBiaXRzIHNldCB0byAwLgoKICAgICAgVGhlIGNhbm9uaWNhbCBmb3JtYXQgb2YgYW4gSVB2NCBwcmVmaXggaGFzIGFsbCBiaXRzIG9mCiAgICAgIHRoZSBJUHY0IGFkZHJlc3Mgc2V0IHRvIHplcm8gdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlCiAgICAgIElQdjQgcHJlZml4LiI7CiAgfQoKICB0eXBlZGVmIGlwdjYtcHJlZml4IHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKCg6fFswLTlhLWZBLUZdezAsNH0pOikoWzAtOWEtZkEtRl17MCw0fTopezAsNX0nCiAgICAgICAgICAgICsgJygoKFswLTlhLWZBLUZdezAsNH06KT8oOnxbMC05YS1mQS1GXXswLDR9KSl8JwogICAgICAgICAgICArICcoKCgyNVswLTVdfDJbMC00XVswLTldfFswMV0/WzAtOV0/WzAtOV0pXC4pezN9JwogICAgICAgICAgICArICcoMjVbMC01XXwyWzAtNF1bMC05XXxbMDFdP1swLTldP1swLTldKSkpJwogICAgICAgICAgICArICcoLygoWzAtOV0pfChbMC05XXsyfSl8KDFbMC0xXVswLTldKXwoMTJbMC04XSkpKSc7CiAgICAgIHBhdHRlcm4gJygoW146XSs6KXs2fSgoW146XSs6W146XSspfCguKlwuLiopKSl8JwogICAgICAgICAgICArICcoKChbXjpdKzopKlteOl0rKT86OigoW146XSs6KSpbXjpdKyk/KScKICAgICAgICAgICAgKyAnKC8uKyknOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGlwdjYtcHJlZml4IHR5cGUgcmVwcmVzZW50cyBhbiBJUHY2IGFkZHJlc3MgcHJlZml4LgogICAgICBUaGUgcHJlZml4IGxlbmd0aCBpcyBnaXZlbiBieSB0aGUgbnVtYmVyIGZvbGxvd2luZyB0aGUKICAgICAgc2xhc2ggY2hhcmFjdGVyIGFuZCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAxMjguCgogICAgICBBIHByZWZpeCBsZW5ndGggdmFsdWUgb2YgbiBjb3JyZXNwb25kcyB0byBhbiBJUCBhZGRyZXNzCiAgICAgIG1hc2sgdGhhdCBoYXMgbiBjb250aWd1b3VzIDEtYml0cyBmcm9tIHRoZSBtb3N0CiAgICAgIHNpZ25pZmljYW50IGJpdCAoTVNCKSBhbmQgYWxsIG90aGVyIGJpdHMgc2V0IHRvIDAuCgogICAgICBUaGUgSVB2NiBhZGRyZXNzIHNob3VsZCBoYXZlIGFsbCBiaXRzIHRoYXQgZG8gbm90IGJlbG9uZwogICAgICB0byB0aGUgcHJlZml4IHNldCB0byB6ZXJvLgoKICAgICAgVGhlIGNhbm9uaWNhbCBmb3JtYXQgb2YgYW4gSVB2NiBwcmVmaXggaGFzIGFsbCBiaXRzIG9mCiAgICAgIHRoZSBJUHY2IGFkZHJlc3Mgc2V0IHRvIHplcm8gdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlCiAgICAgIElQdjYgcHJlZml4LiAgRnVydGhlcm1vcmUsIHRoZSBJUHY2IGFkZHJlc3MgaXMgcmVwcmVzZW50ZWQKICAgICAgYXMgZGVmaW5lZCBpbiBTZWN0aW9uIDQgb2YgUkZDIDU5NTIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNTk1MjogQSBSZWNvbW1lbmRhdGlvbiBmb3IgSVB2NiBBZGRyZXNzIFRleHQKICAgICAgICAgICAgICAgIFJlcHJlc2VudGF0aW9uIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBkb21haW4gbmFtZSBhbmQgVVJJIHR5cGVzICoqKi8KCiAgdHlwZWRlZiBkb21haW4tbmFtZSB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIGxlbmd0aCAiMS4uMjUzIjsKICAgICAgcGF0dGVybgogICAgICAgICcoKChbYS16QS1aMC05X10oW2EtekEtWjAtOVwtX10pezAsNjF9KT9bYS16QS1aMC05XVwuKSonCiAgICAgICsgJyhbYS16QS1aMC05X10oW2EtekEtWjAtOVwtX10pezAsNjF9KT9bYS16QS1aMC05XVwuPyknCiAgICAgICsgJ3xcLic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgZG9tYWluLW5hbWUgdHlwZSByZXByZXNlbnRzIGEgRE5TIGRvbWFpbiBuYW1lLiAgVGhlCiAgICAgIG5hbWUgU0hPVUxEIGJlIGZ1bGx5IHF1YWxpZmllZCB3aGVuZXZlciBwb3NzaWJsZS4KCiAgICAgIEludGVybmV0IGRvbWFpbiBuYW1lcyBhcmUgb25seSBsb29zZWx5IHNwZWNpZmllZC4gIFNlY3Rpb24KICAgICAgMy41IG9mIFJGQyAxMDM0IHJlY29tbWVuZHMgYSBzeW50YXggKG1vZGlmaWVkIGluIFNlY3Rpb24KICAgICAgMi4xIG9mIFJGQyAxMTIzKS4gIFRoZSBwYXR0ZXJuIGFib3ZlIGlzIGludGVuZGVkIHRvIGFsbG93CiAgICAgIGZvciBjdXJyZW50IHByYWN0aWNlIGluIGRvbWFpbiBuYW1lIHVzZSwgYW5kIHNvbWUgcG9zc2libGUKICAgICAgZnV0dXJlIGV4cGFuc2lvbi4gIEl0IGlzIGRlc2lnbmVkIHRvIGhvbGQgdmFyaW91cyB0eXBlcyBvZgogICAgICBkb21haW4gbmFtZXMsIGluY2x1ZGluZyBuYW1lcyB1c2VkIGZvciBBIG9yIEFBQUEgcmVjb3JkcwogICAgICAoaG9zdCBuYW1lcykgYW5kIG90aGVyIHJlY29yZHMsIHN1Y2ggYXMgU1JWIHJlY29yZHMuICBOb3RlCiAgICAgIHRoYXQgSW50ZXJuZXQgaG9zdCBuYW1lcyBoYXZlIGEgc3RyaWN0ZXIgc3ludGF4IChkZXNjcmliZWQKICAgICAgaW4gUkZDIDk1MikgdGhhbiB0aGUgRE5TIHJlY29tbWVuZGF0aW9ucyBpbiBSRkNzIDEwMzQgYW5kCiAgICAgIDExMjMsIGFuZCB0aGF0IHN5c3RlbXMgdGhhdCB3YW50IHRvIHN0b3JlIGhvc3QgbmFtZXMgaW4KICAgICAgc2NoZW1hIG5vZGVzIHVzaW5nIHRoZSBkb21haW4tbmFtZSB0eXBlIGFyZSByZWNvbW1lbmRlZCB0bwogICAgICBhZGhlcmUgdG8gdGhpcyBzdHJpY3RlciBzdGFuZGFyZCB0byBlbnN1cmUgaW50ZXJvcGVyYWJpbGl0eS4KCiAgICAgIFRoZSBlbmNvZGluZyBvZiBETlMgbmFtZXMgaW4gdGhlIEROUyBwcm90b2NvbCBpcyBsaW1pdGVkCiAgICAgIHRvIDI1NSBjaGFyYWN0ZXJzLiAgU2luY2UgdGhlIGVuY29kaW5nIGNvbnNpc3RzIG9mIGxhYmVscwogICAgICBwcmVmaXhlZCBieSBhIGxlbmd0aCBieXRlcyBhbmQgdGhlcmUgaXMgYSB0cmFpbGluZyBOVUxMCiAgICAgIGJ5dGUsIG9ubHkgMjUzIGNoYXJhY3RlcnMgY2FuIGFwcGVhciBpbiB0aGUgdGV4dHVhbCBkb3R0ZWQKICAgICAgbm90YXRpb24uCgogICAgICBUaGUgZGVzY3JpcHRpb24gY2xhdXNlIG9mIHNjaGVtYSBub2RlcyB1c2luZyB0aGUgZG9tYWluLW5hbWUKICAgICAgdHlwZSBNVVNUIGRlc2NyaWJlIHdoZW4gYW5kIGhvdyB0aGVzZSBuYW1lcyBhcmUgcmVzb2x2ZWQgdG8KICAgICAgSVAgYWRkcmVzc2VzLiAgTm90ZSB0aGF0IHRoZSByZXNvbHV0aW9uIG9mIGEgZG9tYWluLW5hbWUgdmFsdWUKICAgICAgbWF5IHJlcXVpcmUgdG8gcXVlcnkgbXVsdGlwbGUgRE5TIHJlY29yZHMgKGUuZy4sIEEgZm9yIElQdjQKICAgICAgYW5kIEFBQUEgZm9yIElQdjYpLiAgVGhlIG9yZGVyIG9mIHRoZSByZXNvbHV0aW9uIHByb2Nlc3MgYW5kCiAgICAgIHdoaWNoIEROUyByZWNvcmQgdGFrZXMgcHJlY2VkZW5jZSBjYW4gZWl0aGVyIGJlIGRlZmluZWQKICAgICAgZXhwbGljaXRseSBvciBtYXkgZGVwZW5kIG9uIHRoZSBjb25maWd1cmF0aW9uIG9mIHRoZQogICAgICByZXNvbHZlci4KCiAgICAgIERvbWFpbi1uYW1lIHZhbHVlcyB1c2UgdGhlIFVTLUFTQ0lJIGVuY29kaW5nLiAgVGhlaXIgY2Fub25pY2FsCiAgICAgIGZvcm1hdCB1c2VzIGxvd2VyY2FzZSBVUy1BU0NJSSBjaGFyYWN0ZXJzLiAgSW50ZXJuYXRpb25hbGl6ZWQKICAgICAgZG9tYWluIG5hbWVzIE1VU1QgYmUgQS1sYWJlbHMgYXMgcGVyIFJGQyA1ODkwLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDICA5NTI6IERvRCBJbnRlcm5ldCBIb3N0IFRhYmxlIFNwZWNpZmljYXRpb24KICAgICAgUkZDIDEwMzQ6IERvbWFpbiBOYW1lcyAtIENvbmNlcHRzIGFuZCBGYWNpbGl0aWVzCiAgICAgIFJGQyAxMTIzOiBSZXF1aXJlbWVudHMgZm9yIEludGVybmV0IEhvc3RzIC0tIEFwcGxpY2F0aW9uCiAgICAgICAgICAgICAgICBhbmQgU3VwcG9ydAogICAgICBSRkMgMjc4MjogQSBETlMgUlIgZm9yIHNwZWNpZnlpbmcgdGhlIGxvY2F0aW9uIG9mIHNlcnZpY2VzCiAgICAgICAgICAgICAgICAoRE5TIFNSVikKICAgICAgUkZDIDU4OTA6IEludGVybmF0aW9uYWxpemVkIERvbWFpbiBOYW1lcyBpbiBBcHBsaWNhdGlvbnMKICAgICAgICAgICAgICAgIChJRE5BKTogRGVmaW5pdGlvbnMgYW5kIERvY3VtZW50IEZyYW1ld29yayI7CiAgfQoKICB0eXBlZGVmIGhvc3QgewogICAgdHlwZSB1bmlvbiB7CiAgICAgIHR5cGUgaW5ldDppcC1hZGRyZXNzOwogICAgICB0eXBlIGluZXQ6ZG9tYWluLW5hbWU7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgaG9zdCB0eXBlIHJlcHJlc2VudHMgZWl0aGVyIGFuIElQIGFkZHJlc3Mgb3IgYSBETlMKICAgICAgZG9tYWluIG5hbWUuIjsKICB9CgogIHR5cGVkZWYgdXJpIHsKICAgIHR5cGUgc3RyaW5nOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIHVyaSB0eXBlIHJlcHJlc2VudHMgYSBVbmlmb3JtIFJlc291cmNlIElkZW50aWZpZXIKICAgICAgKFVSSSkgYXMgZGVmaW5lZCBieSBTVEQgNjYuCgogICAgICBPYmplY3RzIHVzaW5nIHRoZSB1cmkgdHlwZSBNVVNUIGJlIGluIFVTLUFTQ0lJIGVuY29kaW5nLAogICAgICBhbmQgTVVTVCBiZSBub3JtYWxpemVkIGFzIGRlc2NyaWJlZCBieSBSRkMgMzk4NiBTZWN0aW9ucwogICAgICA2LjIuMSwgNi4yLjIuMSwgYW5kIDYuMi4yLjIuICBBbGwgdW5uZWNlc3NhcnkKICAgICAgcGVyY2VudC1lbmNvZGluZyBpcyByZW1vdmVkLCBhbmQgYWxsIGNhc2UtaW5zZW5zaXRpdmUKICAgICAgY2hhcmFjdGVycyBhcmUgc2V0IHRvIGxvd2VyY2FzZSBleGNlcHQgZm9yIGhleGFkZWNpbWFsCiAgICAgIGRpZ2l0cywgd2hpY2ggYXJlIG5vcm1hbGl6ZWQgdG8gdXBwZXJjYXNlIGFzIGRlc2NyaWJlZCBpbgogICAgICBTZWN0aW9uIDYuMi4yLjEuCgogICAgICBUaGUgcHVycG9zZSBvZiB0aGlzIG5vcm1hbGl6YXRpb24gaXMgdG8gaGVscCBwcm92aWRlCiAgICAgIHVuaXF1ZSBVUklzLiAgTm90ZSB0aGF0IHRoaXMgbm9ybWFsaXphdGlvbiBpcyBub3QKICAgICAgc3VmZmljaWVudCB0byBwcm92aWRlIHVuaXF1ZW5lc3MuICBUd28gVVJJcyB0aGF0IGFyZQogICAgICB0ZXh0dWFsbHkgZGlzdGluY3QgYWZ0ZXIgdGhpcyBub3JtYWxpemF0aW9uIG1heSBzdGlsbCBiZQogICAgICBlcXVpdmFsZW50LgoKICAgICAgT2JqZWN0cyB1c2luZyB0aGUgdXJpIHR5cGUgbWF5IHJlc3RyaWN0IHRoZSBzY2hlbWVzIHRoYXQKICAgICAgdGhleSBwZXJtaXQuICBGb3IgZXhhbXBsZSwgJ2RhdGE6JyBhbmQgJ3VybjonIHNjaGVtZXMKICAgICAgbWlnaHQgbm90IGJlIGFwcHJvcHJpYXRlLgoKICAgICAgQSB6ZXJvLWxlbmd0aCBVUkkgaXMgbm90IGEgdmFsaWQgVVJJLiAgVGhpcyBjYW4gYmUgdXNlZCB0bwogICAgICBleHByZXNzICdVUkkgYWJzZW50JyB3aGVyZSByZXF1aXJlZC4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBVcmkgU01JdjIgdGV4dHVhbCBjb252ZW50aW9uIGRlZmluZWQgaW4gUkZDIDUwMTcuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzk4NjogVW5pZm9ybSBSZXNvdXJjZSBJZGVudGlmaWVyIChVUkkpOiBHZW5lcmljIFN5bnRheAogICAgICBSRkMgMzMwNTogUmVwb3J0IGZyb20gdGhlIEpvaW50IFczQy9JRVRGIFVSSSBQbGFubmluZyBJbnRlcmVzdAogICAgICAgICAgICAgICAgR3JvdXA6IFVuaWZvcm0gUmVzb3VyY2UgSWRlbnRpZmllcnMgKFVSSXMpLCBVUkxzLAogICAgICAgICAgICAgICAgYW5kIFVuaWZvcm0gUmVzb3VyY2UgTmFtZXMgKFVSTnMpOiBDbGFyaWZpY2F0aW9ucwogICAgICAgICAgICAgICAgYW5kIFJlY29tbWVuZGF0aW9ucwogICAgICBSRkMgNTAxNzogTUlCIFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFVuaWZvcm0gUmVzb3VyY2UKICAgICAgICAgICAgICAgIElkZW50aWZpZXJzIChVUklzKSI7CiAgfQoKfQ==
+ietf-yang-types        urn:ietf:params:xml:ns:yang:ietf-yang-types     \N      []      2013-07-15      bW9kdWxlIGlldGYteWFuZy10eXBlcyB7CgogIG5hbWVzcGFjZSAidXJuOmlldGY6cGFyYW1zOnhtbDpuczp5YW5nOmlldGYteWFuZy10eXBlcyI7CiAgcHJlZml4ICJ5YW5nIjsKCiAgb3JnYW5pemF0aW9uCiAgICJJRVRGIE5FVE1PRCAoTkVUQ09ORiBEYXRhIE1vZGVsaW5nIExhbmd1YWdlKSBXb3JraW5nIEdyb3VwIjsKCiAgY29udGFjdAogICAiV0cgV2ViOiAgIDxodHRwOi8vdG9vbHMuaWV0Zi5vcmcvd2cvbmV0bW9kLz4KICAgIFdHIExpc3Q6ICA8bWFpbHRvOm5ldG1vZEBpZXRmLm9yZz4KCiAgICBXRyBDaGFpcjogRGF2aWQgS2Vzc2VucwogICAgICAgICAgICAgIDxtYWlsdG86ZGF2aWQua2Vzc2Vuc0Buc24uY29tPgoKICAgIFdHIENoYWlyOiBKdWVyZ2VuIFNjaG9lbndhZWxkZXIKICAgICAgICAgICAgICA8bWFpbHRvOmouc2Nob2Vud2FlbGRlckBqYWNvYnMtdW5pdmVyc2l0eS5kZT4KCiAgICBFZGl0b3I6ICAgSnVlcmdlbiBTY2hvZW53YWVsZGVyCiAgICAgICAgICAgICAgPG1haWx0bzpqLnNjaG9lbndhZWxkZXJAamFjb2JzLXVuaXZlcnNpdHkuZGU+IjsKCiAgZGVzY3JpcHRpb24KICAgIlRoaXMgbW9kdWxlIGNvbnRhaW5zIGEgY29sbGVjdGlvbiBvZiBnZW5lcmFsbHkgdXNlZnVsIGRlcml2ZWQKICAgIFlBTkcgZGF0YSB0eXBlcy4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMTMgSUVURiBUcnVzdCBhbmQgdGhlIHBlcnNvbnMgaWRlbnRpZmllZCBhcwogICAgYXV0aG9ycyBvZiB0aGUgY29kZS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvcgogICAgd2l0aG91dCBtb2RpZmljYXRpb24sIGlzIHBlcm1pdHRlZCBwdXJzdWFudCB0bywgYW5kIHN1YmplY3QKICAgIHRvIHRoZSBsaWNlbnNlIHRlcm1zIGNvbnRhaW5lZCBpbiwgdGhlIFNpbXBsaWZpZWQgQlNEIExpY2Vuc2UKICAgIHNldCBmb3J0aCBpbiBTZWN0aW9uIDQuYyBvZiB0aGUgSUVURiBUcnVzdCdzIExlZ2FsIFByb3Zpc2lvbnMKICAgIFJlbGF0aW5nIHRvIElFVEYgRG9jdW1lbnRzCiAgICAoaHR0cDovL3RydXN0ZWUuaWV0Zi5vcmcvbGljZW5zZS1pbmZvKS4KCiAgICBUaGlzIHZlcnNpb24gb2YgdGhpcyBZQU5HIG1vZHVsZSBpcyBwYXJ0IG9mIFJGQyA2OTkxOyBzZWUKICAgIHRoZSBSRkMgaXRzZWxmIGZvciBmdWxsIGxlZ2FsIG5vdGljZXMuIjsKCiAgcmV2aXNpb24gMjAxMy0wNy0xNSB7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGlzIHJldmlzaW9uIGFkZHMgdGhlIGZvbGxvd2luZyBuZXcgZGF0YSB0eXBlczoKICAgICAgLSB5YW5nLWlkZW50aWZpZXIKICAgICAgLSBoZXgtc3RyaW5nCiAgICAgIC0gdXVpZAogICAgICAtIGRvdHRlZC1xdWFkIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjk5MTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICByZXZpc2lvbiAyMDEwLTA5LTI0IHsKICAgIGRlc2NyaXB0aW9uCiAgICAgIkluaXRpYWwgcmV2aXNpb24uIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNjAyMTogQ29tbW9uIFlBTkcgRGF0YSBUeXBlcyI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2YgY291bnRlciBhbmQgZ2F1Z2UgdHlwZXMgKioqLwoKICB0eXBlZGVmIGNvdW50ZXIzMiB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBjb3VudGVyMzIgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIKICAgICAgdGhhdCBtb25vdG9uaWNhbGx5IGluY3JlYXNlcyB1bnRpbCBpdCByZWFjaGVzIGEKICAgICAgbWF4aW11bSB2YWx1ZSBvZiAyXjMyLTEgKDQyOTQ5NjcyOTUgZGVjaW1hbCksIHdoZW4gaXQKICAgICAgd3JhcHMgYXJvdW5kIGFuZCBzdGFydHMgaW5jcmVhc2luZyBhZ2FpbiBmcm9tIHplcm8uCgogICAgICBDb3VudGVycyBoYXZlIG5vIGRlZmluZWQgJ2luaXRpYWwnIHZhbHVlLCBhbmQgdGh1cywgYQogICAgICBzaW5nbGUgdmFsdWUgb2YgYSBjb3VudGVyIGhhcyAoaW4gZ2VuZXJhbCkgbm8gaW5mb3JtYXRpb24KICAgICAgY29udGVudC4gIERpc2NvbnRpbnVpdGllcyBpbiB0aGUgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nCiAgICAgIHZhbHVlIG5vcm1hbGx5IG9jY3VyIGF0IHJlLWluaXRpYWxpemF0aW9uIG9mIHRoZQogICAgICBtYW5hZ2VtZW50IHN5c3RlbSwgYW5kIGF0IG90aGVyIHRpbWVzIGFzIHNwZWNpZmllZCBpbiB0aGUKICAgICAgZGVzY3JpcHRpb24gb2YgYSBzY2hlbWEgbm9kZSB1c2luZyB0aGlzIHR5cGUuICBJZiBzdWNoCiAgICAgIG90aGVyIHRpbWVzIGNhbiBvY2N1ciwgZm9yIGV4YW1wbGUsIHRoZSBjcmVhdGlvbiBvZgogICAgICBhIHNjaGVtYSBub2RlIG9mIHR5cGUgY291bnRlcjMyIGF0IHRpbWVzIG90aGVyIHRoYW4KICAgICAgcmUtaW5pdGlhbGl6YXRpb24sIHRoZW4gYSBjb3JyZXNwb25kaW5nIHNjaGVtYSBub2RlCiAgICAgIHNob3VsZCBiZSBkZWZpbmVkLCB3aXRoIGFuIGFwcHJvcHJpYXRlIHR5cGUsIHRvIGluZGljYXRlCiAgICAgIHRoZSBsYXN0IGRpc2NvbnRpbnVpdHkuCgogICAgICBUaGUgY291bnRlcjMyIHR5cGUgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBjb25maWd1cmF0aW9uCiAgICAgIHNjaGVtYSBub2Rlcy4gIEEgZGVmYXVsdCBzdGF0ZW1lbnQgU0hPVUxEIE5PVCBiZSB1c2VkIGluCiAgICAgIGNvbWJpbmF0aW9uIHdpdGggdGhlIHR5cGUgY291bnRlcjMyLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIENvdW50ZXIzMiB0eXBlIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyNTc4OiBTdHJ1Y3R1cmUgb2YgTWFuYWdlbWVudCBJbmZvcm1hdGlvbiBWZXJzaW9uIDIKICAgICAgICAgICAgICAgIChTTUl2MikiOwogIH0KCiAgdHlwZWRlZiB6ZXJvLWJhc2VkLWNvdW50ZXIzMiB7CiAgICB0eXBlIHlhbmc6Y291bnRlcjMyOwogICAgZGVmYXVsdCAiMCI7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgemVyby1iYXNlZC1jb3VudGVyMzIgdHlwZSByZXByZXNlbnRzIGEgY291bnRlcjMyCiAgICAgIHRoYXQgaGFzIHRoZSBkZWZpbmVkICdpbml0aWFsJyB2YWx1ZSB6ZXJvLgoKICAgICAgQSBzY2hlbWEgbm9kZSBvZiB0aGlzIHR5cGUgd2lsbCBiZSBzZXQgdG8gemVybyAoMCkgb24gY3JlYXRpb24KICAgICAgYW5kIHdpbGwgdGhlcmVhZnRlciBpbmNyZWFzZSBtb25vdG9uaWNhbGx5IHVudGlsIGl0IHJlYWNoZXMKICAgICAgYSBtYXhpbXVtIHZhbHVlIG9mIDJeMzItMSAoNDI5NDk2NzI5NSBkZWNpbWFsKSwgd2hlbiBpdAogICAgICB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIFByb3ZpZGVkIHRoYXQgYW4gYXBwbGljYXRpb24gZGlzY292ZXJzIGEgbmV3IHNjaGVtYSBub2RlCiAgICAgIG9mIHRoaXMgdHlwZSB3aXRoaW4gdGhlIG1pbmltdW0gdGltZSB0byB3cmFwLCBpdCBjYW4gdXNlIHRoZQogICAgICAnaW5pdGlhbCcgdmFsdWUgYXMgYSBkZWx0YS4gIEl0IGlzIGltcG9ydGFudCBmb3IgYSBtYW5hZ2VtZW50CiAgICAgIHN0YXRpb24gdG8gYmUgYXdhcmUgb2YgdGhpcyBtaW5pbXVtIHRpbWUgYW5kIHRoZSBhY3R1YWwgdGltZQogICAgICBiZXR3ZWVuIHBvbGxzLCBhbmQgdG8gZGlzY2FyZCBkYXRhIGlmIHRoZSBhY3R1YWwgdGltZSBpcyB0b28KICAgICAgbG9uZyBvciB0aGVyZSBpcyBubyBkZWZpbmVkIG1pbmltdW0gdGltZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBaZXJvQmFzZWRDb3VudGVyMzIgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgICJSRkMgNDUwMjogUmVtb3RlIE5ldHdvcmsgTW9uaXRvcmluZyBNYW5hZ2VtZW50IEluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgQmFzZSBWZXJzaW9uIDIiOwogIH0KCiAgdHlwZWRlZiBjb3VudGVyNjQgewogICAgdHlwZSB1aW50NjQ7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgY291bnRlcjY0IHR5cGUgcmVwcmVzZW50cyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyCiAgICAgIHRoYXQgbW9ub3RvbmljYWxseSBpbmNyZWFzZXMgdW50aWwgaXQgcmVhY2hlcyBhCiAgICAgIG1heGltdW0gdmFsdWUgb2YgMl42NC0xICgxODQ0Njc0NDA3MzcwOTU1MTYxNSBkZWNpbWFsKSwKICAgICAgd2hlbiBpdCB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIENvdW50ZXJzIGhhdmUgbm8gZGVmaW5lZCAnaW5pdGlhbCcgdmFsdWUsIGFuZCB0aHVzLCBhCiAgICAgIHNpbmdsZSB2YWx1ZSBvZiBhIGNvdW50ZXIgaGFzIChpbiBnZW5lcmFsKSBubyBpbmZvcm1hdGlvbgogICAgICBjb250ZW50LiAgRGlzY29udGludWl0aWVzIGluIHRoZSBtb25vdG9uaWNhbGx5IGluY3JlYXNpbmcKICAgICAgdmFsdWUgbm9ybWFsbHkgb2NjdXIgYXQgcmUtaW5pdGlhbGl6YXRpb24gb2YgdGhlCiAgICAgIG1hbmFnZW1lbnQgc3lzdGVtLCBhbmQgYXQgb3RoZXIgdGltZXMgYXMgc3BlY2lmaWVkIGluIHRoZQogICAgICBkZXNjcmlwdGlvbiBvZiBhIHNjaGVtYSBub2RlIHVzaW5nIHRoaXMgdHlwZS4gIElmIHN1Y2gKICAgICAgb3RoZXIgdGltZXMgY2FuIG9jY3VyLCBmb3IgZXhhbXBsZSwgdGhlIGNyZWF0aW9uIG9mCiAgICAgIGEgc2NoZW1hIG5vZGUgb2YgdHlwZSBjb3VudGVyNjQgYXQgdGltZXMgb3RoZXIgdGhhbgogICAgICByZS1pbml0aWFsaXphdGlvbiwgdGhlbiBhIGNvcnJlc3BvbmRpbmcgc2NoZW1hIG5vZGUKICAgICAgc2hvdWxkIGJlIGRlZmluZWQsIHdpdGggYW4gYXBwcm9wcmlhdGUgdHlwZSwgdG8gaW5kaWNhdGUKICAgICAgdGhlIGxhc3QgZGlzY29udGludWl0eS4KCiAgICAgIFRoZSBjb3VudGVyNjQgdHlwZSBzaG91bGQgbm90IGJlIHVzZWQgZm9yIGNvbmZpZ3VyYXRpb24KICAgICAgc2NoZW1hIG5vZGVzLiAgQSBkZWZhdWx0IHN0YXRlbWVudCBTSE9VTEQgTk9UIGJlIHVzZWQgaW4KICAgICAgY29tYmluYXRpb24gd2l0aCB0aGUgdHlwZSBjb3VudGVyNjQuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgQ291bnRlcjY0IHR5cGUgb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDI1Nzg6IFN0cnVjdHVyZSBvZiBNYW5hZ2VtZW50IEluZm9ybWF0aW9uIFZlcnNpb24gMgogICAgICAgICAgICAgICAgKFNNSXYyKSI7CiAgfQoKICB0eXBlZGVmIHplcm8tYmFzZWQtY291bnRlcjY0IHsKICAgIHR5cGUgeWFuZzpjb3VudGVyNjQ7CiAgICBkZWZhdWx0ICIwIjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSB6ZXJvLWJhc2VkLWNvdW50ZXI2NCB0eXBlIHJlcHJlc2VudHMgYSBjb3VudGVyNjQgdGhhdAogICAgICBoYXMgdGhlIGRlZmluZWQgJ2luaXRpYWwnIHZhbHVlIHplcm8uCgoKCgogICAgICBBIHNjaGVtYSBub2RlIG9mIHRoaXMgdHlwZSB3aWxsIGJlIHNldCB0byB6ZXJvICgwKSBvbiBjcmVhdGlvbgogICAgICBhbmQgd2lsbCB0aGVyZWFmdGVyIGluY3JlYXNlIG1vbm90b25pY2FsbHkgdW50aWwgaXQgcmVhY2hlcwogICAgICBhIG1heGltdW0gdmFsdWUgb2YgMl42NC0xICgxODQ0Njc0NDA3MzcwOTU1MTYxNSBkZWNpbWFsKSwKICAgICAgd2hlbiBpdCB3cmFwcyBhcm91bmQgYW5kIHN0YXJ0cyBpbmNyZWFzaW5nIGFnYWluIGZyb20gemVyby4KCiAgICAgIFByb3ZpZGVkIHRoYXQgYW4gYXBwbGljYXRpb24gZGlzY292ZXJzIGEgbmV3IHNjaGVtYSBub2RlCiAgICAgIG9mIHRoaXMgdHlwZSB3aXRoaW4gdGhlIG1pbmltdW0gdGltZSB0byB3cmFwLCBpdCBjYW4gdXNlIHRoZQogICAgICAnaW5pdGlhbCcgdmFsdWUgYXMgYSBkZWx0YS4gIEl0IGlzIGltcG9ydGFudCBmb3IgYSBtYW5hZ2VtZW50CiAgICAgIHN0YXRpb24gdG8gYmUgYXdhcmUgb2YgdGhpcyBtaW5pbXVtIHRpbWUgYW5kIHRoZSBhY3R1YWwgdGltZQogICAgICBiZXR3ZWVuIHBvbGxzLCBhbmQgdG8gZGlzY2FyZCBkYXRhIGlmIHRoZSBhY3R1YWwgdGltZSBpcyB0b28KICAgICAgbG9uZyBvciB0aGVyZSBpcyBubyBkZWZpbmVkIG1pbmltdW0gdGltZS4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBaZXJvQmFzZWRDb3VudGVyNjQgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyODU2OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBBZGRpdGlvbmFsIEhpZ2ggQ2FwYWNpdHkKICAgICAgICAgICAgICAgIERhdGEgVHlwZXMiOwogIH0KCiAgdHlwZWRlZiBnYXVnZTMyIHsKICAgIHR5cGUgdWludDMyOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhlIGdhdWdlMzIgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIsIHdoaWNoCiAgICAgIG1heSBpbmNyZWFzZSBvciBkZWNyZWFzZSwgYnV0IHNoYWxsIG5ldmVyIGV4Y2VlZCBhIG1heGltdW0KICAgICAgdmFsdWUsIG5vciBmYWxsIGJlbG93IGEgbWluaW11bSB2YWx1ZS4gIFRoZSBtYXhpbXVtIHZhbHVlCiAgICAgIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gMl4zMi0xICg0Mjk0OTY3Mjk1IGRlY2ltYWwpLCBhbmQKICAgICAgdGhlIG1pbmltdW0gdmFsdWUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiAwLiAgVGhlIHZhbHVlIG9mCiAgICAgIGEgZ2F1Z2UzMiBoYXMgaXRzIG1heGltdW0gdmFsdWUgd2hlbmV2ZXIgdGhlIGluZm9ybWF0aW9uCiAgICAgIGJlaW5nIG1vZGVsZWQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGl0cyBtYXhpbXVtCiAgICAgIHZhbHVlLCBhbmQgaGFzIGl0cyBtaW5pbXVtIHZhbHVlIHdoZW5ldmVyIHRoZSBpbmZvcm1hdGlvbgogICAgICBiZWluZyBtb2RlbGVkIGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0byBpdHMgbWluaW11bSB2YWx1ZS4KICAgICAgSWYgdGhlIGluZm9ybWF0aW9uIGJlaW5nIG1vZGVsZWQgc3Vic2VxdWVudGx5IGRlY3JlYXNlcwogICAgICBiZWxvdyAoaW5jcmVhc2VzIGFib3ZlKSB0aGUgbWF4aW11bSAobWluaW11bSkgdmFsdWUsIHRoZQogICAgICBnYXVnZTMyIGFsc28gZGVjcmVhc2VzIChpbmNyZWFzZXMpLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIEdhdWdlMzIgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgZ2F1Z2U2NCB7CiAgICB0eXBlIHVpbnQ2NDsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSBnYXVnZTY0IHR5cGUgcmVwcmVzZW50cyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLCB3aGljaAogICAgICBtYXkgaW5jcmVhc2Ugb3IgZGVjcmVhc2UsIGJ1dCBzaGFsbCBuZXZlciBleGNlZWQgYSBtYXhpbXVtCiAgICAgIHZhbHVlLCBub3IgZmFsbCBiZWxvdyBhIG1pbmltdW0gdmFsdWUuICBUaGUgbWF4aW11bSB2YWx1ZQogICAgICBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIDJeNjQtMSAoMTg0NDY3NDQwNzM3MDk1NTE2MTUpLCBhbmQKICAgICAgdGhlIG1pbmltdW0gdmFsdWUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiAwLiAgVGhlIHZhbHVlIG9mCiAgICAgIGEgZ2F1Z2U2NCBoYXMgaXRzIG1heGltdW0gdmFsdWUgd2hlbmV2ZXIgdGhlIGluZm9ybWF0aW9uCiAgICAgIGJlaW5nIG1vZGVsZWQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGl0cyBtYXhpbXVtCiAgICAgIHZhbHVlLCBhbmQgaGFzIGl0cyBtaW5pbXVtIHZhbHVlIHdoZW5ldmVyIHRoZSBpbmZvcm1hdGlvbgogICAgICBiZWluZyBtb2RlbGVkIGlzIHNtYWxsZXIgdGhhbiBvciBlcXVhbCB0byBpdHMgbWluaW11bSB2YWx1ZS4KICAgICAgSWYgdGhlIGluZm9ybWF0aW9uIGJlaW5nIG1vZGVsZWQgc3Vic2VxdWVudGx5IGRlY3JlYXNlcwogICAgICBiZWxvdyAoaW5jcmVhc2VzIGFib3ZlKSB0aGUgbWF4aW11bSAobWluaW11bSkgdmFsdWUsIHRoZQogICAgICBnYXVnZTY0IGFsc28gZGVjcmVhc2VzIChpbmNyZWFzZXMpLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIENvdW50ZXJCYXNlZEdhdWdlNjQgU01JdjIgdGV4dHVhbCBjb252ZW50aW9uIGRlZmluZWQKICAgICAgaW4gUkZDIDI4NTYiOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyODU2OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBBZGRpdGlvbmFsIEhpZ2ggQ2FwYWNpdHkKICAgICAgICAgICAgICAgIERhdGEgVHlwZXMiOwogIH0KCiAgLyoqKiBjb2xsZWN0aW9uIG9mIGlkZW50aWZpZXItcmVsYXRlZCB0eXBlcyAqKiovCgogIHR5cGVkZWYgb2JqZWN0LWlkZW50aWZpZXIgewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICcoKFswLTFdKFwuWzEtM10/WzAtOV0pKXwoMlwuKDB8KFsxLTldXGQqKSkpKScKICAgICAgICAgICAgKyAnKFwuKDB8KFsxLTldXGQqKSkpKic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgb2JqZWN0LWlkZW50aWZpZXIgdHlwZSByZXByZXNlbnRzIGFkbWluaXN0cmF0aXZlbHkKICAgICAgYXNzaWduZWQgbmFtZXMgaW4gYSByZWdpc3RyYXRpb24taGllcmFyY2hpY2FsLW5hbWUgdHJlZS4KCiAgICAgIFZhbHVlcyBvZiB0aGlzIHR5cGUgYXJlIGRlbm90ZWQgYXMgYSBzZXF1ZW5jZSBvZiBudW1lcmljYWwKICAgICAgbm9uLW5lZ2F0aXZlIHN1Yi1pZGVudGlmaWVyIHZhbHVlcy4gIEVhY2ggc3ViLWlkZW50aWZpZXIKICAgICAgdmFsdWUgTVVTVCBOT1QgZXhjZWVkIDJeMzItMSAoNDI5NDk2NzI5NSkuICBTdWItaWRlbnRpZmllcnMKICAgICAgYXJlIHNlcGFyYXRlZCBieSBzaW5nbGUgZG90cyBhbmQgd2l0aG91dCBhbnkgaW50ZXJtZWRpYXRlCiAgICAgIHdoaXRlc3BhY2UuCgogICAgICBUaGUgQVNOLjEgc3RhbmRhcmQgcmVzdHJpY3RzIHRoZSB2YWx1ZSBzcGFjZSBvZiB0aGUgZmlyc3QKICAgICAgc3ViLWlkZW50aWZpZXIgdG8gMCwgMSwgb3IgMi4gIEZ1cnRoZXJtb3JlLCB0aGUgdmFsdWUgc3BhY2UKICAgICAgb2YgdGhlIHNlY29uZCBzdWItaWRlbnRpZmllciBpcyByZXN0cmljdGVkIHRvIHRoZSByYW5nZQogICAgICAwIHRvIDM5IGlmIHRoZSBmaXJzdCBzdWItaWRlbnRpZmllciBpcyAwIG9yIDEuICBGaW5hbGx5LAogICAgICB0aGUgQVNOLjEgc3RhbmRhcmQgcmVxdWlyZXMgdGhhdCBhbiBvYmplY3QgaWRlbnRpZmllcgogICAgICBoYXMgYWx3YXlzIGF0IGxlYXN0IHR3byBzdWItaWRlbnRpZmllcnMuICBUaGUgcGF0dGVybgogICAgICBjYXB0dXJlcyB0aGVzZSByZXN0cmljdGlvbnMuCgogICAgICBBbHRob3VnaCB0aGUgbnVtYmVyIG9mIHN1Yi1pZGVudGlmaWVycyBpcyBub3QgbGltaXRlZCwKICAgICAgbW9kdWxlIGRlc2lnbmVycyBzaG91bGQgcmVhbGl6ZSB0aGF0IHRoZXJlIG1heSBiZQogICAgICBpbXBsZW1lbnRhdGlvbnMgdGhhdCBzdGljayB3aXRoIHRoZSBTTUl2MiBsaW1pdCBvZiAxMjgKICAgICAgc3ViLWlkZW50aWZpZXJzLgoKICAgICAgVGhpcyB0eXBlIGlzIGEgc3VwZXJzZXQgb2YgdGhlIFNNSXYyIE9CSkVDVCBJREVOVElGSUVSIHR5cGUKICAgICAgc2luY2UgaXQgaXMgbm90IHJlc3RyaWN0ZWQgdG8gMTI4IHN1Yi1pZGVudGlmaWVycy4gIEhlbmNlLAogICAgICB0aGlzIHR5cGUgU0hPVUxEIE5PVCBiZSB1c2VkIHRvIHJlcHJlc2VudCB0aGUgU01JdjIgT0JKRUNUCiAgICAgIElERU5USUZJRVIgdHlwZTsgdGhlIG9iamVjdC1pZGVudGlmaWVyLTEyOCB0eXBlIFNIT1VMRCBiZQogICAgICB1c2VkIGluc3RlYWQuIjsKICAgIHJlZmVyZW5jZQogICAgICJJU085ODM0LTE6IEluZm9ybWF0aW9uIHRlY2hub2xvZ3kgLS0gT3BlbiBTeXN0ZW1zCiAgICAgIEludGVyY29ubmVjdGlvbiAtLSBQcm9jZWR1cmVzIGZvciB0aGUgb3BlcmF0aW9uIG9mIE9TSQogICAgICBSZWdpc3RyYXRpb24gQXV0aG9yaXRpZXM6IEdlbmVyYWwgcHJvY2VkdXJlcyBhbmQgdG9wCiAgICAgIGFyY3Mgb2YgdGhlIEFTTi4xIE9iamVjdCBJZGVudGlmaWVyIHRyZWUiOwogIH0KCiAgdHlwZWRlZiBvYmplY3QtaWRlbnRpZmllci0xMjggewogICAgdHlwZSBvYmplY3QtaWRlbnRpZmllciB7CiAgICAgIHBhdHRlcm4gJ1xkKihcLlxkKil7MSwxMjd9JzsKICAgIH0KICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoaXMgdHlwZSByZXByZXNlbnRzIG9iamVjdC1pZGVudGlmaWVycyByZXN0cmljdGVkIHRvIDEyOAogICAgICBzdWItaWRlbnRpZmllcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgT0JKRUNUIElERU5USUZJRVIgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgeWFuZy1pZGVudGlmaWVyIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgbGVuZ3RoICIxLi5tYXgiOwogICAgICBwYXR0ZXJuICdbYS16QS1aX11bYS16QS1aMC05XC1fLl0qJzsKICAgICAgcGF0dGVybiAnLnwuLnxbXnhYXS4qfC5bXm1NXS4qfC4uW15sTF0uKic7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICAiQSBZQU5HIGlkZW50aWZpZXIgc3RyaW5nIGFzIGRlZmluZWQgYnkgdGhlICdpZGVudGlmaWVyJwogICAgICAgcnVsZSBpbiBTZWN0aW9uIDEyIG9mIFJGQyA2MDIwLiAgQW4gaWRlbnRpZmllciBtdXN0CiAgICAgICBzdGFydCB3aXRoIGFuIGFscGhhYmV0aWMgY2hhcmFjdGVyIG9yIGFuIHVuZGVyc2NvcmUKICAgICAgIGZvbGxvd2VkIGJ5IGFuIGFyYml0cmFyeSBzZXF1ZW5jZSBvZiBhbHBoYWJldGljIG9yCiAgICAgICBudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmVzLCBoeXBoZW5zLCBvciBkb3RzLgoKICAgICAgIEEgWUFORyBpZGVudGlmaWVyIE1VU1QgTk9UIHN0YXJ0IHdpdGggYW55IHBvc3NpYmxlCiAgICAgICBjb21iaW5hdGlvbiBvZiB0aGUgbG93ZXJjYXNlIG9yIHVwcGVyY2FzZSBjaGFyYWN0ZXIKICAgICAgIHNlcXVlbmNlICd4bWwnLiI7CiAgICByZWZlcmVuY2UKICAgICAgIlJGQyA2MDIwOiBZQU5HIC0gQSBEYXRhIE1vZGVsaW5nIExhbmd1YWdlIGZvciB0aGUgTmV0d29yawogICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gUHJvdG9jb2wgKE5FVENPTkYpIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiB0eXBlcyByZWxhdGVkIHRvIGRhdGUgYW5kIHRpbWUqKiovCgogIHR5cGVkZWYgZGF0ZS1hbmQtdGltZSB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4gJ1xkezR9LVxkezJ9LVxkezJ9VFxkezJ9OlxkezJ9OlxkezJ9KFwuXGQrKT8nCiAgICAgICAgICAgICsgJyhafFtcK1wtXVxkezJ9OlxkezJ9KSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgZGF0ZS1hbmQtdGltZSB0eXBlIGlzIGEgcHJvZmlsZSBvZiB0aGUgSVNPIDg2MDEKICAgICAgc3RhbmRhcmQgZm9yIHJlcHJlc2VudGF0aW9uIG9mIGRhdGVzIGFuZCB0aW1lcyB1c2luZyB0aGUKICAgICAgR3JlZ29yaWFuIGNhbGVuZGFyLiAgVGhlIHByb2ZpbGUgaXMgZGVmaW5lZCBieSB0aGUKICAgICAgZGF0ZS10aW1lIHByb2R1Y3Rpb24gaW4gU2VjdGlvbiA1LjYgb2YgUkZDIDMzMzkuCgogICAgICBUaGUgZGF0ZS1hbmQtdGltZSB0eXBlIGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgZGF0ZVRpbWUgWE1MCiAgICAgIHNjaGVtYSB0eXBlIHdpdGggdGhlIGZvbGxvd2luZyBub3RhYmxlIGV4Y2VwdGlvbnM6CgogICAgICAoYSkgVGhlIGRhdGUtYW5kLXRpbWUgdHlwZSBkb2VzIG5vdCBhbGxvdyBuZWdhdGl2ZSB5ZWFycy4KCiAgICAgIChiKSBUaGUgZGF0ZS1hbmQtdGltZSB0aW1lLW9mZnNldCAtMDA6MDAgaW5kaWNhdGVzIGFuIHVua25vd24KICAgICAgICAgIHRpbWUgem9uZSAoc2VlIFJGQyAzMzM5KSB3aGlsZSAtMDA6MDAgYW5kICswMDowMCBhbmQgWgogICAgICAgICAgYWxsIHJlcHJlc2VudCB0aGUgc2FtZSB0aW1lIHpvbmUgaW4gZGF0ZVRpbWUuCgogICAgICAoYykgVGhlIGNhbm9uaWNhbCBmb3JtYXQgKHNlZSBiZWxvdykgb2YgZGF0YS1hbmQtdGltZSB2YWx1ZXMKICAgICAgICAgIGRpZmZlcnMgZnJvbSB0aGUgY2Fub25pY2FsIGZvcm1hdCB1c2VkIGJ5IHRoZSBkYXRlVGltZSBYTUwKICAgICAgICAgIHNjaGVtYSB0eXBlLCB3aGljaCByZXF1aXJlcyBhbGwgdGltZXMgdG8gYmUgaW4gVVRDIHVzaW5nCiAgICAgICAgICB0aGUgdGltZS1vZmZzZXQgJ1onLgoKICAgICAgVGhpcyB0eXBlIGlzIG5vdCBlcXVpdmFsZW50IHRvIHRoZSBEYXRlQW5kVGltZSB0ZXh0dWFsCiAgICAgIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyIHNpbmNlIFJGQyAzMzM5IHVzZXMgYSBkaWZmZXJlbnQKICAgICAgc2VwYXJhdG9yIGJldHdlZW4gZnVsbC1kYXRlIGFuZCBmdWxsLXRpbWUgYW5kIHByb3ZpZGVzCiAgICAgIGhpZ2hlciByZXNvbHV0aW9uIG9mIHRpbWUtc2VjZnJhYy4KCiAgICAgIFRoZSBjYW5vbmljYWwgZm9ybWF0IGZvciBkYXRlLWFuZC10aW1lIHZhbHVlcyB3aXRoIGEga25vd24gdGltZQogICAgICB6b25lIHVzZXMgYSBudW1lcmljIHRpbWUgem9uZSBvZmZzZXQgdGhhdCBpcyBjYWxjdWxhdGVkIHVzaW5nCiAgICAgIHRoZSBkZXZpY2UncyBjb25maWd1cmVkIGtub3duIG9mZnNldCB0byBVVEMgdGltZS4gIEEgY2hhbmdlIG9mCiAgICAgIHRoZSBkZXZpY2UncyBvZmZzZXQgdG8gVVRDIHRpbWUgd2lsbCBjYXVzZSBkYXRlLWFuZC10aW1lIHZhbHVlcwogICAgICB0byBjaGFuZ2UgYWNjb3JkaW5nbHkuICBTdWNoIGNoYW5nZXMgbWlnaHQgaGFwcGVuIHBlcmlvZGljYWxseQogICAgICBpbiBjYXNlIGEgc2VydmVyIGZvbGxvd3MgYXV0b21hdGljYWxseSBkYXlsaWdodCBzYXZpbmcgdGltZQogICAgICAoRFNUKSB0aW1lIHpvbmUgb2Zmc2V0IGNoYW5nZXMuICBUaGUgY2Fub25pY2FsIGZvcm1hdCBmb3IKICAgICAgZGF0ZS1hbmQtdGltZSB2YWx1ZXMgd2l0aCBhbiB1bmtub3duIHRpbWUgem9uZSAodXN1YWxseQogICAgICByZWZlcnJpbmcgdG8gdGhlIG5vdGlvbiBvZiBsb2NhbCB0aW1lKSB1c2VzIHRoZSB0aW1lLW9mZnNldAogICAgICAtMDA6MDAuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMzMzOTogRGF0ZSBhbmQgVGltZSBvbiB0aGUgSW50ZXJuZXQ6IFRpbWVzdGFtcHMKICAgICAgUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyCiAgICAgIFhTRC1UWVBFUzogWE1MIFNjaGVtYSBQYXJ0IDI6IERhdGF0eXBlcyBTZWNvbmQgRWRpdGlvbiI7CiAgfQoKICB0eXBlZGVmIHRpbWV0aWNrcyB7CiAgICB0eXBlIHVpbnQzMjsKICAgIGRlc2NyaXB0aW9uCiAgICAgIlRoZSB0aW1ldGlja3MgdHlwZSByZXByZXNlbnRzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgdGhhdAogICAgICByZXByZXNlbnRzIHRoZSB0aW1lLCBtb2R1bG8gMl4zMiAoNDI5NDk2NzI5NiBkZWNpbWFsKSwgaW4KICAgICAgaHVuZHJlZHRocyBvZiBhIHNlY29uZCBiZXR3ZWVuIHR3byBlcG9jaHMuICBXaGVuIGEgc2NoZW1hCiAgICAgIG5vZGUgaXMgZGVmaW5lZCB0aGF0IHVzZXMgdGhpcyB0eXBlLCB0aGUgZGVzY3JpcHRpb24gb2YKICAgICAgdGhlIHNjaGVtYSBub2RlIGlkZW50aWZpZXMgYm90aCBvZiB0aGUgcmVmZXJlbmNlIGVwb2Nocy4KCiAgICAgIEluIHRoZSB2YWx1ZSBzZXQgYW5kIGl0cyBzZW1hbnRpY3MsIHRoaXMgdHlwZSBpcyBlcXVpdmFsZW50CiAgICAgIHRvIHRoZSBUaW1lVGlja3MgdHlwZSBvZiB0aGUgU01JdjIuIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgMjU3ODogU3RydWN0dXJlIG9mIE1hbmFnZW1lbnQgSW5mb3JtYXRpb24gVmVyc2lvbiAyCiAgICAgICAgICAgICAgICAoU01JdjIpIjsKICB9CgogIHR5cGVkZWYgdGltZXN0YW1wIHsKICAgIHR5cGUgeWFuZzp0aW1ldGlja3M7CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgdGltZXN0YW1wIHR5cGUgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2YgYW4gYXNzb2NpYXRlZAogICAgICB0aW1ldGlja3Mgc2NoZW1hIG5vZGUgYXQgd2hpY2ggYSBzcGVjaWZpYyBvY2N1cnJlbmNlCiAgICAgIGhhcHBlbmVkLiAgVGhlIHNwZWNpZmljIG9jY3VycmVuY2UgbXVzdCBiZSBkZWZpbmVkIGluIHRoZQogICAgICBkZXNjcmlwdGlvbiBvZiBhbnkgc2NoZW1hIG5vZGUgZGVmaW5lZCB1c2luZyB0aGlzIHR5cGUuICBXaGVuCiAgICAgIHRoZSBzcGVjaWZpYyBvY2N1cnJlbmNlIG9jY3VycmVkIHByaW9yIHRvIHRoZSBsYXN0IHRpbWUgdGhlCiAgICAgIGFzc29jaWF0ZWQgdGltZXRpY2tzIGF0dHJpYnV0ZSB3YXMgemVybywgdGhlbiB0aGUgdGltZXN0YW1wCiAgICAgIHZhbHVlIGlzIHplcm8uICBOb3RlIHRoYXQgdGhpcyByZXF1aXJlcyBhbGwgdGltZXN0YW1wIHZhbHVlcwogICAgICB0byBiZSByZXNldCB0byB6ZXJvIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBhc3NvY2lhdGVkIHRpbWV0aWNrcwogICAgICBhdHRyaWJ1dGUgcmVhY2hlcyA0OTcrIGRheXMgYW5kIHdyYXBzIGFyb3VuZCB0byB6ZXJvLgoKICAgICAgVGhlIGFzc29jaWF0ZWQgdGltZXRpY2tzIHNjaGVtYSBub2RlIG11c3QgYmUgc3BlY2lmaWVkCiAgICAgIGluIHRoZSBkZXNjcmlwdGlvbiBvZiBhbnkgc2NoZW1hIG5vZGUgdXNpbmcgdGhpcyB0eXBlLgoKICAgICAgSW4gdGhlIHZhbHVlIHNldCBhbmQgaXRzIHNlbWFudGljcywgdGhpcyB0eXBlIGlzIGVxdWl2YWxlbnQKICAgICAgdG8gdGhlIFRpbWVTdGFtcCB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBnZW5lcmljIGFkZHJlc3MgdHlwZXMgKioqLwoKICB0eXBlZGVmIHBoeXMtYWRkcmVzcyB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4gJyhbMC05YS1mQS1GXXsyfSg6WzAtOWEtZkEtRl17Mn0pKik/JzsKICAgIH0KCgoKCiAgICBkZXNjcmlwdGlvbgogICAgICJSZXByZXNlbnRzIG1lZGlhLSBvciBwaHlzaWNhbC1sZXZlbCBhZGRyZXNzZXMgcmVwcmVzZW50ZWQKICAgICAgYXMgYSBzZXF1ZW5jZSBvY3RldHMsIGVhY2ggb2N0ZXQgcmVwcmVzZW50ZWQgYnkgdHdvIGhleGFkZWNpbWFsCiAgICAgIG51bWJlcnMuICBPY3RldHMgYXJlIHNlcGFyYXRlZCBieSBjb2xvbnMuICBUaGUgY2Fub25pY2FsCiAgICAgIHJlcHJlc2VudGF0aW9uIHVzZXMgbG93ZXJjYXNlIGNoYXJhY3RlcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgUGh5c0FkZHJlc3MgdGV4dHVhbCBjb252ZW50aW9uIG9mIHRoZSBTTUl2Mi4iOwogICAgcmVmZXJlbmNlCiAgICAgIlJGQyAyNTc5OiBUZXh0dWFsIENvbnZlbnRpb25zIGZvciBTTUl2MiI7CiAgfQoKICB0eXBlZGVmIG1hYy1hZGRyZXNzIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnWzAtOWEtZkEtRl17Mn0oOlswLTlhLWZBLUZdezJ9KXs1fSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJUaGUgbWFjLWFkZHJlc3MgdHlwZSByZXByZXNlbnRzIGFuIElFRUUgODAyIE1BQyBhZGRyZXNzLgogICAgICBUaGUgY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uIHVzZXMgbG93ZXJjYXNlIGNoYXJhY3RlcnMuCgogICAgICBJbiB0aGUgdmFsdWUgc2V0IGFuZCBpdHMgc2VtYW50aWNzLCB0aGlzIHR5cGUgaXMgZXF1aXZhbGVudAogICAgICB0byB0aGUgTWFjQWRkcmVzcyB0ZXh0dWFsIGNvbnZlbnRpb24gb2YgdGhlIFNNSXYyLiI7CiAgICByZWZlcmVuY2UKICAgICAiSUVFRSA4MDI6IElFRUUgU3RhbmRhcmQgZm9yIExvY2FsIGFuZCBNZXRyb3BvbGl0YW4gQXJlYQogICAgICAgICAgICAgICAgTmV0d29ya3M6IE92ZXJ2aWV3IGFuZCBBcmNoaXRlY3R1cmUKICAgICAgUkZDIDI1Nzk6IFRleHR1YWwgQ29udmVudGlvbnMgZm9yIFNNSXYyIjsKICB9CgogIC8qKiogY29sbGVjdGlvbiBvZiBYTUwtc3BlY2lmaWMgdHlwZXMgKioqLwoKICB0eXBlZGVmIHhwYXRoMS4wIHsKICAgIHR5cGUgc3RyaW5nOwogICAgZGVzY3JpcHRpb24KICAgICAiVGhpcyB0eXBlIHJlcHJlc2VudHMgYW4gWFBBVEggMS4wIGV4cHJlc3Npb24uCgogICAgICBXaGVuIGEgc2NoZW1hIG5vZGUgaXMgZGVmaW5lZCB0aGF0IHVzZXMgdGhpcyB0eXBlLCB0aGUKICAgICAgZGVzY3JpcHRpb24gb2YgdGhlIHNjaGVtYSBub2RlIE1VU1Qgc3BlY2lmeSB0aGUgWFBhdGgKICAgICAgY29udGV4dCBpbiB3aGljaCB0aGUgWFBhdGggZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQuIjsKICAgIHJlZmVyZW5jZQogICAgICJYUEFUSDogWE1MIFBhdGggTGFuZ3VhZ2UgKFhQYXRoKSBWZXJzaW9uIDEuMCI7CiAgfQoKICAvKioqIGNvbGxlY3Rpb24gb2Ygc3RyaW5nIHR5cGVzICoqKi8KCiAgdHlwZWRlZiBoZXgtc3RyaW5nIHsKICAgIHR5cGUgc3RyaW5nIHsKICAgICAgcGF0dGVybiAnKFswLTlhLWZBLUZdezJ9KDpbMC05YS1mQS1GXXsyfSkqKT8nOwogICAgfQogICAgZGVzY3JpcHRpb24KICAgICAiQSBoZXhhZGVjaW1hbCBzdHJpbmcgd2l0aCBvY3RldHMgcmVwcmVzZW50ZWQgYXMgaGV4IGRpZ2l0cwogICAgICBzZXBhcmF0ZWQgYnkgY29sb25zLiAgVGhlIGNhbm9uaWNhbCByZXByZXNlbnRhdGlvbiB1c2VzCiAgICAgIGxvd2VyY2FzZSBjaGFyYWN0ZXJzLiI7CiAgfQoKICB0eXBlZGVmIHV1aWQgewogICAgdHlwZSBzdHJpbmcgewogICAgICBwYXR0ZXJuICdbMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS0nCiAgICAgICAgICAgICsgJ1swLTlhLWZBLUZdezR9LVswLTlhLWZBLUZdezEyfSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICJBIFVuaXZlcnNhbGx5IFVuaXF1ZSBJRGVudGlmaWVyIGluIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgICAgZGVmaW5lZCBpbiBSRkMgNDEyMi4gIFRoZSBjYW5vbmljYWwgcmVwcmVzZW50YXRpb24gdXNlcwogICAgICBsb3dlcmNhc2UgY2hhcmFjdGVycy4KCiAgICAgIFRoZSBmb2xsb3dpbmcgaXMgYW4gZXhhbXBsZSBvZiBhIFVVSUQgaW4gc3RyaW5nIHJlcHJlc2VudGF0aW9uOgogICAgICBmODFkNGZhZS03ZGVjLTExZDAtYTc2NS0wMGEwYzkxZTZiZjYKICAgICAgIjsKICAgIHJlZmVyZW5jZQogICAgICJSRkMgNDEyMjogQSBVbml2ZXJzYWxseSBVbmlxdWUgSURlbnRpZmllciAoVVVJRCkgVVJOCiAgICAgICAgICAgICAgICBOYW1lc3BhY2UiOwogIH0KCiAgdHlwZWRlZiBkb3R0ZWQtcXVhZCB7CiAgICB0eXBlIHN0cmluZyB7CiAgICAgIHBhdHRlcm4KICAgICAgICAnKChbMC05XXxbMS05XVswLTldfDFbMC05XVswLTldfDJbMC00XVswLTldfDI1WzAtNV0pXC4pezN9JwogICAgICArICcoWzAtOV18WzEtOV1bMC05XXwxWzAtOV1bMC05XXwyWzAtNF1bMC05XXwyNVswLTVdKSc7CiAgICB9CiAgICBkZXNjcmlwdGlvbgogICAgICAiQW4gdW5zaWduZWQgMzItYml0IG51bWJlciBleHByZXNzZWQgaW4gdGhlIGRvdHRlZC1xdWFkCiAgICAgICBub3RhdGlvbiwgaS5lLiwgZm91ciBvY3RldHMgd3JpdHRlbiBhcyBkZWNpbWFsIG51bWJlcnMKICAgICAgIGFuZCBzZXBhcmF0ZWQgd2l0aCB0aGUgJy4nIChmdWxsIHN0b3ApIGNoYXJhY3Rlci4iOwogIH0KfQ==
+o-ran-smo-teiv-common-yang-extensions  urn:o-ran:smo-teiv-common-yang-extensions       \N      []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgewogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOm8tcmFuOnNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMiOwogICAgcHJlZml4IG9yLXRlaXYteWV4dDsKCiAgICBvcmdhbml6YXRpb24gIkVyaWNzc29uIEFCIjsKICAgIGNvbnRhY3QgIkVyaWNzc29uIGZpcnN0IGxpbmUgc3VwcG9ydCB2aWEgZW1haWwiOwogICAgZGVzY3JpcHRpb24KICAgICJUb3BvbG9neSBhbmQgSW52ZW50b3J5IFlBTkcgZXh0ZW5zaW9ucyBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyBleHRlbnNpb25zIHRvIHRoZSBZQU5HIGxhbmd1YWdlIHRoYXQgdG9wb2xvZ3kgYW5kCiAgICBpbnZlbnRvcnkgbW9kZWxzIHdpbGwgdXNlIHRvIGRlZmluZSBhbmQgYW5ub3RhdGUgdHlwZXMgYW5kIHJlbGF0aW9uc2hpcHMuIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0yNCIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIGV4dGVuc2lvbiBiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJEZWZpbmVzIGEgYmktZGlyZWN0aW9uYWwgcmVsYXRpb25zaGlwIGluIHRoZSB0b3BvbG9neS4KCiAgICAgICAgICAgIEEgYmktZGlyZWN0aW9uYWwtYXNzb2NpYXRpb24gKEJEQSkgaXMgYSByZWxhdGlvbnNoaXAgY29tcHJpc2luZyBvZgogICAgICAgICAgICBhbiBBLXNpZGUgYW5kIGEgQi1zaWRlLiBUaGUgQS1zaWRlIGlzIGNvbnNpZGVyZWQgdGhlIG9yaWdpbmF0aW5nCiAgICAgICAgICAgIHNpZGUgb2YgdGhlIHJlbGF0aW9uc2hpcDsgdGhlIEItc2lkZSBpcyBjb25zaWRlcmVkIHRoZSB0ZXJtaW5hdGluZwogICAgICAgICAgICBzaWRlIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSBvcmRlciBvZiBBLXNpZGUgYW5kIEItc2lkZSBpcyBvZgogICAgICAgICAgICBpbXBvcnRhbmNlIGFuZCBNVVNUIE5PVCBiZSBjaGFuZ2VkIG9uY2UgZGVmaW5lZC4KCiAgICAgICAgICAgIEJvdGggQS1zaWRlIGFuZCBCLXNpZGUgYXJlIGRlZmluZWQgb24gYSB0eXBlLCBhbmQgYXJlIGdpdmVuIGEgcm9sZS4KICAgICAgICAgICAgQSB0eXBlIG1heSBoYXZlIG11bHRpcGxlIG9yaWdpbmF0aW5nIGFuZC9vciB0ZXJtaW5hdGluZyBzaWRlcyBvZiBhCiAgICAgICAgICAgIHJlbGF0aW9uc2hpcCwgYWxsIGRpc3Rpbmd1aXNoZWQgYnkgcm9sZSBuYW1lLgoKICAgICAgICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIG9ubHkgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlICdtb2R1bGUnIHN0YXRlbWVudC4KICAgICAgICAgICAgTXVsdGlwbGUgJ2JpLWRpcmVjdGlvbmFsLXRvcG9sb2d5LXJlbGF0aW9uc2hpcCcgc3RhdGVtZW50cyBhcmUKICAgICAgICAgICAgYWxsb3dlZCBwZXIgcGFyZW50IHN0YXRlbWVudC4KCiAgICAgICAgICAgIFN1YnN0YXRlbWVudHMgdG8gdGhlICdiaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIGRlZmluZQogICAgICAgICAgICB0aGUgQS1zaWRlIGFuZCB0aGUgQi1zaWRlLCByZXNwZWN0aXZlbHksIGFuZCBvcHRpb25hbGx5IHByb3BlcnRpZXMKICAgICAgICAgICAgb2YgdGhlIHJlbGF0aW9uc2hpcC4gRGF0YSBub2RlcyBvZiB0eXBlcyAnbGVhZicgYW5kICdsZWFmLWxpc3QnIGFyZQogICAgICAgICAgICB1c2VkIGZvciB0aGlzIHB1cnBvc2UuIE9uZSBvZiB0aGUgZGF0YSBub2RlcyBNVVNUIGJlIGFubm90YXRlZCB3aXRoCiAgICAgICAgICAgIHRoZSAnYS1zaWRlJyBleHRlbnNpb247IGFub3RoZXIgZGF0YSBub2RlIE1VU1QgYmUgYW5ub3RhdGVkIHdpdGggdGhlCiAgICAgICAgICAgICdiLXNpZGUnIGV4dGVuc2lvbi4gT3RoZXIgZGF0YSBub2RlcyBkZWZpbmUgcHJvcGVydGllcyBvZiB0aGUKICAgICAgICAgICAgcmVsYXRpb25zaGlwLgoKICAgICAgICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSByZWxhdGlvbnNoaXAgbmFtZQogICAgICAgICAgICBpcyBzY29wZWQgdG8gdGhlIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyaW5nIG1vZHVsZSBhbmQgTVVTVCBiZQogICAgICAgICAgICB1bmlxdWUgd2l0aGluIHRoZSBzY29wZS4iOwoKICAgICAgICBhcmd1bWVudCByZWxhdGlvbnNoaXBOYW1lOwogICAgfQoKICAgIGV4dGVuc2lvbiBhU2lkZSB7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICAgICAgIkRlZmluZXMgdGhlIEEtc2lkZSBvZiBhIHJlbGF0aW9uc2hpcC4KCiAgICAgICAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIGEgJ2xlYWYnIG9yICdsZWFmLWxpc3QnCiAgICAgICAgICAgIHN0YXRlbWVudCwgd2hpY2ggaXRzZWxmIG11c3QgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgdGhlCiAgICAgICAgICAgICd1bmktZGlyZWN0aW9uYWwtdG9wb2xvZ3ktcmVsYXRpb25zaGlwJyBzdGF0ZW1lbnQuCgogICAgICAgICAgICBUaGUgZGF0YSB0eXBlIG9mIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIE1VU1QgYmUKICAgICAgICAgICAgJ2luc3RhbmNlLWlkZW50aWZpZXInLiBDb25zdHJhaW50cyBNQVkgYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwYXJlbnQKICAgICAgICAgICAgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIHRvIGVuZm9yY2UgY2FyZGluYWxpdHkuCgogICAgICAgICAgICBUaGUgaWRlbnRpZmllciBvZiB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBpcyB1c2VkIGFzIG5hbWUKICAgICAgICAgICAgb2YgdGhlIHJvbGUgb2YgdGhlIEEtc2lkZSBvZiB0aGUgcmVsYXRpb25zaGlwLiBUaGUgbmFtZSBvZiB0aGUgcm9sZQogICAgICAgICAgICBpcyBzY29wZWQgdG8gdGhlIHR5cGUgb24gd2hpY2ggdGhlIEEtc2lkZSBpcyBkZWZpbmVkIGFuZCBNVVNUIGJlCiAgICAgICAgICAgIHVuaXF1ZSB3aXRoaW4gdGhlIHNjb3BlLgoKICAgICAgICAgICAgV2hpbGUgdGhlIHBhcmVudCAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgZG9lcyBub3QgcmVzdWx0IGluIGEgcHJvcGVydHkKICAgICAgICAgICAgb2YgdGhlIHJlbGF0aW9uc2hpcCwgaXQgaXMgUkVDT01NRU5ERUQgdG8gYXZvaWQgdXNpbmcgdGhlIG5hbWUgb2YgYW4KICAgICAgICAgICAgZXhpc3RpbmcgdHlwZSBwcm9wZXJ0eSBhcyByb2xlIG5hbWUgdG8gYXZvaWQgcG90ZW50aWFsIGFtYmlndWl0aWVzCiAgICAgICAgICAgIGJldHdlZW4gcHJvcGVydGllcyBvZiBhIHR5cGUsIGFuZCByb2xlcyBvZiBhIHJlbGF0aW9uc2hpcCBvbiB0aGUKICAgICAgICAgICAgdHlwZS4KCiAgICAgICAgICAgIFRoZSBhcmd1bWVudCBpcyB0aGUgbmFtZSBvZiB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQS1zaWRlIHJlc2lkZXMuCiAgICAgICAgICAgIElmIHRoZSB0eXBlIGlzIGRlY2xhcmVkIGluIGFub3RoZXIgbW9kdWxlLCB0aGUgdHlwZSBtdXN0IGJlCiAgICAgICAgICAgIHByZWZpeGVkLCBhbmQgYSBjb3JyZXNwb25kaW5nICdpbXBvcnQnIHN0YXRlbWVudCBiZSB1c2VkIHRvIGRlY2xhcmUKICAgICAgICAgICAgdGhlIHByZWZpeC4iOwoKICAgICAgICBhcmd1bWVudCBhU2lkZVR5cGU7CiAgICB9CgogICAgZXh0ZW5zaW9uIGJTaWRlIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiRGVmaW5lcyB0aGUgQi1zaWRlIG9mIGEgcmVsYXRpb25zaGlwLgoKICAgICAgICAgICAgVGhlIHN0YXRlbWVudCBNVVNUIG9ubHkgYmUgYSBzdWJzdGF0ZW1lbnQgb2YgYSAnbGVhZicgb3IgJ2xlYWYtbGlzdCcKICAgICAgICAgICAgc3RhdGVtZW50LCB3aGljaCBpdHNlbGYgbXVzdCBiZSBhIHN1YnN0YXRlbWVudCBvZiB0aGUKICAgICAgICAgICAgJ3VuaS1kaXJlY3Rpb25hbC10b3BvbG9neS1yZWxhdGlvbnNoaXAnIHN0YXRlbWVudC4KCiAgICAgICAgICAgIFRoZSBkYXRhIHR5cGUgb2YgdGhlIHBhcmVudCAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgTVVTVCBiZQogICAgICAgICAgICAnaW5zdGFuY2UtaWRlbnRpZmllcicuIENvbnN0cmFpbnRzIE1BWSBiZSB1c2VkIGFzIHBhcnQgb2YgdGhlIHBhcmVudAogICAgICAgICAgICAnbGVhZicgb3IgJ2xlYWYtbGlzdCcgdG8gZW5mb3JjZSBjYXJkaW5hbGl0eS4KCiAgICAgICAgICAgIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBwYXJlbnQgJ2xlYWYnIG9yICdsZWFmLWxpc3QnIGlzIHVzZWQgYXMgbmFtZQogICAgICAgICAgICBvZiB0aGUgcm9sZSBvZiB0aGUgQi1zaWRlIG9mIHRoZSByZWxhdGlvbnNoaXAuIFRoZSBuYW1lIG9mIHRoZSByb2xlCiAgICAgICAgICAgIGlzIHNjb3BlZCB0byB0aGUgdHlwZSBvbiB3aGljaCB0aGUgQi1zaWRlIGlzIGRlZmluZWQgYW5kIE1VU1QgYmUKICAgICAgICAgICAgdW5pcXVlIHdpdGhpbiB0aGUgc2NvcGUuCgogICAgICAgICAgICBXaGlsZSB0aGUgcGFyZW50ICdsZWFmJyBvciAnbGVhZi1saXN0JyBkb2VzIG5vdCByZXN1bHQgaW4gYSBwcm9wZXJ0eQogICAgICAgICAgICBvZiB0aGUgcmVsYXRpb25zaGlwLCBpdCBpcyBSRUNPTU1FTkRFRCB0byBhdm9pZCB1c2luZyB0aGUgbmFtZSBvZiBhbgogICAgICAgICAgICBleGlzdGluZyB0eXBlIHByb3BlcnR5IGFzIHJvbGUgbmFtZSB0byBhdm9pZCBwb3RlbnRpYWwgYW1iaWd1aXRpZXMKICAgICAgICAgICAgYmV0d2VlbiBwcm9wZXJ0aWVzIG9mIGEgdHlwZSwgYW5kIHJvbGVzIG9mIGEgcmVsYXRpb25zaGlwIG9uIHRoZQogICAgICAgICAgICB0eXBlLgoKICAgICAgICAgICAgVGhlIGFyZ3VtZW50IGlzIHRoZSBuYW1lIG9mIHRoZSB0eXBlIG9uIHdoaWNoIHRoZSBCLXNpZGUgcmVzaWRlcy4KICAgICAgICAgICAgSWYgdGhlIHR5cGUgaXMgZGVjbGFyZWQgaW4gYW5vdGhlciBtb2R1bGUsIHRoZSB0eXBlIG11c3QgYmUKICAgICAgICAgICAgcHJlZml4ZWQsIGFuZCBhIGNvcnJlc3BvbmRpbmcgJ2ltcG9ydCcgc3RhdGVtZW50IGJlIHVzZWQgdG8gZGVjbGFyZQogICAgICAgICAgICB0aGUgcHJlZml4LiI7CgogICAgICAgIGFyZ3VtZW50IGJTaWRlVHlwZTsKICAgIH0KCiAgICBleHRlbnNpb24gZG9tYWluIHsKICAgICAgICBkZXNjcmlwdGlvbiAiS2V5d29yZCB1c2VkIHRvIGNhcnJ5IGRvbWFpbiBpbmZvcm1hdGlvbi4iOwogICAgICAgIGFyZ3VtZW50IGRvbWFpbk5hbWU7CiAgICB9CgogICAgZXh0ZW5zaW9uIGxhYmVsIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhlIGxhYmVsIGNhbiBiZSB1c2VkIHRvIGdpdmUgbW9kdWxlcyBhbmQgc3VibW9kdWxlcyBhIHNlbWFudGljCiAgICAgICAgICAgIHZlcnNpb24sIGluIGFkZGl0aW9uIHRvIHRoZWlyIHJldmlzaW9uLgoKICAgICAgICAgICAgVGhlIGZvcm1hdCBvZiB0aGUgbGFiZWwgaXMg4oCYeC55LnrigJkg4oCTIGV4cHJlc3NlZCBhcyBwYXR0ZXJuLCBpdCBpcwogICAgICAgICAgICBbMC05XStcXC5bMC05XStcXC5bMC05XSsKCiAgICAgICAgICAgIFRoZSBzdGF0ZW1lbnQgTVVTVCBvbmx5IGJlIGEgc3Vic3RhdGVtZW50IG9mIHRoZSByZXZpc2lvbiBzdGF0ZW1lbnQuCiAgICAgICAgICAgIFplcm8gb3Igb25lIHJldmlzaW9uIGxhYmVsIHN0YXRlbWVudHMgcGVyIHBhcmVudCBzdGF0ZW1lbnQgYXJlCiAgICAgICAgICAgIGFsbG93ZWQuCgogICAgICAgICAgICBSZXZpc2lvbiBsYWJlbHMgTVVTVCBiZSB1bmlxdWUgYW1vbmdzdCBhbGwgcmV2aXNpb25zIG9mIGEgbW9kdWxlIG9yCiAgICAgICAgICAgIHN1Ym1vZHVsZS4iOwoKICAgICAgICBhcmd1bWVudCBzZW12ZXJzaW9uOwogICAgfQp9
+o-ran-smo-teiv-common-yang-types       urn:o-ran:smo-teiv-common-yang-types    \N      []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyI7CiAgICBwcmVmaXggb3ItdGVpdi10eXBlczsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7IHByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgXzNncHAtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggdHlwZXMzZ3BwOyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiVG9wb2xvZ3kgYW5kIEludmVudG9yeSBjb21tb24gdHlwZXMgbW9kZWwuCgogICAgQ29weXJpZ2h0IChjKSAyMDI0IEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKICAgIFRoaXMgbW9kZWwgY29udGFpbnMgcmUtdXNhYmxlIGRhdGEgdHlwZXMgdGhhdCB0b3BvbG9neSBhbmQgaW52ZW50b3J5IG1vZGVscwogICAgd2lsbCBmcmVxdWVudGx5IHVzZSBhcyBwYXJ0IG9mIHR5cGVzIGFuZCByZWxhdGlvbnNoaXBzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBncm91cGluZyBUb3BfR3JwX1R5cGUgewogICAgICAgIGRlc2NyaXB0aW9uICJHcm91cGluZyBjb250YWluaW5nIHRoZSBrZXkgYXR0cmlidXRlIGNvbW1vbiB0byBhbGwgdHlwZXMuCiAgICAgICAgICAgIEFsbCB0eXBlcyBNVVNUIHVzZSB0aGlzIGdyb3VwaW5nLiI7CgogICAgICAgIGxlYWYgaWQgewogICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVuaXF1ZSBpZGVudGlmaWVyIG9mIHRvcG9sb2d5IGVudGl0aWVzLiBSZXByZXNlbnRzIHRoZQogICAgICAgICAgICAgICAgRW50aXR5IEluc3RhbmNlIElkZW50aWZpZXIuIjsKICAgICAgICB9CiAgICB9CgogICAgY29udGFpbmVyIGRlY29yYXRvcnMgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJUaGlzIGNvbnRhaW5lciBzZXJ2ZXMgYXMgZXh0ZW5zaW9uIHBvaW50IGZvciBhcHBsaWNhdGlvbnMgd2lzaGluZwogICAgICAgICAgICB0byBkZWZpbmUgdGhlaXIgb3duIGRlY29yYXRvcnMuIFRoaXMgaXMgZG9uZSB2aWEgYXVnbWVudGF0aW9ucy4gVGhleQogICAgICAgICAgICBjYW4gb25seSBiZSBkZWZpbmVkIGluIG5hbWUgdmFsdWUgcGFpci4KCiAgICAgICAgICAgIFRoaXMgaXMgYSBjb25zdW1lciBkYXRhIGFuZCBjYW4gYmUgYXR0YWNoZWQgdG8gVG9wb2xvZ3kgRW50aXR5IG9yCiAgICAgICAgICAgIFRvcG9sb2d5IFJlbGF0aW9uIGluc3RhbmNlLCBvdXRzaWRlIG9mIHRoZSBkZWNsYXJlZCBUb3BvbG9neSBFbnRpdHkKICAgICAgICAgICAgb3IgVG9wb2xvZ3kgUmVsYXRpb25zaGlwJ3MgYXR0cmlidXRlcy4gVGhpcyBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLAogICAgICAgICAgICBhbmQgaXQgTVVTVCBOT1QgYmUgYXVnbWVudGVkIG9yIGRldmlhdGVkIGluIGFueSB3YXksIHVubGVzcyBzdGF0ZWQKICAgICAgICAgICAgb3RoZXJ3aXNlLiI7CiAgICB9CgogICAgbGVhZi1saXN0IGNsYXNzaWZpZXJzIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiQ29uc3VtZXIgZGVmaW5lZCB0YWdzIHRvIHRvcG9sb2d5IGVudGl0aWVzIGFuZCByZWxhdGlvbnNoaXBzLgoKICAgICAgICAgICAgVGhpcyBpcyBhIGNvbnN1bWVyIGRhdGEgYW5kIGNhbiBiZSBhdHRhY2hlZCB0byBUb3BvbG9neSBFbnRpdHkgb3IKICAgICAgICAgICAgVG9wb2xvZ3kgUmVsYXRpb24gaW5zdGFuY2UsIG91dHNpZGUgb2YgdGhlIGRlY2xhcmVkIFRvcG9sb2d5IEVudGl0eQogICAgICAgICAgICBvciBUb3BvbG9neSBSZWxhdGlvbnNoaXAncyBhdHRyaWJ1dGVzLiBUaGlzIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQsCiAgICAgICAgICAgIGFuZCBpdCBNVVNUIE5PVCBiZSBhdWdtZW50ZWQgb3IgZGV2aWF0ZWQgaW4gYW55IHdheSwgdW5sZXNzIHN0YXRlZAogICAgICAgICAgICBvdGhlcndpc2UuIjsKCiAgICAgICAgdHlwZSBpZGVudGl0eXJlZiB7IGJhc2UgY2xhc3NpZmllcjsgfQogICAgfQoKICAgIGxlYWYtbGlzdCBzb3VyY2VJZHMgewogICAgICAgIGRlc2NyaXB0aW9uCiAgICAgICAgICAgICJBbiBvcmRlcmVkIGxpc3Qgb2YgaWRlbnRpdGllcyB0aGF0IHJlcHJlc2VudCB0aGUgc2V0IG9mIG5hdGl2ZQogICAgICAgICAgICBzb3VyY2UgaWRlbnRpZmllcnMgZm9yIHBhcnRpY2lwYXRpbmcgZW50aXRpZXMuCgogICAgICAgICAgICBUaGlzIGlzIGEgY29uc3VtZXIgZGF0YSBhbmQgY2FuIGJlIGF0dGFjaGVkIHRvIFRvcG9sb2d5IEVudGl0eSBvcgogICAgICAgICAgICBUb3BvbG9neSBSZWxhdGlvbiBpbnN0YW5jZSwgb3V0c2lkZSBvZiB0aGUgZGVjbGFyZWQgVG9wb2xvZ3kgRW50aXR5CiAgICAgICAgICAgIG9yIFRvcG9sb2d5IFJlbGF0aW9uc2hpcCdzIGF0dHJpYnV0ZXMuIFRoaXMgY2Fubm90IGJlIGluc3RhbnRpYXRlZCwKICAgICAgICAgICAgYW5kIGl0IE1VU1QgTk9UIGJlIGF1Z21lbnRlZCBvciBkZXZpYXRlZCBpbiBhbnkgd2F5LCB1bmxlc3Mgc3RhdGVkCiAgICAgICAgICAgIG90aGVyd2lzZS4iOwoKICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICBvcmRlcmVkLWJ5IHVzZXI7CiAgICB9CgogICAgY29udGFpbmVyIG1ldGFkYXRhIHsKICAgICAgICBkZXNjcmlwdGlvbgogICAgICAgICAgICAiVGhpcyBjb250YWluZXIgc2VydmVzIGFzIGV4dGVuc2lvbiBwb2ludCB0byBkZWZpbmUgbWV0YWRhdGEuIFRoZXkKICAgICAgICAgICAgY2FuIG9ubHkgYmUgZGVmaW5lZCBpbiBuYW1lIHZhbHVlIHBhaXIuCgogICAgICAgICAgICBUaGlzIGlzIGEgY29uc3VtZXIgZGF0YSBhbmQgY2FuIGJlIGF0dGFjaGVkIHRvIFRvcG9sb2d5IEVudGl0eSBvcgogICAgICAgICAgICBUb3BvbG9neSBSZWxhdGlvbiBpbnN0YW5jZSwgb3V0c2lkZSBvZiB0aGUgZGVjbGFyZWQgVG9wb2xvZ3kgRW50aXR5CiAgICAgICAgICAgIG9yIFRvcG9sb2d5IFJlbGF0aW9uc2hpcCdzIGF0dHJpYnV0ZXMuIFRoaXMgY2Fubm90IGJlIGluc3RhbnRpYXRlZCwKICAgICAgICAgICAgYW5kIGl0IE1VU1QgTk9UIGJlIGF1Z21lbnRlZCBvciBkZXZpYXRlZCBpbiBhbnkgd2F5LCB1bmxlc3Mgc3RhdGVkCiAgICAgICAgICAgIG90aGVyd2lzZS4iOwogICAgfQoKICAgIGlkZW50aXR5IGNsYXNzaWZpZXJ7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjbGFzc2lmaWVyIGlzIHVzZWQgYXMgYSBiYXNlIHRvIHByb3ZpZGUgYWxsIGNsYXNzaWZpZXJzCiAgICAgICAgICAgIHdpdGggaWRlbnRpdHkuICI7CiAgICB9Cn0=
+o-ran-smo-teiv-equipment       urn:o-ran:smo-teiv-equipment    EQUIPMENT       []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LWVxdWlwbWVudCB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtZXF1aXBtZW50IjsKICAgIHByZWZpeCBvci10ZWl2LWVxdWlwOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgeyBwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgICAgICBwcmVmaXggZ2VvOwogICAgICAgIHJlZmVyZW5jZSAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIkVxdWlwbWVudCB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgRXF1aXBtZW50CiAgICBkb21haW4sIHdoaWNoIGlzIG1vZGVsbGVkIHRvIHVuZGVyc3RhbmQgdGhlIHBoeXNpY2FsIGxvY2F0aW9uIG9mIGVxdWlwbWVudAogICAgc3VjaCBhcyBhbnRlbm5hcyBhc3NvY2lhdGVkIHdpdGggYSBjZWxsL2NhcnJpZXIgYW5kIHRoZWlyIHJlbGV2YW50CiAgICBwcm9wZXJ0aWVzIGUuZy4gdGlsdCwgbWF4IHBvd2VyIGV0Yy4iOwoKICAgIHJldmlzaW9uICIyMDI0LTA1LTI0IiB7CiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmRvbWFpbiBFUVVJUE1FTlQ7CgogICAgbGlzdCBBbnRlbm5hTW9kdWxlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gQW50ZW5uYSBNb2R1bGUgcmVwcmVzZW50cyB0aGUgcGh5c2ljYWwgYXNwZWN0IG9mIGFuCiAgICAgICAgICAgIGFudGVubmEuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBhbnRlbm5hTW9kZWxOdW1iZXIgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlZlbmRvci1zcGVjaWZpYyBhbnRlbm5hIG1vZGVsIGlkZW50aWZpZXIuIFRoaXMKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGUgaXMgcGFydCBvZiBBSVNHIHYzIEFEQiBTdGFuZGFyZCBhbmQgaGFzIG5vCiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uYWwgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBtZWNoYW5pY2FsQW50ZW5uYUJlYXJpbmcgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgYmVhcmluZyBvbiBhbnRlbm5hIHN1YnVuaXQgd2hlcmUgYW50ZW5uYQogICAgICAgICAgICAgICAgICAgIHVuaXQgaXMgaW5zdGFsbGVkLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG1lY2hhbmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGZpeGVkIGFudGVubmEgdGlsdCBvZiB0aGUgaW5zdGFsbGF0aW9uLCBkZWZpbmVkCiAgICAgICAgICAgICAgICAgICAgYXMgdGhlIGluY2xpbmF0aW9uIG9mIHRoZSBhbnRlbm5hIGVsZW1lbnQgcmVzcGVjdCB0byB0aGUKICAgICAgICAgICAgICAgICAgICB2ZXJ0aWNhbCBwbGFuZS4gSXQgaXMgYSBzaWduZWQgdmFsdWUuIFBvc2l0aXZlIGluZGljYXRlcwogICAgICAgICAgICAgICAgICAgIGRvd250aWx0LCBhbmQgbmVnYXRpdmUgaW5kaWNhdGVzIHVwdGlsdC4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBwb3NpdGlvbldpdGhpblNlY3RvciB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSB1bml0IHBvc2l0aW9uIHdpdGhpbiBzZWN0b3IuIFRoaXMgYXR0cmlidXRlCiAgICAgICAgICAgICAgICAgICAgaXMgcGFydCBvZiBBSVNHIHYzIEFEQiBTdGFuZGFyZCBhbmQgaGFzIG5vIG9wZXJhdGlvbmFsCiAgICAgICAgICAgICAgICAgICAgaW1wYWN0LiI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiB0b3RhbFRpbHQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRvdGFsIGFudGVubmEgZWxldmF0aW9uIGluY2x1ZGluZyB0aGUgaW5zdGFsbGVkCiAgICAgICAgICAgICAgICAgICAgdGlsdCBhbmQgdGhlIHRpbHQgYXBwbGllZCBieSB0aGUgUmVtb3RlIEVsZWN0cmljYWwKICAgICAgICAgICAgICAgICAgICBUaWx0IChSRVQpLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVsZWN0cmljYWxBbnRlbm5hVGlsdCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiRWxlY3RyaWNhbGx5LWNvbnRyb2xsZWQgdGlsdCBvZiBtYWluIGJlYW0gbWF4aW11bQogICAgICAgICAgICAgICAgICAgIHdpdGggcmVzcGVjdCB0byBkaXJlY3Rpb24gb3J0aG9nb25hbCB0byBhbnRlbm5hIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICBheGlzIChzZWUgM0dQUCBUUyAyNS40NjYpLiBWYWx1ZSBpcyBzaWduZWQ7IHRpbHQgZG93biBpcwogICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlLCB0aWx0IHVwIGlzIG5lZ2F0aXZlLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmLWxpc3QgYW50ZW5uYUJlYW1XaWR0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGFuZ3VsYXIgc3BhbiBvZiB0aGUgbWFpbiBsb2JlIG9mIHRoZSBhbnRlbm5hCiAgICAgICAgICAgICAgICAgICAgcmFkaWF0aW9uIHBhdHRlcm4gaW4gdGhlIGhvcml6b250YWwgcGxhbmUuIE1lYXN1cmVkIGluCiAgICAgICAgICAgICAgICAgICAgZGVncmVlcy4iOwogICAgICAgICAgICAgICAgdHlwZSB1aW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzZXMgZ2VvOmdlby1sb2NhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgbGlzdCBTaXRlIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBzaXRlIGlzIGEgcGh5c2ljYWwgbG9jYXRpb24gd2hlcmUgYW4gZXF1aXBtZW50IGNhbiBiZQogICAgICAgICAgICBpbnN0YWxsZWQuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBuYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIFNpdGUiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHVzZXMgZ2VvOmdlby1sb2NhdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBBTlRFTk5BTU9EVUxFX0lOU1RBTExFRF9BVF9TSVRFIHsgLy8gMC4ubiB0byAwLi4xCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmIGluc3RhbGxlZC1hdC1zaXRlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIGluc3RhbGxlZCBhdCBTaXRlLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgaW5zdGFsbGVkLWFudGVubmFNb2R1bGUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2l0ZSB3aGVyZSBBbnRlbm5hIE1vZHVsZSBpcyBpbnN0YWxsZWQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIFNpdGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9Cn0=
+o-ran-smo-teiv-oam     urn:o-ran:smo-teiv-oam  OAM     []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LW9hbSB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtb2FtIjsKICAgIHByZWZpeCBvci10ZWl2LW9hbTsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggb3ItdGVpdi10eXBlczsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHsgcHJlZml4IG9yLXRlaXYteWV4dDsgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIk8mTSB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgTyZNIGRvbWFpbiwKICAgIHdoaWNoIGFyZSBpbnRlbmRlZCB0byByZXByZXNlbnQgbWFuYWdlbWVudCBzeXN0ZW1zIGFuZCBtYW5hZ2VtZW50CiAgICBpbnRlcmZhY2VzLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIE9BTTsKCiAgICBsaXN0IE1hbmFnZWRFbGVtZW50IHsKICAgICAgICBkZXNjcmlwdGlvbiAiQSBNYW5hZ2VkIEVsZW1lbnQgKE1FKSBpcyBhIG5vZGUgaW50byBhIHRlbGVjb21tdW5pY2F0aW9uCiAgICAgICAgICAgIG5ldHdvcmsgcHJvdmlkaW5nIHN1cHBvcnQgYW5kL29yIHNlcnZpY2UgdG8gc3Vic2NyaWJlcnMuIEFuIE1FCiAgICAgICAgICAgIGNvbW11bmljYXRlcyB3aXRoIGEgbWFuYWdlciBhcHBsaWNhdGlvbiAoZGlyZWN0bHkgb3IgaW5kaXJlY3RseSkKICAgICAgICAgICAgb3ZlciBvbmUgb3IgbW9yZSBpbnRlcmZhY2VzIGZvciB0aGUgcHVycG9zZSBvZiBiZWluZyBtb25pdG9yZWQKICAgICAgICAgICAgYW5kL29yIGNvbnRyb2xsZWQuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CiAgICB9Cn0=
+o-ran-smo-teiv-ran     urn:o-ran:smo-teiv-ran  RAN     []      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJhbiB7CiAgICB5YW5nLXZlcnNpb24gMS4xOwogICAgbmFtZXNwYWNlICJ1cm46by1yYW46c21vLXRlaXYtcmFuIjsKICAgIHByZWZpeCBvci10ZWl2LXJhbjsKCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctdHlwZXMge3ByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMge3ByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgXzNncHAtY29tbW9uLXlhbmctdHlwZXMgeyBwcmVmaXggdHlwZXMzZ3BwOyB9CgogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsKICAgICAgICBwcmVmaXggZ2VvOwogICAgICAgIHJlZmVyZW5jZSAiUkZDIDkxNzk6IEEgWUFORyBHcm91cGluZyBmb3IgR2VvZ3JhcGhpYyBMb2NhdGlvbnMiOwogICAgfQoKICAgIG9yZ2FuaXphdGlvbiAiRXJpY3Nzb24gQUIiOwogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7CiAgICBkZXNjcmlwdGlvbgogICAgIlJBTiB0b3BvbG9neSBtb2RlbC4KCiAgICBDb3B5cmlnaHQgKGMpIDIwMjQgRXJpY3Nzb24gQUIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgdG9wb2xvZ3kgZW50aXRpZXMgYW5kIHJlbGF0aW9ucyBpbiB0aGUgUkFOIGRvbWFpbiwKICAgIHdoaWNoIHJlcHJlc2VudHMgdGhlIGZ1bmN0aW9uYWwgY2FwYWJpbGl0eSBvZiB0aGUgZGVwbG95ZWQgUkFOIHRoYXQgYXJlCiAgICByZWxldmFudCB0byByQXBwcyB1c2UgY2FzZXMuIjsKCiAgICByZXZpc2lvbiAiMjAyNC0wNS0yNCIgewogICAgICAgIGRlc2NyaXB0aW9uICJJbml0aWFsIHJldmlzaW9uLiI7CiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOwogICAgfQoKICAgIG9yLXRlaXYteWV4dDpkb21haW4gUkFOOwoKICAgIGxpc3QgR05CRFVGdW5jdGlvbiB7CiAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQiBEaXN0cmlidXRlZCBVbml0IChnTkItRFUpLgoKICAgICAgICAgICAgQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ2VudHJhbGl6ZWQgVW5pdCAoZ05CLUNVKSBhbmQgYSBnTkItRFUuCiAgICAgICAgICAgIFRoZSBDVSBwcm9jZXNzZXMgbm9uLXJlYWwgdGltZSBwcm90b2NvbHMgYW5kIHNlcnZpY2VzLCBhbmQgdGhlIERVCiAgICAgICAgICAgIHByb2Nlc3NlcyBQSFkgbGV2ZWwgcHJvdG9jb2wgYW5kIHJlYWwgdGltZSBzZXJ2aWNlcy4gVGhlIGdOQi1DVSBhbmQKICAgICAgICAgICAgdGhlIGdOQi1EVSB1bml0cyBhcmUgY29ubmVjdGVkIHZpYSBGMSBsb2dpY2FsIGludGVyZmFjZS4KCiAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgaXMgdHJ1ZSBmb3IgYSBnTkItRFU6CiAgICAgICAgICAgIElzIGNvbm5lY3RlZCB0byB0aGUgZ05CLUNVLUNQIHRocm91Z2ggdGhlIEYxLUMgaW50ZXJmYWNlLiBJcwogICAgICAgICAgICBjb25uZWN0ZWQgdG8gdGhlIGdOQi1DVS1VUCB0aHJvdWdoIHRoZSBGMS1VIGludGVyZmFjZS4gT25lIGdOQi1EVSBpcwogICAgICAgICAgICBjb25uZWN0ZWQgdG8gb25seSBvbmUgZ05CLUNVLUNQLiBPbmUgZ05CLURVIGNhbiBiZSBjb25uZWN0ZWQgdG8KICAgICAgICAgICAgbXVsdGlwbGUgZ05CLUNVLVVQcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUgc2FtZSBnTkItQ1UtQ1AuCgogICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUgZ05CLUNVLVVQcyBhbmQKICAgICAgICAgICAgbXVsdGlwbGUgZ05CLURVcy4gZ05CLURVIGlzIGEgY29uY3JldGUgY2xhc3MgdGhhdCBleHRlbmRzIHRoZSBORy1SQU4KICAgICAgICAgICAgbm9kZSBvYmplY3QuIEluIFRvcG9sb2d5LCB5b3UgY2FuIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQgZGVsZXRlCiAgICAgICAgICAgIHRoZSBnTkItRFUgb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGNvbnRhaW5lciBkVXBMTU5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBpZGVudGlmaWVyIHVzZWQgYXMgcGFydCBvZiBQTSBFdmVudHMgZGF0YSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZ05CRFVJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBEVSB3aXRoaW4gYSBnTm9kZUIiOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEdOQkNVQ1BGdW5jdGlvbiB7CiAgICAgICAgZGVzY3JpcHRpb24gImdOb2RlQiBDZW50cmFsaXplZCBVbml0IENvbnRyb2wgUGxhbmUgKGdOQi1DVS1DUCkKCiAgICAgICAgICAgIFRoaXMgaXMgYSBsb2dpY2FsIG5vZGUgaG9zdGluZyB0aGUgUmFkaW8gUmVzb3VyY2UgQ29udHJvbCAoUlJDKSBhbmQKICAgICAgICAgICAgdGhlIGNvbnRyb2wgcGxhbmUgcGFydCBvZiB0aGUgUGFja2V0IERhdGEgQ29udmVyZ2VuY2UgUHJvdG9jb2wKICAgICAgICAgICAgKFBEQ1ApIG9mIHRoZSBnTm9kZUIgQ2VudHJhbGl6ZWQgVW5pdCAoZ05CLUNVKSBmb3IgYW4gRS1VVFJBTiBnTm9kZUIKICAgICAgICAgICAgKGVuLWdOQikgb3IgYSBnTm9kZUIgKGdOQikuIFRoZSBnTkItQ1UtQ1AgdGVybWluYXRlcyB0aGUgRTEKICAgICAgICAgICAgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTkItQ1UtVVAgYW5kIHRoZSBGMS1DIGludGVyZmFjZQogICAgICAgICAgICBjb25uZWN0ZWQgd2l0aCB0aGUgZ05vZGVCIERpc3RyaWJ1dGVkIFVuaXQgKGdOQi1EVSkuCgogICAgICAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIGEgZ05CLUNVLUNQOgogICAgICAgICAgICBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1EVSB0aHJvdWdoIHRoZSBGMS1DIGludGVyZmFjZS4gSXMgY29ubmVjdGVkCiAgICAgICAgICAgIHRvIHRoZSBnTkItQ1UtVVAgdGhyb3VnaCB0aGUgRTEgaW50ZXJmYWNlLiBPbmx5IG9uZSBnTkItQ1UtQ1AgaXMKICAgICAgICAgICAgY29ubmVjdGVkIHRvIG9uZSBnTkItRFUuIE9ubHkgb25lIGdOQi1DVS1DUCBpcyBjb25uZWN0ZWQgdG8gb25lCiAgICAgICAgICAgIGdOQi1DVS1VUC4gT25lIGdOQi1EVSBjYW4gYmUgY29ubmVjdGVkIHRvIG11bHRpcGxlIGdOQi1DVS1VUHMgdW5kZXIKICAgICAgICAgICAgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLk9uZSBnTkItQ1UtVVAgY2FuIGJlIGNvbm5lY3RlZCB0bwogICAgICAgICAgICBtdWx0aXBsZSBEVXMgdW5kZXIgdGhlIGNvbnRyb2wgb2YgdGhlIHNhbWUgZ05CLUNVLUNQLgoKICAgICAgICAgICAgTm90ZTogQSBnTkIgbWF5IGNvbnNpc3Qgb2YgYSBnTkItQ1UtQ1AsIG11bHRpcGxlIGdOQi1DVS1VUHMgYW5kCiAgICAgICAgICAgIG11bHRpcGxlIGdOQi1EVXMuIEEgZ05CLUNVLUNQIGlzIGEgY29uY3JldGUgY2xhc3MgdGhhdCBleHRlbmRzIHRoZQogICAgICAgICAgICBORy1SQU4gbm9kZSBvYmplY3QuIEluIFRvcG9sb2d5LCB5b3UgY2FuIGNyZWF0ZSwgcmVhZCwgdXBkYXRlLCBhbmQKICAgICAgICAgICAgZGVsZXRlIHRoZSBnTkItQ1UtQ1Agb2JqZWN0LiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZ05CQ1VOYW1lIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOYW1lIG9mIGdOb2RlQi1DVSI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIHBMTU5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBpZGVudGlmaWVyIHRvIGJlIHVzZWQgYXMgcGFydCBvZiBnbG9iYWwgUkFOCiAgICAgICAgICAgICAgICAgICAgbm9kZSBpZGVudGl0eSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBHTkJDVVVQRnVuY3Rpb24gewogICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUIgQ2VudHJhbGl6ZWQgVW5pdCBVc2VyIFBsYW5lIChnTkItQ1UtVVApCgogICAgICAgICAgICBBIGdOQi1DVS1VUCBpcyBhIGxvZ2ljYWwgbm9kZSBob3N0aW5nIHRoZSBVc2VyIFBsYW5lIHBhcnQgb2YgdGhlCiAgICAgICAgICAgIFBhY2tldCBEYXRhIENvbnZlcmdlbmNlLCBQcm90b2NvbCAoUERDUCkgb2YgdGhlIGdOb2RlQiBDZW50cmFsaXplZAogICAgICAgICAgICBVbml0IChnTkItQ1UpIGZvciBhbiBFLVVUUkFOIGdOb2RlQiAoZW4tZ05CKSwgYW5kIHRoZSBVc2VyIFBsYW5lCiAgICAgICAgICAgIHBhcnQgb2YgdGhlIFBEQ1AgcHJvdG9jb2wgYW5kIHRoZSBTZXJ2aWNlIERhdGEgQWRhcHRhdGlvbiBQcm90b2NvbAogICAgICAgICAgICAoU0RBUCkgb2YgdGhlIGdOQi1DVSBmb3IgYSBnTm9kZUIgKGdOQikuIFRoZSBnTkItQ1UtVVAgdGVybWluYXRlcwogICAgICAgICAgICB0aGUgRTEgaW50ZXJmYWNlIGNvbm5lY3RlZCB3aXRoIHRoZSBnTkItQ1UtQ1AgYW5kIHRoZSBGMS1VIGludGVyZmFjZQogICAgICAgICAgICBjb25uZWN0ZWQgd2l0aCB0aGUgZ05vZGVCIERpc3RyaWJ1dGVkIFVuaXQgKGdOQi1EVSkuCgogICAgICAgICAgICBUaGUgZm9sbG93aW5nIGlzIHRydWUgZm9yIGEgZ05CLUNVLVVQOgogICAgICAgICAgICBJcyBjb25uZWN0ZWQgdG8gdGhlIGdOQi1EVSB0aHJvdWdoIHRoZSBGMS1VIGludGVyZmFjZS4gSXMgY29ubmVjdGVkCiAgICAgICAgICAgIHRvIHRoZSBnTkItQ1UtQ1AgdGhyb3VnaCB0aGUgRTEgaW50ZXJmYWNlLiBPbmUgZ05CLUNVLVVQIGlzCiAgICAgICAgICAgIGNvbm5lY3RlZCB0byBvbmx5IG9uZSBnTkItQ1UtQ1AuIE9uZSBnTkItRFUgY2FuIGJlIGNvbm5lY3RlZCB0bwogICAgICAgICAgICBtdWx0aXBsZSBnTkItQ1UtVVBzIHVuZGVyIHRoZSBjb250cm9sIG9mIHRoZSBzYW1lIGdOQi1DVS1DUC4gT25lCiAgICAgICAgICAgIGdOQi1DVS1VUCBjYW4gYmUgY29ubmVjdGVkIHRvIG11bHRpcGxlIERVcyB1bmRlciB0aGUgY29udHJvbCBvZiB0aGUKICAgICAgICAgICAgc2FtZSBnTkItQ1UtQ1AuCgogICAgICAgICAgICBOb3RlOiBBIGdOQiBtYXkgY29uc2lzdCBvZiBhIGdOQi1DVS1DUCwgbXVsdGlwbGUgZ05CLUNVLVVQcyBhbmQKICAgICAgICAgICAgbXVsdGlwbGUgZ05CLURVcy4gQSBnTkItQ1UtVVAgaXMgYSBjb25jcmV0ZSBjbGFzcyB0aGF0IGV4dGVuZHMgdGhlCiAgICAgICAgICAgIE5HLVJBTiBub2RlIG9iamVjdC4gSW4gVG9wb2xvZ3ksIHlvdSBjYW4gY3JlYXRlLCByZWFkLCB1cGRhdGUsIGFuZAogICAgICAgICAgICBkZWxldGUgdGhlIGdOQi1DVS1VUCBvYmplY3QuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBnTkJJZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSWRlbnRpdHkgb2YgZ05vZGVCIHdpdGhpbiBhIFBMTU4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBnTkJJZExlbmd0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVuZ3RoIG9mIGdOQklkIGJpdCBzdHJpbmcgcmVwcmVzZW50YXRpb24iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IE5SQ2VsbENVIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyBhbiBOUiBDZWxsIGluIGdOb2RlQi1DVS4KCiAgICAgICAgICAgIDVHIE5SIGlzIGEgbmV3IHJhZGlvIGFjY2VzcyB0ZWNobm9sb2d5IChSQVQpIGRldmVsb3BlZCBieSAzR1BQIGZvcgogICAgICAgICAgICB0aGUgNUcgKGZpZnRoIGdlbmVyYXRpb24pIG1vYmlsZSBuZXR3b3JrLiBJdCBpcyBkZXNpZ25lZCB0byBiZSB0aGUKICAgICAgICAgICAgZ2xvYmFsIHN0YW5kYXJkIGZvciB0aGUgYWlyIGludGVyZmFjZSBvZiA1RyBuZXR3b3Jrcy4KCiAgICAgICAgICAgIDVHIE5SIGhhcyBzeW5jaHJvbml6YXRpb24gc2lnbmFsIHRoYXQgaXMga25vd24gYXMgUHJpbWFyeQogICAgICAgICAgICBTeW5jaHJvbml6YXRpb24gU2lnbmFsIChQU1MpIGFuZCBTZWNvbmRhcnkgU3luY2hyb25pemF0aW9uCiAgICAgICAgICAgIFNpZ25hbCAoU1NTKS4gVGhlc2Ugc2lnbmFscyBhcmUgc3BlY2lmaWMgdG8gTlIgcGh5c2ljYWwgbGF5ZXIgYW5kCiAgICAgICAgICAgIHByb3ZpZGUgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiByZXF1aXJlZCBieSBVRSBmb3IgZG93bmxpbmsKICAgICAgICAgICAgc3luY2hyb25pemF0aW9uOiBQU1MgcHJvdmlkZXMgUmFkaW8gRnJhbWUgQm91bmRhcnkgKFBvc2l0aW9uIG9mIDFzdAogICAgICAgICAgICBTeW1ib2wgaW4gYSBSYWRpbyBmcmFtZSkgU1NTIHByb3ZpZGVzIFN1YmZyYW1lIEJvdW5kYXJ5IChQb3NpdGlvbiBvZgogICAgICAgICAgICAxc3QgU3ltYm9sIGluIGEgU3ViZnJhbWUpIFBoeXNpY2FsIExheWVyIENlbGwgSUQgKFBDSSkgaW5mb3JtYXRpb24KICAgICAgICAgICAgdXNpbmcgYm90aCBQU1MgYW5kIFNTUy4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIGNlbGxMb2NhbElkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJVc2VkIHRvZ2V0aGVyIHdpdGggZ05vZGVCIGlkZW50aWZpZXIgdG8gaWRlbnRpZnkgTlIKICAgICAgICAgICAgICAgICAgICBjZWxsIGluIFBMTU4uIFVzZWQgdG9nZXRoZXIgd2l0aCBnTkJJZCB0byBmb3JtIE5DSS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29udGFpbmVyIHBsbW5JZCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUExNTiBJRCBmb3IgTlIgQ0dJLiBJZiBlbXB0eSwKICAgICAgICAgICAgICAgICAgICBHTkJDVUNQRnVuY3Rpb246OnBMTU5JZCBpcyB1c2VkIGZvciBQTE1OIElEIGluIE5SIENHSSI7CiAgICAgICAgICAgICAgICB1c2VzIHR5cGVzM2dwcDpQTE1OSWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgbkNJIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsIElkZW50aXR5IjsKICAgICAgICAgICAgICAgIHR5cGUgaW50NjQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgblJUQUMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKSI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTlJDZWxsRFUgewogICAgICAgIGRlc2NyaXB0aW9uICJSZXByZXNlbnRzIGFuIE5SIENlbGwgaW4gZ05vZGVCLURVLgoKICAgICAgICAgICAgNUcgTlIgaXMgYSBuZXcgcmFkaW8gYWNjZXNzIHRlY2hub2xvZ3kgKFJBVCkgZGV2ZWxvcGVkIGJ5IDNHUFAgZm9yCiAgICAgICAgICAgIHRoZSA1RyAoZmlmdGggZ2VuZXJhdGlvbikgbW9iaWxlIG5ldHdvcmsuIEl0IGlzIGRlc2lnbmVkIHRvIGJlIHRoZQogICAgICAgICAgICBnbG9iYWwgc3RhbmRhcmQgZm9yIHRoZSBhaXIgaW50ZXJmYWNlIG9mIDVHIG5ldHdvcmtzLgoKICAgICAgICAgICAgNUcgTlIgaGFzIHN5bmNocm9uaXphdGlvbiBzaWduYWwgdGhhdCBpcyBrbm93biBhcyBQcmltYXJ5CiAgICAgICAgICAgIFN5bmNocm9uaXphdGlvbiBzaWduYWwgKFBTUykgYW5kIFNlY29uZGFyeSBTeW5jaHJvbml6YXRpb24gc2lnbmFsCiAgICAgICAgICAgIChTU1MpLiBUaGVzZSBzaWduYWxzIGFyZSBzcGVjaWZpYyB0byBOUiBwaHlzaWNhbCBsYXllciBhbmQgcHJvdmlkZQogICAgICAgICAgICB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIHJlcXVpcmVkIGJ5IFVFIGZvciBkb3dubGluawogICAgICAgICAgICBzeW5jaHJvbml6YXRpb246IFBTUyBwcm92aWRlcyBSYWRpbyBGcmFtZSBCb3VuZGFyeSAoUG9zaXRpb24gb2YgMXN0CiAgICAgICAgICAgIFN5bWJvbCBpbiBhIFJhZGlvIGZyYW1lKSBTU1MgcHJvdmlkZXMgU3ViZnJhbWUgQm91bmRhcnkgKFBvc2l0aW9uIG9mCiAgICAgICAgICAgIDFzdCBTeW1ib2wgaW4gYSBTdWJmcmFtZSkgUGh5c2ljYWwgTGF5ZXIgQ2VsbCBJRCAoUENJKSBpbmZvcm1hdGlvbgogICAgICAgICAgICB1c2luZyBib3RoIFBTUyBhbmQgU1NTLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgY2VsbExvY2FsSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlVzZWQgdG9nZXRoZXIgd2l0aCBnTm9kZUIgaWRlbnRpZmllciB0byBpZGVudGlmeSBOUgogICAgICAgICAgICAgICAgICAgIGNlbGwgaW4gUExNTi4gVXNlZCB0b2dldGhlciB3aXRoIGdOQklkIHRvIGZvcm0gTkNJLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIG5DSSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbCBJZGVudGl0eS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBuUlBDSSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIFBoeXNpY2FsIENlbGwgSWRlbnRpdHkgKFBDSSkgb2YgdGhlIE5SIGNlbGwuIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgblJUQUMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFRyYWNraW5nIEFyZWEgQ29kZSAoVEFDKS4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IEVOb2RlQkZ1bmN0aW9uIHsKICAgICAgICBkZXNjcmlwdGlvbiAiQW4gRXZvbHZlZCBOb2RlIEIgKGVOb2RlQikgaXMgdGhlIG9ubHkgbWFuZGF0b3J5IG5vZGUgaW4KICAgICAgICAgICAgdGhlIHJhZGlvIGFjY2VzcyBuZXR3b3JrIChSQU4pIG9mIExvbmctVGVybSBFdm9sdXRpb24gKExURSkuIFRoZQogICAgICAgICAgICBlTm9kZUIgaXMgYSBjb21wbGV4IGJhc2Ugc3RhdGlvbiB0aGF0IGhhbmRsZXMgcmFkaW8gY29tbXVuaWNhdGlvbnMKICAgICAgICAgICAgaW4gdGhlIGNlbGwgYW5kIGNhcnJpZXMgb3V0IHJhZGlvIHJlc291cmNlIG1hbmFnZW1lbnQgYW5kIGhhbmRvdmVyCiAgICAgICAgICAgIGRlY2lzaW9ucy4gVW5saWtlIDIvM0cgd2lyZWxlc3MgUkFOLCB0aGVyZSBpcyBubyBjZW50cmFsaXplZCByYWRpbwogICAgICAgICAgICBuZXR3b3JrIGNvbnRyb2xsZXIgaW4gTFRFLiBJdCBpcyB0aGUgaGFyZHdhcmUgdGhhdCBpcyBjb25uZWN0ZWQgdG8KICAgICAgICAgICAgdGhlIG1vYmlsZSBwaG9uZSBuZXR3b3JrIHRoYXQgY29tbXVuaWNhdGVzIGRpcmVjdGx5IHdpdGggbW9iaWxlCiAgICAgICAgICAgIGhhbmRzZXRzIChVc2VyIEVxdWlwbWVudCksIGxpa2UgYSBiYXNlIHRyYW5zY2VpdmVyIHN0YXRpb24gKEJUUykgaW4KICAgICAgICAgICAgR1NNIG5ldHdvcmtzLiBUaGlzIHNpbXBsaWZpZXMgdGhlIGFyY2hpdGVjdHVyZSBhbmQgYWxsb3dzIGxvd2VyCiAgICAgICAgICAgIHJlc3BvbnNlIHRpbWVzLiI7CgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7CiAgICAgICAgICAgIGxlYWYgZU5CSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgSUQgdGhhdCBmb3JtcyBwYXJ0IG9mIHRoZSBDZWxsIEdsb2JhbAogICAgICAgICAgICAgICAgICAgIElkZW50aXR5LCBhbmQgaXMgYWxzbyB1c2VkIHRvIGlkZW50aWZ5IHRoZSBub2RlIG92ZXIgdGhlIFMxCiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRhaW5lciBlTm9kZUJQbG1uSWQgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFTm9kZUIgUHVibGljIExhbmQgTW9iaWxlIE5ldHdvcmsgKFBMTU4pIElECiAgICAgICAgICAgICAgICAgICAgdGhhdCBmb3JtcyBwYXJ0IG9mIHRoZSBFTm9kZUIgR2xvYmFsIElEIHVzZWQgdG8gaWRlbnRpZnkgdGhlCiAgICAgICAgICAgICAgICAgICAgbm9kZSBvdmVyIHRoZSBTMSBpbnRlcmZhY2UuIE5vdGU6IFRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIChNQ0M9MDAxLCBNTkM9MDEpIGluZGljYXRlcyB0aGF0IHRoZSBQTE1OIGlzIG5vdCBpbml0aWF0ZWQuCiAgICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIGNhbiBub3QgYmUgdXNlZCBhcyBhIHZhbGlkIFBMTU4gSWRlbnRpdHkuIjsKCiAgICAgICAgICAgICAgICBsZWFmIG1jYyB7CiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBNQ0MgcGFydCBvZiBhIFBMTU4gaWRlbnRpdHkgdXNlZCBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgcmFkaW8gbmV0d29yay4iOwogICAgICAgICAgICAgICAgICAgIHR5cGUgaW50MzIgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZSAwLi45OTk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGVhZiBtbmMgewogICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTU5DIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5IHVzZWQgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgIHJhZGlvIG5ldHdvcmsuIjsKICAgICAgICAgICAgICAgICAgICB0eXBlIGludDMyIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgMC4uOTk5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxlYWYgbW5jTGVuZ3RoIHsKICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGxlbmd0aCBvZiB0aGUgTU5DIHBhcnQgb2YgYSBQTE1OIGlkZW50aXR5CiAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgaW4gdGhlIHJhZGlvIG5ldHdvcmsuIjsKICAgICAgICAgICAgICAgICAgICB0eXBlIGludDMyIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgMi4uMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBFVXRyYW5DZWxsIHsKICAgICAgICBkZXNjcmlwdGlvbiAiUmVwcmVzZW50cyBhbiBGREQgb3IgVEREIEVVdHJhbkNlbGwgYW5kCiAgICAgICAgICAgICAgICAgICAgY29udGFpbnMgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNlbGwuCiAgICAgICAgICAgICAgICAgICAgSXQgYWxzbyBjb250YWlucyBwYXJhbWV0ZXJzIGZvciB0aGUKICAgICAgICAgICAgICAgICAgICBtYW5kYXRvcnkgY29tbW9uIGNoYW5uZWxzLiBBbiBFVVRSQU4gc3RhbmRzCiAgICAgICAgICAgICAgICAgICAgZm9yIEV2b2x2ZWQgVW5pdmVyc2FsIE1vYmlsZSBUZWxlY29tbXVuaWNhdGlvbnMKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0gKFVNVFMpIFRlcnJlc3RyaWFsIFJhZGlvIEFjY2VzcyBOZXR3b3JrCiAgICAgICAgICAgICAgICAgICAgd2hpY2ggY29udGFpbnMgYW4gZU5vZGVCLiBUaGUgZU5vZGVCIGNvbmNyZXRlCiAgICAgICAgICAgICAgICAgICAgY2xhc3MgaXMgZXh0ZW5kZWQgZnJvbSB0aGUgRVVUUkFOIE5vZGUgYWJzdHJhY3QgY2xhc3MuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBjZWxsSWR7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUkJTIGludGVybmFsIElEIGF0dHJpYnV0ZSBmb3IgRVV0cmFuQ2VsbC4gTXVzdCBiZQogICAgICAgICAgICAgICAgICAgIHVuaXF1ZSBpbiB0aGUgUkJTLiBUb2dldGhlciB3aXRoIHRoZSBOb2RlIElEIGFuZCBQdWJsaWMKICAgICAgICAgICAgICAgICAgICBMYW5kIE1vYmlsZSBOZXR3b3JrIChQTE1OKSB0aGlzIGlzIGEgdW5pdmVyc2FsbHkgdW5pcXVlCiAgICAgICAgICAgICAgICAgICAgY2VsbCBJRCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVhcmZjbmRsIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUaGUgY2hhbm5lbCBudW1iZXIgZm9yIHRoZSBjZW50cmFsIGRvd25saW5rCiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5LiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGVhcmZjbnVsIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJDaGFubmVsIG51bWJlciBmb3IgdGhlIGNlbnRyYWwgdXBsaW5rIGZyZXF1ZW5jeSI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGRsQ2hhbm5lbEJhbmR3aWR0aCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVGhlIGRvd25saW5rIGNoYW5uZWwgYmFuZHdpZHRoIGluIHRoZSBGREQgY2VsbC4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBlYXJmY24gewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBFLVVUUkEgQWJzb2x1dGUgUmFkaW8gRnJlcXVlbmN5IENoYW5uZWwgTnVtYmVyCiAgICAgICAgICAgICAgICAgICAgKEVBUkZDTikgZm9yIHRoZSBUREQgY2VsbCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGNoYW5uZWxCYW5kd2lkdGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBjaGFubmVsIGJhbmR3aWR0aCBpbiB0aGUgVEREIGNlbGwuIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgdGFjIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJUcmFja2luZyBBcmVhIENvZGUgZm9yIHRoZSBFVXRyYW4gQ2VsbCI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGR1cGxleFR5cGUgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkluZGljYXRvciBvZiBFVXRyYW5DZWxsIHR5cGUsIEZERCBvciBUREQiOwogICAgICAgICAgICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgZW51bSBmZGQgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiRkREIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSB0ZGQgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAxOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiVEREIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgbGlzdCBOUlNlY3RvckNhcnJpZXIgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGUgTlIgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZSBhdHRyaWJ1dGVzIGZvcgogICAgICAgICAgICBkZWZpbmluZyB0aGUgbG9naWNhbCBjaGFyYWN0ZXJpc3RpY3Mgb2YgYSBjYXJyaWVyIChjZWxsKSBpbiBhCiAgICAgICAgICAgIHNlY3Rvci4gQSBzZWN0b3IgaXMgYSBjb3ZlcmFnZSBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbgogICAgICAgICAgICBoYXZpbmcgaXRzIG93biBhbnRlbm5hcywgcmFkaW8gcG9ydHMsIGFuZCBjb250cm9sIGNoYW5uZWxzLiBUaGUKICAgICAgICAgICAgY29uY2VwdCBvZiBzZWN0b3JzIHdhcyBkZXZlbG9wZWQgdG8gaW1wcm92ZSBjby1jaGFubmVsIGludGVyZmVyZW5jZQogICAgICAgICAgICBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zIHVzZSB0aHJlZSBzZWN0b3IKICAgICAgICAgICAgY2VsbHMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBhcmZjbkRMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBBYnNvbHV0ZSBSYWRpbyBGcmVxdWVuY3kgQ2hhbm5lbCBOdW1iZXIKICAgICAgICAgICAgICAgICAgICAoTlItQVJGQ04pIGZvciBkb3dubGluayI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZWFmIGFyZmNuVUwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIEFic29sdXRlIFJhZGlvIGZyZXF1ZW5jeSBDaGFubmVsIE51bWJlcgogICAgICAgICAgICAgICAgICAgIChOUi1BUkZDTikgZm9yIHVwbGluay4iOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBmcmVxdWVuY3lETCB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUkYgUmVmZXJlbmNlIEZyZXF1ZW5jeSBvZiBkb3dubGluayBjaGFubmVsIjsKICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYgZnJlcXVlbmN5VUwgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIlJGIFJlZmVyZW5jZSBGcmVxdWVuY3kgb2YgdXBsaW5rIGNoYW5uZWwiOwogICAgICAgICAgICAgICAgdHlwZSBpbnQzMjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZiBiU0NoYW5uZWxCd0RMIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJCUyBDaGFubmVsIGJhbmR3aWR0aCBpbiBNSHogZm9yIGRvd25saW5rLiI7CiAgICAgICAgICAgICAgICB0eXBlIGludDMyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgTFRFU2VjdG9yQ2FycmllciB7CiAgICAgICAgZGVzY3JpcHRpb24gIlRoZSBMVEUgU2VjdG9yIENhcnJpZXIgb2JqZWN0IHByb3ZpZGVzIHRoZSBhdHRyaWJ1dGVzIGZvcgogICAgICAgICAgICBkZWZpbmluZyB0aGUgbG9naWNhbCBjaGFyYWN0ZXJpc3RpY3Mgb2YgYSBjYXJyaWVyIChjZWxsKSBpbiBhCiAgICAgICAgICAgIHNlY3Rvci4gQSBzZWN0b3IgaXMgYSBjb3ZlcmFnZSBhcmVhIGFzc29jaWF0ZWQgd2l0aCBhIGJhc2Ugc3RhdGlvbgogICAgICAgICAgICBoYXZpbmcgaXRzIG93biBhbnRlbm5hcywgcmFkaW8gcG9ydHMsIGFuZCBjb250cm9sIGNoYW5uZWxzLiBUaGUKICAgICAgICAgICAgY29uY2VwdCBvZiBzZWN0b3JzIHdhcyBkZXZlbG9wZWQgdG8gaW1wcm92ZSBjby1jaGFubmVsIGludGVyZmVyZW5jZQogICAgICAgICAgICBpbiBjZWxsdWxhciBzeXN0ZW1zLCBhbmQgbW9zdCB3aXJlbGVzcyBzeXN0ZW1zIHVzZSB0aHJlZSBzZWN0b3IKICAgICAgICAgICAgY2VsbHMuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZiBzZWN0b3JDYXJyaWVyVHlwZSB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBzZWN0b3IgY2FycmllcgogICAgICAgICAgICAgICAgICAgIG1vZGVsbGVkIGJ5IE1PIFNlY3RvckNhcnJpZXIgaXMgYSBkaWdpdGFsIHNlY3Rvci4iOwogICAgICAgICAgICAgICAgdHlwZSBlbnVtZXJhdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgZW51bSBub3JtYWxfc2VjdG9yIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgMDsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5vdCBhIGRpZ2l0YWwgc2VjdG9yIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSBsZWZ0X2RpZ2l0YWxfc2VjdG9yIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgMTsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxlZnQgZGlnaXRhbCBzZWN0b3IgZm9yIDJEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gcmlnaHRfZGlnaXRhbF9zZWN0b3IgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAyOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUmlnaHQgZGlnaXRhbCBzZWN0b3IgZm9yIDJEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gbGVmdF9kaWdpdGFsX3NlY3Rvcl8zZHMgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAzOwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGVmdCBkaWdpdGFsIHNlY3RvciBmb3IgM0RTIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZW51bSByaWdodF9kaWdpdGFsX3NlY3Rvcl8zZHMgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA0OwogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiUmlnaHQgZGlnaXRhbCBzZWN0b3IgZm9yIDNEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVudW0gbWlkZGxlX2RpZ2l0YWxfc2VjdG9yXzNkcyB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDU7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNaWRkbGUgZGlnaXRhbCBzZWN0b3IgZm9yIDNEUyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGxpc3QgQW50ZW5uYUNhcGFiaWxpdHkgewogICAgICAgIGRlc2NyaXB0aW9uICJUaGlzIE1PIHNlcnZlcyBhcyBhIG1hcHBpbmcgYmV0d2VlbiB0aGUgY2VsbCBhbmQgdGhlIFJCUwogICAgICAgICAgICBlcXVpcG1lbnQgdXNlZCB0byBwcm92aWRlIGNvdmVyYWdlIGluIGEgY2VydGFpbiBnZW9ncmFwaGljYWwgYXJlYS4KICAgICAgICAgICAgVGhlIE1PIGFsc28gY29udHJvbHMgdGhlIG1heGltdW0gb3V0cHV0IHBvd2VyIG9mIHRoZSBzZWN0b3IuIjsKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGNvbnRhaW5lciBhdHRyaWJ1dGVzIHsKICAgICAgICAgICAgbGVhZi1saXN0IGVVdHJhbkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgTFRFIGZyZXF1ZW5jeSBiYW5kcyB0aGF0IGFzc29jaWF0ZWQKICAgICAgICAgICAgICAgICAgICBoYXJkd2FyZSBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbGVhZi1saXN0IGdlcmFuRnFCYW5kcyB7CiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbiAiTGlzdCBvZiBHRVJBTiBmcmVxdWVuY3kgYmFuZHMgdGhhdCBhc3NvY2lhdGVkCiAgICAgICAgICAgICAgICAgICAgaGFyZHdhcmUgc3VwcG9ydHMiOwogICAgICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxlYWYtbGlzdCBuUkZxQmFuZHMgewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkxpc3Qgb2YgTlIgZnJlcXVlbmN5IGJhbmRzIGFzc29jaWF0ZWQgaGFyZHdhcmUKICAgICAgICAgICAgICAgICAgICBzdXBwb3J0cyI7CiAgICAgICAgICAgICAgICB0eXBlIHN0cmluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBsaXN0IFNlY3RvciB7CiAgICAgICAgZGVzY3JpcHRpb24gIkEgZ3JvdXAgb2YgY28tbG9jYXRlZCBDZWxscyB0aGF0IGhhdmUgYSBzaGFyZWQKICAgICAgICAgICAgY292ZXJhZ2UgYXJlYS4iOwoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgY29udGFpbmVyIGF0dHJpYnV0ZXMgewogICAgICAgICAgICBsZWFmIHNlY3RvcklkIHsKICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uICJVbml2ZXJzYWxseSB1bmlxdWUgSUQgZ2VuZXJhdGVkIGJ5IHRoZSBzZWN0b3IncwogICAgICAgICAgICAgICAgICAgIGRpc2NvdmVyeSBtZWNoYW5pc20uIjsKICAgICAgICAgICAgICAgIHR5cGUgdWludDY0OwogICAgICAgICAgICB9CgogICAgICAgICAgICB1c2VzIGdlbzpnZW8tbG9jYXRpb247CgogICAgICAgICAgICBsZWFmIGF6aW11dGggewogICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gIkF2ZXJhZ2UgdmFsdWUgb2YgdGhlIGF6aW11dGhzIG9mIHRoZSBjZWxscwogICAgICAgICAgICAgICAgICAgIGNvbXByaXNpbmcgdGhlIHNlY3RvciwgZGV0ZXJtaW5lZCBkdXJpbmcgc2VjdG9yIGRpc2NvdmVyeS4iOwogICAgICAgICAgICAgICAgdHlwZSBkZWNpbWFsNjR7CiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1bml0cyAiZGVncmVlcyI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfRVVUUkFOQ0VMTCB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIEVVVFJBTiBDZWxsLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBFTm9kZUJGdW5jdGlvbjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBwcm92aWRlZC1ieS1lbm9kZWJGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCBwcm92aWRlZCBieSBlTm9kZUIgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEVVdHJhbkNlbGw7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5PREVCRlVOQ1RJT05fUFJPVklERVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZU5vZGVCIEZ1bmN0aW9uIHByb3ZpZGVzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHByb3ZpZGVkIGJ5IGVOb2RlQiBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTFRFU2VjdG9yQ2FycmllcjsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBHTkJEVUZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTERVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIENlbGwtRFUuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIEdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgcHJvdmlkZWQtYnktZ25iZHVGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLURVIHByb3ZpZGVkIGJ5IGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CRFVGVU5DVElPTl9QUk9WSURFU19OUlNFQ1RPUkNBUlJJRVIgeyAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBwcm92aWRlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLURVIEZ1bmN0aW9uIHByb3ZpZGVzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBHTkJEVUZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmR1RnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgU2VjdG9yIENhcnJpZXIgcHJvdmlkZWQgYnkgZ05vZGVCLURVIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUlNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgR05CQ1VDUEZVTkNUSU9OX1BST1ZJREVTX05SQ0VMTENVIHsgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgcHJvdmlkZWQtbnJDZWxsQ3UgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVQ1AgRnVuY3Rpb24gcHJvdmlkZXMgTlIgQ2VsbC1DVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgR05CQ1VDUEZ1bmN0aW9uOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIHByb3ZpZGVkLWJ5LWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBDZWxsLUNVIHByb3ZpZGVkIGJ5IGdOb2RlQi1DVUNQIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBOUkNlbGxDVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgICAgICBtYW5kYXRvcnkgdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBFVVRSQU5DRUxMX1VTRVNfTFRFU0VDVE9SQ0FSUklFUiB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IHVzZWQtbHRlU2VjdG9yQ2FycmllciB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJFVVRSQU4gQ2VsbCB1c2VzIExURSBTZWN0b3IgQ2Fycmllci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRVV0cmFuQ2VsbDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTFRFIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgRVVUUkFOIENlbGwuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBMVEVTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJMVEUgU2VjdG9yIENhcnJpZXIgdXNlcyBBbnRlbm5hIENhcGFiaWxpdHkuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIExURVNlY3RvckNhcnJpZXI7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYtbGlzdCB1c2VkLWJ5LWx0ZVNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTFRFIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBBbnRlbm5hQ2FwYWJpbGl0eTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KICAgIH0KCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE5SQ0VMTERVX1VTRVNfTlJTRUNUT1JDQVJSSUVSIHsgLy8gMC4uMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSB1c2VzIE5SIFNlY3RvciBDYXJyaWVyLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBOUkNlbGxEVTsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiB1c2VkLWJ5LW5yQ2VsbER1IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk5SIFNlY3RvciBDYXJyaWVyIHVzZWQgYnkgTlIgQ2VsbC1EVS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTlJTRUNUT1JDQVJSSUVSX1VTRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLjEKCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYgdXNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJOUiBTZWN0b3IgQ2FycmllciB1c2VzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgTlJTZWN0b3JDYXJyaWVyOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3QgdXNlZC1ieS1uclNlY3RvckNhcnJpZXIgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiQW50ZW5uYSBDYXBhYmlsaXR5IHVzZWQgYnkgTlIgU2VjdG9yIENhcnJpZXIuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEFudGVubmFDYXBhYmlsaXR5OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgU0VDVE9SX0dST1VQU19OUkNFTExEVSB7IC8vIDAuLjEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IGdyb3VwZWQtbnJDZWxsRHUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBOUiBDZWxsLURVLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBTZWN0b3I7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgZ3JvdXBlZC1ieS1zZWN0b3IgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTlIgQ2VsbC1EVSBncm91cGVkIGJ5IFNlY3Rvci4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgTlJDZWxsRFU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBTRUNUT1JfR1JPVVBTX0VVVFJBTkNFTEwgeyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWV1VHJhbkNlbGwgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBFVVRSQU4gQ2VsbC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgU2VjdG9yOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGdyb3VwZWQtYnktc2VjdG9yIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkVVVFJBTiBDZWxsIGdyb3VwZWQgYnkgU2VjdG9yLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBFVXRyYW5DZWxsOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQogICAgfQp9
+o-ran-smo-teiv-rel-equipment-ran       urn:o-ran:smo-teiv-rel-equipment-ran    REL_EQUIPMENT_RAN       ["o-ran-smo-teiv-equipment", "o-ran-smo-teiv-ran"]      2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJlbC1lcXVpcG1lbnQtcmFuIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1yZWwtZXF1aXBtZW50LXJhbiI7CiAgICBwcmVmaXggb3ItdGVpdi1yZWwtZXF1aXByYW47CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsgcHJlZml4IG9yLXRlaXYtdHlwZXM7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7IHByZWZpeCBvci10ZWl2LXlleHQ7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtZXF1aXBtZW50IHsgcHJlZml4IG9yLXRlaXYtZXF1aXA7IH0KCiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtcmFuIHsgcHJlZml4IG9yLXRlaXYtcmFuOyB9CgogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7CiAgICBjb250YWN0ICJFcmljc3NvbiBmaXJzdCBsaW5lIHN1cHBvcnQgdmlhIGVtYWlsIjsKICAgIGRlc2NyaXB0aW9uCiAgICAiRXF1aXBtZW50IGFuZCBSQU4gdG9wb2xvZ3kgcmVsYXRpb24gbW9kZWwuCgogICAgQ29weXJpZ2h0IChjKSAyMDI0IEVyaWNzc29uIEFCLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoKICAgIFRoaXMgbW9kZWwgY29udGFpbnMgdGhlIHRvcG9sb2d5IHJlbGF0aW9ucyBiZXR3ZWVuIEVxdWlwbWVudCBhbmQgUkFOLiI7CgogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsKICAgICAgICBkZXNjcmlwdGlvbiAiSW5pdGlhbCByZXZpc2lvbi4iOwogICAgICAgIG9yLXRlaXYteWV4dDpsYWJlbCAwLjMuMDsKICAgIH0KCiAgICBvci10ZWl2LXlleHQ6ZG9tYWluIFJFTF9FUVVJUE1FTlRfUkFOOwoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgQU5URU5OQU1PRFVMRV9TRVJWRVNfQU5URU5OQUNBUEFCSUxJVFkgeyAvLyAwLi5uIHRvIDAuLm0KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBzZXJ2aWNlZC1hbnRlbm5hQ2FwYWJpbGl0eSB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJBbnRlbm5hIENhcGFiaWxpdHkgc2VydmljZWQgYnkgdGhpcyBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1lcXVpcDpBbnRlbm5hTW9kdWxlOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmLWxpc3Qgc2VydmluZy1hbnRlbm5hTW9kdWxlIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIHNlcnZlcyB0aGlzIEFudGVubmEgQ2FwYWJpbGl0eS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46QW50ZW5uYUNhcGFiaWxpdHk7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBTRUNUT1JfR1JPVVBTX0FOVEVOTkFNT0RVTEUgeyAvLyAwLi4xIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWFudGVubmFNb2R1bGUgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiU2VjdG9yIGdyb3VwcyBBbnRlbm5hIE1vZHVsZS4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1yYW46U2VjdG9yOwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIGdyb3VwZWQtYnktc2VjdG9yIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIkFudGVubmEgTW9kdWxlIGdyb3VwZWQgYnkgU2VjdG9yLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LWVxdWlwOkFudGVubmFNb2R1bGU7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CiAgICB9Cn0=
+o-ran-smo-teiv-rel-oam-ran     urn:o-ran:smo-teiv-rel-oam-ran  REL_OAM_RAN     ["o-ran-smo-teiv-oam", "o-ran-smo-teiv-ran"]    2024-05-24      bW9kdWxlIG8tcmFuLXNtby10ZWl2LXJlbC1vYW0tcmFuIHsKICAgIHlhbmctdmVyc2lvbiAxLjE7CiAgICBuYW1lc3BhY2UgInVybjpvLXJhbjpzbW8tdGVpdi1yZWwtb2FtLXJhbiI7CiAgICBwcmVmaXggb3ItdGVpdi1yZWwtb2FtcmFuOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCBvci10ZWl2LXR5cGVzOyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLWV4dGVuc2lvbnMgeyBwcmVmaXggb3ItdGVpdi15ZXh0OyB9CgogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LW9hbSB7IHByZWZpeCBvci10ZWl2LW9hbTsgfQoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1yYW4geyBwcmVmaXggb3ItdGVpdi1yYW47IH0KCiAgICBvcmdhbml6YXRpb24gIk9SQU4iOwogICAgY29udGFjdCAiVGhlIEF1dGhvcnMiOwogICAgZGVzY3JpcHRpb24KICAgICJSQU4gTyZNIHRvIExvZ2ljYWwgdG9wb2xvZ3kgbW9kZWwuCgogICAgVGhpcyBtb2RlbCBjb250YWlucyB0aGUgUkFOIE8mTSB0byBMb2dpY2FsIHRvcG9sb2d5IHJlbGF0aW9ucwoKICAgIENvcHlyaWdodCAoQykgMjAyNCBFcmljc3NvbgogICAgTW9kaWZpY2F0aW9ucyBDb3B5cmlnaHQgKEMpIDIwMjQgT3BlbkluZnJhIEZvdW5kYXRpb24gRXVyb3BlCgogICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsKICAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUywKICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCgogICAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjAiOwoKICAgIHJldmlzaW9uICIyMDI0LTA1LTI0IiB7CiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgb3ItdGVpdi15ZXh0OmRvbWFpbiBSRUxfT0FNX1JBTjsKCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIE1BTkFHRURFTEVNRU5UX01BTkFHRVNfRU5PREVCRlVOQ1RJT04geyAgIC8vIDEgdG8gMC4ubgoKICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOwogICAgICAgIGtleSBpZDsKCiAgICAgICAgbGVhZi1saXN0IG1hbmFnZWQtZW5vZGViRnVuY3Rpb24gewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiTWFuYWdlZCBFbGVtZW50IG1hbmFnZXMgZU5vZGVCIEZ1bmN0aW9uLiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBvci10ZWl2LW9hbTpNYW5hZ2VkRWxlbWVudDsKICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOwogICAgICAgIH0KCiAgICAgICAgbGVhZiBtYW5hZ2VkLWJ5LW1hbmFnZWRFbGVtZW50IHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gImVOb2RlQiBGdW5jdGlvbiBtYW5hZ2VkIGJ5IE1hbmFnZWQgRWxlbWVudC4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgb3ItdGVpdi1yYW46RU5vZGVCRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJEVUZVTkNUSU9OIHsgICAgLy8gMSB0byAwLi5uCgogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7CiAgICAgICAga2V5IGlkOwoKICAgICAgICBsZWFmLWxpc3QgbWFuYWdlZC1nbmJkdUZ1bmN0aW9uIHsKICAgICAgICAgICAgZGVzY3JpcHRpb24gIk1hbmFnZWQgRWxlbWVudCBtYW5hZ2VzIGdOb2RlQi1EVSBGdW5jdGlvbi4iOwogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgb3ItdGVpdi1vYW06TWFuYWdlZEVsZW1lbnQ7CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICB9CgogICAgICAgIGxlYWYgbWFuYWdlZC1ieS1tYW5hZ2VkRWxlbWVudCB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJnTm9kZUItRFUgRnVuY3Rpb24gbWFuYWdlZCBieSBNYW5hZ2VkIEVsZW1lbnQuIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIG9yLXRlaXYtcmFuOkdOQkRVRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVUNQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1Y3BGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtQ1AgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLUNQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVUNQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgTUFOQUdFREVMRU1FTlRfTUFOQUdFU19HTkJDVVVQRlVOQ1RJT04geyAgICAvLyAxIHRvIDAuLm4KCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsKICAgICAgICBrZXkgaWQ7CgogICAgICAgIGxlYWYtbGlzdCBtYW5hZ2VkLWduYmN1dXBGdW5jdGlvbiB7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uICJNYW5hZ2VkIEVsZW1lbnQgbWFuYWdlcyBnTm9kZUItQ1UtVVAgRnVuY3Rpb24uIjsKICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmFTaWRlIG9yLXRlaXYtb2FtOk1hbmFnZWRFbGVtZW50OwogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7CiAgICAgICAgfQoKICAgICAgICBsZWFmIG1hbmFnZWQtYnktbWFuYWdlZEVsZW1lbnQgewogICAgICAgICAgICBkZXNjcmlwdGlvbiAiZ05vZGVCLUNVLVVQIEZ1bmN0aW9uIG1hbmFnZWQgYnkgTWFuYWdlZCBFbGVtZW50LiI7CiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBvci10ZWl2LXJhbjpHTkJDVVVQRnVuY3Rpb247CiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsKICAgICAgICAgICAgbWFuZGF0b3J5IHRydWU7CiAgICAgICAgfQogICAgfQp9
 \.
 
-COPY ties_model.relationship_info("name", "aSideAssociationName", "aSideMOType", "aSideMinCardinality", "aSideMaxCardinality", "bSideAssociationName", "bSideMOType", "bSideMinCardinality", "bSideMaxCardinality", "associationKind", "relationshipDataLocation", "connectSameEntity", "moduleReferenceName") FROM stdin;
-MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN       managed-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        1       1       managed-by-managedElementttttttttttttttttttttttttttttttttttttttt        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-ran
-MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM       deployed-as-cloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        1       1       deployed-managedElementttttttttttttttttttttttttttttttttttttttttt        CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm        0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-oam-to-cloud
-MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN       realised-by-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        1       1       realised-managedElementttttttttttttttttttttttttttttttttttttttttt        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        1       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-cloud
-MANAGEDELEMENT_MANAGES_ENODEBFUNCTION  managed-enodebFunction  ManagedElement  1       1       managed-by-managedElement       ENodeBFunction  0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-ran
-MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION managed-gnbcucpFunction ManagedElement  1       1       managed-by-managedElement       GNBCUCPFunction 0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-ran
-MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION managed-gnbcuupFunction ManagedElement  1       1       managed-by-managedElement       GNBCUUPFunction 0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-ran
-MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION      realised-by-cloudNativeApplication      ManagedElement  1       1       realised-managedElement CloudNativeApplication  1       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-cloud
-MANAGEDELEMENT_MANAGES_GNBDUFUNCTION   managed-gnbduFunction   ManagedElement  1       1       managed-by-managedElement       GNBDUFunction   0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-oam-to-ran
-MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM   deployed-as-cloudNativeSystem   ManagedElement  1       1       deployed-managedElement CloudNativeSystem       0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-oam-to-cloud
-NODECLUSTER_LOCATED_AT_CLOUDSITE       located-at-cloudSite    NodeCluster     0       9223372036854775807     location-of-nodeCluster CloudSite       1       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-cloud
-CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION     comprised-cloudNativeApplication        CloudNativeSystem       0       1       comprised-by-cloudNativeSystem  CloudNativeApplication  0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-cloud
-CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE   deployed-on-namespace   CloudNativeApplication  0       9223372036854775807     deployed-cloudNativeApplication Namespace       0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-cloud
-CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE       deployed-on-namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        0       9223372036854775807     deployed-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-cloud
-NAMESPACE_DEPLOYED_ON_NODECLUSTER      deployed-on-nodeCluster Namespace       0       9223372036854775807     deployed-namespace      NodeCluster     1       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-cloud
-SECTOR_GROUPS_EUTRANCELL       grouped-euTranCell      Sector  0       1       grouped-by-sector       EUtranCell      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-equipment-to-ran
-SECTOR_GROUPS_ANTENNAMODULE    grouped-antennaModule   Sector  0       1       grouped-by-sector       AntennaModule   0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-equipment-to-ran
-SECTOR_GROUPS_NRCELLDU grouped-nrCellDu        Sector  0       1       grouped-by-sector       NRCellDU        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION     realised-by-cloudNativeApplication      GNBCUUPFunction 0       9223372036854775807     realised-gnbcuupFunction        CloudNativeApplication  0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-cloud-to-ran
-ENODEBFUNCTION_PROVIDES_EUTRANCELL     provided-euTranCell     ENodeBFunction  1       1       provided-by-enodebFunction      EUtranCell      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER       provided-lteSectorCarrier       ENodeBFunction  1       1       provided-by-enodebFunction      LTESectorCarrier        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE    realised-by-physicalNetworkAppliance    ENodeBFunction  0       9223372036854775807     realised-enodebFunction PhysicalNetworkAppliance        0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-equipment-to-ran
-NRCELLDU_USES_NRSECTORCARRIER  used-nrSectorCarrier    NRCellDU        0       1       used-by-nrCellDu        NRSectorCarrier 0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-LTESECTORCARRIER_USES_ANTENNACAPABILITY        used-antennaCapability  LTESectorCarrier        0       1       used-by-lteSectorCarrier        AntennaCapability       0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-ran
-GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION       realised-by-cloudNativeApplication      GNBDUFunction   0       9223372036854775807     realised-gnbduFunction  CloudNativeApplication  0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-cloud-to-ran
-GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER provided-nrSectorCarrier        GNBDUFunction   1       1       provided-by-gnbduFunction       NRSectorCarrier 0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-GNBDUFUNCTION_PROVIDES_NRCELLDU        provided-nrCellDu       GNBDUFunction   1       1       provided-by-gnbduFunction       NRCellDU        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN       realised-by-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        0       9223372036854775807     realised-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-cloud-to-ran
-GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU       provided-nrCellDuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        1       1       provided-by-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-EUTRANCELL_USES_LTESECTORCARRIER       used-lteSectorCarrier   EUtranCell      0       1       used-by-euTranCell      LTESectorCarrier        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-GNBCUCPFUNCTION_PROVIDES_NRCELLCU      provided-nrCellCu       GNBCUCPFunction 1       1       provided-by-gnbcucpFunction     NRCellCU        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION     realised-by-cloudNativeApplication      GNBCUCPFunction 0       9223372036854775807     realised-gnbcucpFunction        CloudNativeApplication  0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-cloud-to-ran
-NRSECTORCARRIER_USES_ANTENNACAPABILITY used-antennaCapability  NRSectorCarrier 0       9223372036854775807     used-by-nrSectorCarrier AntennaCapability       0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-ran
-ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE    realised-by-antennaModule       AntennaCapability       0       9223372036854775807     realised-antennaCapability      AntennaModule   0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-equipment-to-ran
-TESTENTITYA_PROVIDES_TESTENTITYB       provided-testEntityB    TestEntityA     0       2       provided-by-testEntityA TestEntityB     0       3       BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-ran
-TESTENTITYA_USES_TESTENTITYB   used-TestEntityB        TestEntityA     0       1       used-by-testEntityA     TestEntityB     0       2       BI_DIRECTIONAL  B_SIDE  false   o-ran-smo-teiv-ran
-TESTENTITYA_GROUPS_TESTENTITYB grouped-testEntityB     TestEntityA     0       2       grouped-by-testEntityA  TestEntityB     0       9223372036854775807     BI_DIRECTIONAL  RELATION        false   o-ran-smo-teiv-ran
-ANTENNAMODULE_INSTALLED_AT_SITE        installed-at-site       AntennaModule   0       9223372036854775807     installed-antennaModule Site    0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-equipment
-PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE     installed-at-site       PhysicalNetworkAppliance        0       9223372036854775807     installed-physicalNetworkAppliance      Site    0       1       BI_DIRECTIONAL  A_SIDE  false   o-ran-smo-teiv-equipment
-ANTENNAMODULE_REALISED_BY_ANTENNAMODULE        realised-by-antennaModule       AntennaModule   0       9223372036854775807     realised-antennaModule  AntennaModule   0       9223372036854775807     BI_DIRECTIONAL  RELATION        true    o-ran-smo-teiv-equipment
-ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE       realised-by-antennaModule       AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        0       1       realised-antennaModule  AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        0       9223372036854775807     BI_DIRECTIONAL  RELATION        true    o-ran-smo-teiv-equipment
-ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE       deployed-on-antennaModule       AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        0       1       deployed-antennaModule  AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        0       1       BI_DIRECTIONAL  RELATION        true    o-ran-smo-teiv-equipment
+
+COPY ties_model.entity_info("storedAt", "name", "moduleReferenceName") FROM stdin;
+o-ran-smo-teiv-ran-oam_ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        o-ran-smo-teiv-ran-oam
+o-ran-smo-teiv-ran-oam_ManagedElement  ManagedElement  o-ran-smo-teiv-ran-oam
+o-ran-smo-teiv-ran-cloud_NodeCluster   NodeCluster     o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_CloudNativeSystem     CloudNativeSystem       o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_CloudNativeApplication        CloudNativeApplication  o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm      CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm        o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_CloudSite     CloudSite       o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee      Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn      CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-cloud_Namespace     Namespace       o-ran-smo-teiv-ran-cloud
+o-ran-smo-teiv-ran-logical-to-equipment_Sector Sector  o-ran-smo-teiv-ran-logical-to-equipment
+o-ran-smo-teiv-ran-logical_GNBCUUPFunction     GNBCUUPFunction o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_ENodeBFunction      ENodeBFunction  o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU    NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU        o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_NRCellDU    NRCellDU        o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_LTESectorCarrier    LTESectorCarrier        o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_GNBDUFunction       GNBDUFunction   o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_NRCellCU    NRCellCU        o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn    GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-equipment_AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee  AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-equipment
+o-ran-smo-teiv-ran-logical_EUtranCell  EUtranCell      o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_GNBCUCPFunction     GNBCUCPFunction o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_NRSectorCarrier     NRSectorCarrier o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_AntennaCapability   AntennaCapability       o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_TestEntityB TestEntityB     o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-logical_TestEntityA TestEntityA     o-ran-smo-teiv-ran-logical
+o-ran-smo-teiv-ran-equipment_Site      Site    o-ran-smo-teiv-ran-equipment
+o-ran-smo-teiv-ran-equipment_AntennaModule     AntennaModule   o-ran-smo-teiv-ran-equipment
+o-ran-smo-teiv-ran-equipment_PhysicalNetworkAppliance  PhysicalNetworkAppliance        o-ran-smo-teiv-ran-equipment
+\.
+
+COPY ties_model.relationship_info("name", "aSideAssociationName", "aSideMOType", "aSideModule", "aSideMinCardinality", "aSideMaxCardinality", "bSideAssociationName", "bSideMOType", "bSideModule", "bSideMinCardinality", "bSideMaxCardinality", "associationKind", "relationshipDataLocation", "storedAt", "connectSameEntity", "moduleReferenceName") FROM stdin;
+MANAGEDELEMENTTTTTTTTTTTTTTT_MANAGES_GNBDUFUNCTIONNNNNNNNNNNNNNN       managed-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        o-ran-smo-teiv-ran-oam  1       1       managed-by-managedElementttttttttttttttttttttttttttttttttttttttt        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn     false   o-ran-smo-teiv-ran-oam-to-logical
+MANAGEDELEMENTTTTTTTTTTT_DEPLOYED_AS_CLOUDNATIVESYSTEMMMMMMMMMMM       deployed-as-cloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        o-ran-smo-teiv-ran-oam  1       1       deployed-managedElementttttttttttttttttttttttttttttttttttttttttt        CloudNativeSystemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm        o-ran-smo-teiv-ran-cloud        0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-oam_ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt false   o-ran-smo-teiv-ran-oam-to-cloud
+MANAGEDELEMENTTTTTTTTT_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNN       realised-by-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        ManagedElementtttttttttttttttttttttttttttttttttttttttttttttttttt        o-ran-smo-teiv-ran-oam  1       1       realised-managedElementttttttttttttttttttttttttttttttttttttttttt        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-cloud        1       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-cloud_CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn       false   o-ran-smo-teiv-ran-oam-to-cloud
+MANAGEDELEMENT_MANAGES_ENODEBFUNCTION  managed-enodebFunction  ManagedElement  o-ran-smo-teiv-ran-oam  1       1       managed-by-managedElement       ENodeBFunction  o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_ENodeBFunction       false   o-ran-smo-teiv-ran-oam-to-logical
+MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION managed-gnbcucpFunction ManagedElement  o-ran-smo-teiv-ran-oam  1       1       managed-by-managedElement       GNBCUCPFunction o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_GNBCUCPFunction      false   o-ran-smo-teiv-ran-oam-to-logical
+MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION managed-gnbcuupFunction ManagedElement  o-ran-smo-teiv-ran-oam  1       1       managed-by-managedElement       GNBCUUPFunction o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_GNBCUUPFunction      false   o-ran-smo-teiv-ran-oam-to-logical
+MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION      realised-by-cloudNativeApplication      ManagedElement  o-ran-smo-teiv-ran-oam  1       1       realised-managedElement CloudNativeApplication  o-ran-smo-teiv-ran-cloud        1       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-cloud_CloudNativeApplication false   o-ran-smo-teiv-ran-oam-to-cloud
+MANAGEDELEMENT_MANAGES_GNBDUFUNCTION   managed-gnbduFunction   ManagedElement  o-ran-smo-teiv-ran-oam  1       1       managed-by-managedElement       GNBDUFunction   o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_GNBDUFunction        false   o-ran-smo-teiv-ran-oam-to-logical
+MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM   deployed-as-cloudNativeSystem   ManagedElement  o-ran-smo-teiv-ran-oam  1       1       deployed-managedElement CloudNativeSystem       o-ran-smo-teiv-ran-cloud        0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-oam_ManagedElement   false   o-ran-smo-teiv-ran-oam-to-cloud
+NODECLUSTER_LOCATED_AT_CLOUDSITE       located-at-cloudSite    NodeCluster     o-ran-smo-teiv-ran-cloud        0       9223372036854775807     location-of-nodeCluster CloudSite       o-ran-smo-teiv-ran-cloud        1       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-cloud_NodeCluster    false   o-ran-smo-teiv-ran-cloud
+CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION     comprised-cloudNativeApplication        CloudNativeSystem       o-ran-smo-teiv-ran-cloud        0       1       comprised-by-cloudNativeSystem  CloudNativeApplication  o-ran-smo-teiv-ran-cloud        0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-cloud_CloudNativeApplication false   o-ran-smo-teiv-ran-cloud
+CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE   deployed-on-namespace   CloudNativeApplication  o-ran-smo-teiv-ran-cloud        0       9223372036854775807     deployed-cloudNativeApplication Namespace       o-ran-smo-teiv-ran-cloud        0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-cloud_CloudNativeApplication false   o-ran-smo-teiv-ran-cloud
+CLOUDNATIVEAPPLICATIONNNNNNNNNNN_DEPLOYED_ON_NAMESPACEEEEEEEEEEE       deployed-on-namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-cloud        0       9223372036854775807     deployed-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        Namespaceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-cloud        0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-cloud_CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn       false   o-ran-smo-teiv-ran-cloud
+NAMESPACE_DEPLOYED_ON_NODECLUSTER      deployed-on-nodeCluster Namespace       o-ran-smo-teiv-ran-cloud        0       9223372036854775807     deployed-namespace      NodeCluster     o-ran-smo-teiv-ran-cloud        1       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-cloud_Namespace      false   o-ran-smo-teiv-ran-cloud
+SECTOR_GROUPS_EUTRANCELL       grouped-euTranCell      Sector  o-ran-smo-teiv-ran-logical-to-equipment 0       1       grouped-by-sector       EUtranCell      o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_EUtranCell   false   o-ran-smo-teiv-ran-logical-to-equipment
+SECTOR_GROUPS_ANTENNAMODULE    grouped-antennaModule   Sector  o-ran-smo-teiv-ran-logical-to-equipment 0       1       grouped-by-sector       AntennaModule   o-ran-smo-teiv-ran-equipment    0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-equipment_AntennaModule      false   o-ran-smo-teiv-ran-logical-to-equipment
+SECTOR_GROUPS_NRCELLDU grouped-nrCellDu        Sector  o-ran-smo-teiv-ran-logical-to-equipment 0       1       grouped-by-sector       NRCellDU        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRCellDU     false   o-ran-smo-teiv-ran-logical-to-equipment
+GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION     realised-by-cloudNativeApplication      GNBCUUPFunction o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-gnbcuupFunction        CloudNativeApplication  o-ran-smo-teiv-ran-cloud        0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical-to-cloud_GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION  false   o-ran-smo-teiv-ran-logical-to-cloud
+ENODEBFUNCTION_PROVIDES_EUTRANCELL     provided-euTranCell     ENodeBFunction  o-ran-smo-teiv-ran-logical      1       1       provided-by-enodebFunction      EUtranCell      o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_EUtranCell   false   o-ran-smo-teiv-ran-logical
+ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER       provided-lteSectorCarrier       ENodeBFunction  o-ran-smo-teiv-ran-logical      1       1       provided-by-enodebFunction      LTESectorCarrier        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_LTESectorCarrier     false   o-ran-smo-teiv-ran-logical
+ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE    realised-by-physicalNetworkAppliance    ENodeBFunction  o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-enodebFunction PhysicalNetworkAppliance        o-ran-smo-teiv-ran-equipment    0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-logical_ENodeBFunction       false   o-ran-smo-teiv-ran-logical-to-equipment
+NRCELLDU_USES_NRSECTORCARRIER  used-nrSectorCarrier    NRCellDU        o-ran-smo-teiv-ran-logical      0       1       used-by-nrCellDu        NRSectorCarrier o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRSectorCarrier      false   o-ran-smo-teiv-ran-logical
+LTESECTORCARRIER_USES_ANTENNACAPABILITY        used-antennaCapability  LTESectorCarrier        o-ran-smo-teiv-ran-logical      0       1       used-by-lteSectorCarrier        AntennaCapability       o-ran-smo-teiv-ran-logical      0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-logical_LTESectorCarrier     false   o-ran-smo-teiv-ran-logical
+GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION       realised-by-cloudNativeApplication      GNBDUFunction   o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-gnbduFunction  CloudNativeApplication  o-ran-smo-teiv-ran-cloud        0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical-to-cloud_GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION    false   o-ran-smo-teiv-ran-logical-to-cloud
+GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER provided-nrSectorCarrier        GNBDUFunction   o-ran-smo-teiv-ran-logical      1       1       provided-by-gnbduFunction       NRSectorCarrier o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRSectorCarrier      false   o-ran-smo-teiv-ran-logical
+GNBDUFUNCTION_PROVIDES_NRCELLDU        provided-nrCellDu       GNBDUFunction   o-ran-smo-teiv-ran-logical      1       1       provided-by-gnbduFunction       NRCellDU        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRCellDU     false   o-ran-smo-teiv-ran-logical
+GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN       realised-by-cloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        CloudNativeApplicationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-cloud        0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical-to-cloud_GNBDUFUNCTIONNNNNNNNN_REALISED_BY_CLOUDNATIVEAPPLICATIONNNNNNNNN    false   o-ran-smo-teiv-ran-logical-to-cloud
+GNBDUFUNCTIONNNNNNNNNNNNNNUUU_PROVIDES_NRCELLDUUUUUUUUUUUUUUUUUU       provided-nrCellDuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu        GNBDUFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        o-ran-smo-teiv-ran-logical      1       1       provided-by-gnbduFunctionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn        NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRCellDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU     false   o-ran-smo-teiv-ran-logical
+EUTRANCELL_USES_LTESECTORCARRIER       used-lteSectorCarrier   EUtranCell      o-ran-smo-teiv-ran-logical      0       1       used-by-euTranCell      LTESectorCarrier        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_LTESectorCarrier     false   o-ran-smo-teiv-ran-logical
+GNBCUCPFUNCTION_PROVIDES_NRCELLCU      provided-nrCellCu       GNBCUCPFunction o-ran-smo-teiv-ran-logical      1       1       provided-by-gnbcucpFunction     NRCellCU        o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_NRCellCU     false   o-ran-smo-teiv-ran-logical
+GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION     realised-by-cloudNativeApplication      GNBCUCPFunction o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-gnbcucpFunction        CloudNativeApplication  o-ran-smo-teiv-ran-cloud        0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical-to-cloud_GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION  false   o-ran-smo-teiv-ran-logical-to-cloud
+NRSECTORCARRIER_USES_ANTENNACAPABILITY used-antennaCapability  NRSectorCarrier o-ran-smo-teiv-ran-logical      0       9223372036854775807     used-by-nrSectorCarrier AntennaCapability       o-ran-smo-teiv-ran-logical      0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-logical_NRSectorCarrier      false   o-ran-smo-teiv-ran-logical
+ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE    realised-by-antennaModule       AntennaCapability       o-ran-smo-teiv-ran-logical      0       9223372036854775807     realised-antennaCapability      AntennaModule   o-ran-smo-teiv-ran-equipment    0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical-to-equipment_ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE     false   o-ran-smo-teiv-ran-logical-to-equipment
+TESTENTITYA_PROVIDES_TESTENTITYB       provided-testEntityB    TestEntityA     o-ran-smo-teiv-ran-logical      0       2       provided-by-testEntityA TestEntityB     o-ran-smo-teiv-ran-logical      0       3       BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical_TESTENTITYA_PROVIDES_TESTENTITYB     false   o-ran-smo-teiv-ran-logical
+TESTENTITYA_USES_TESTENTITYB   used-TestEntityB        TestEntityA     o-ran-smo-teiv-ran-logical      0       1       used-by-testEntityA     TestEntityB     o-ran-smo-teiv-ran-logical      0       2       BI_DIRECTIONAL  B_SIDE  o-ran-smo-teiv-ran-logical_TestEntityB  false   o-ran-smo-teiv-ran-logical
+TESTENTITYA_GROUPS_TESTENTITYB grouped-testEntityB     TestEntityA     o-ran-smo-teiv-ran-logical      0       2       grouped-by-testEntityA  TestEntityB     o-ran-smo-teiv-ran-logical      0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-logical_TESTENTITYA_GROUPS_TESTENTITYB       false   o-ran-smo-teiv-ran-logical
+ANTENNAMODULE_INSTALLED_AT_SITE        installed-at-site       AntennaModule   o-ran-smo-teiv-ran-equipment    0       9223372036854775807     installed-antennaModule Site    o-ran-smo-teiv-ran-equipment    0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-equipment_AntennaModule      false   o-ran-smo-teiv-ran-equipment
+PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE     installed-at-site       PhysicalNetworkAppliance        o-ran-smo-teiv-ran-equipment    0       9223372036854775807     installed-physicalNetworkAppliance      Site    o-ran-smo-teiv-ran-equipment    0       1       BI_DIRECTIONAL  A_SIDE  o-ran-smo-teiv-ran-equipment_PhysicalNetworkAppliance   false   o-ran-smo-teiv-ran-equipment
+ANTENNAMODULE_REALISED_BY_ANTENNAMODULE        realised-by-antennaModule       AntennaModule   o-ran-smo-teiv-ran-equipment    0       9223372036854775807     realised-antennaModule  AntennaModule   o-ran-smo-teiv-ran-equipment    0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-equipment_ANTENNAMODULE_REALISED_BY_ANTENNAMODULE    true    o-ran-smo-teiv-ran-equipment
+ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE       realised-by-antennaModule       AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-equipment    0       1       realised-antennaModule  AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-equipment    0       9223372036854775807     BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-equipment_ANTENNAMODULEEEEEEEEEEEE_REALISED_BY_ANTENNAMODULEEEEEEEEEEEEEEE   true    o-ran-smo-teiv-ran-equipment
+ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE       deployed-on-antennaModule       AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-equipment    0       1       deployed-antennaModule  AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee        o-ran-smo-teiv-ran-equipment    0       1       BI_DIRECTIONAL  RELATION        o-ran-smo-teiv-ran-equipment_ANTENNAMODULEEEEEEEEEEEE_DEPLOYED_ON_ANTENNAMODULEEEEEEEEEEEEEEE   true    o-ran-smo-teiv-ran-equipment
 \.
 
 ;
+
+COMMIT;
diff --git a/teiv/src/test/resources/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql b/teiv/src/test/resources/pgsqlschema/02_init-oran-smo-teiv-consumer-data-v1.sql
new file mode 100644 (file)
index 0000000..9c6050f
--- /dev/null
@@ -0,0 +1,48 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+CREATE SCHEMA IF NOT EXISTS ties_consumer_data;
+
+CREATE TABLE IF NOT EXISTS ties_consumer_data."module_reference" (
+    "name"                   VARCHAR(511) PRIMARY KEY,
+    "namespace"              VARCHAR(511),
+    "revision"       VARCHAR(511),
+    "content"               TEXT,
+    "ownerAppId"       VARCHAR(511),
+    "status"       VARCHAR(127)
+);
+
+CREATE TABLE IF NOT EXISTS ties_consumer_data."classifiers" (
+    "name"                VARCHAR(511) PRIMARY KEY,
+    "moduleReferenceName" VARCHAR(511) NOT NULL,
+    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_consumer_data."module_reference" ("name") ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS ties_consumer_data."decorators" (
+    "name"                VARCHAR(511) PRIMARY KEY,
+    "dataType"            VARCHAR(511) NOT NULL,
+    "moduleReferenceName" VARCHAR(511) NOT NULL,
+    FOREIGN KEY ("moduleReferenceName") REFERENCES ties_consumer_data."module_reference" ("name") ON DELETE CASCADE
+);
+
+COMMIT;
diff --git a/teiv/src/test/resources/pgsqlschema/consumer-data-v1.sql b/teiv/src/test/resources/pgsqlschema/consumer-data-v1.sql
new file mode 100644 (file)
index 0000000..fd70b75
--- /dev/null
@@ -0,0 +1,42 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+COPY ties_consumer_data."module_reference"("name", "namespace", "revision", "content", "ownerAppId", "status") FROM stdin;
+test-app-module        urn:o-ran:test-app-module       2024-05-24      bW9kdWxlIHRlc3QtYXBwLW1vZHVsZSB7CgogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOnRlc3QtYXBwLW1vZHVsZSI7CiAgICBwcmVmaXggbW9kdWxlOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCB0ZXN0OyB9CiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IG9yLXRlaXYteWV4dDsgfQoKICAgIHJldmlzaW9uICIyMDI0LTA2LTEwIiB7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICBJbml0aWFsIHJldmlzaW9uLjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgYXVnbWVudCAvdGVzdDpkZWNvcmF0b3JzIHsKICAgICAgICBsZWFmIGxvY2F0aW9uIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgfQogICAgICAgIGxlYWYgdmVuZG9yIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgfQogICAgfQoKICAgIGlkZW50aXR5IE91dGRvb3IgewogICAgICAgIGJhc2UgdGVzdDpjbGFzc2lmaWVyczsKICAgIH0KCiAgICBpZGVudGl0eSBSdXJhbCB7CiAgICAgICAgYmFzZSB0ZXN0OmNsYXNzaWZpZXJzOwogICAgfQoKICAgIGlkZW50aXR5IFdlZWtlbmQgewogICAgICAgIGJhc2UgdGVzdDpjbGFzc2lmaWVyczsKICAgIH0KCn0K    APP     IN_USAGE
+test-app-for-deletion-module   urn:o-ran:test-app-for-deletion-module  2024-05-24      bW9kdWxlIHRlc3QtYXBwLW1vZHVsZSB7CgogICAgeWFuZy12ZXJzaW9uIDEuMTsKICAgIG5hbWVzcGFjZSAidXJuOnRlc3QtYXBwLW1vZHVsZSI7CiAgICBwcmVmaXggbW9kdWxlOwoKICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy10eXBlcyB7IHByZWZpeCB0ZXN0OyB9CiAgICBpbXBvcnQgby1yYW4tc21vLXRlaXYtY29tbW9uLXlhbmctZXh0ZW5zaW9ucyB7cHJlZml4IG9yLXRlaXYteWV4dDsgfQoKICAgIHJldmlzaW9uICIyMDI0LTA2LTEwIiB7CiAgICAgICAgZGVzY3JpcHRpb24KICAgICAgICBJbml0aWFsIHJldmlzaW9uLjsKICAgICAgICBvci10ZWl2LXlleHQ6bGFiZWwgMC4zLjA7CiAgICB9CgogICAgYXVnbWVudCAvdGVzdDpkZWNvcmF0b3JzIHsKICAgICAgICBsZWFmIGxvY2F0aW9uIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgfQogICAgICAgIGxlYWYgdmVuZG9yIHsKICAgICAgICAgICAgdHlwZSBzdHJpbmc7CiAgICAgICAgfQogICAgfQoKICAgIGlkZW50aXR5IE91dGRvb3IgewogICAgICAgIGJhc2UgdGVzdDpjbGFzc2lmaWVyczsKICAgIH0KCiAgICBpZGVudGl0eSBSdXJhbCB7CiAgICAgICAgYmFzZSB0ZXN0OmNsYXNzaWZpZXJzOwogICAgfQoKICAgIGlkZW50aXR5IFdlZWtlbmQgewogICAgICAgIGJhc2UgdGVzdDpjbGFzc2lmaWVyczsKICAgIH0KCn0K    APP     IN_USAGE
+\.
+
+COPY ties_consumer_data."decorators" ("name", "dataType", "moduleReferenceName" )  FROM stdin;
+test-app-module:textdata       TEXT    test-app-module
+test-app-module:intdata        INT     test-app-module
+\.
+
+COPY ties_consumer_data."classifiers" ("name", "moduleReferenceName" )  FROM stdin;
+test-app-module:Indoor test-app-module
+test-app-module:Outdoor        test-app-module
+test-app-module:Rural  test-app-module
+test-app-module:Weekday        test-app-module
+test-app-module:Weekend        test-app-module
+\.
+
+COMMIT;
\ No newline at end of file
diff --git a/teiv/src/test/resources/pgsqlschema/data-v1.sql b/teiv/src/test/resources/pgsqlschema/data-v1.sql
new file mode 100644 (file)
index 0000000..1fd360c
--- /dev/null
@@ -0,0 +1,322 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+COPY ties_data."o-ran-smo-teiv-oam_ManagedElement" ("id", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9  ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10", "urn:cmHandle:72FDA73D085F138FECC974CB91F1450E"]     []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13", "urn:cmHandle:E5196035D0B49A65B00EAA392B4EE155"]     []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14", "urn:cmHandle:D67C0BD04FA613BBFD176B24B68FD6A4"]     []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16", "urn:cmHandle:453431CC154F900606657D584700827A"]     []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]     []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28", "urn:cmHandle:30C68865AF2F353F202056CB1921D418"]     []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_Sector" ("id", "geo-location", "sectorId", "azimuth", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+Sector=1       POINT(59.4019881 17.9419888)    1       1.1     []      []      {}
+Sector=2       POINT(60.4019881 18.9419888)    2       2.2     []      []      {}
+Sector=3       POINT(61.4019881 19.9419888)    3       3.3     []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_AntennaCapability" ("id", "eUtranFqBands", "geranFqBands", "nRFqBands", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1  ["123","456","789"]     ["123","4564","789"]    ["123","456","789"]     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1 ["123","456","789"]     ["123","4564","789"]    ["123","456","789"]     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]     []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-equipment_AntennaModule" ("id", "antennaBeamWidth", "antennaModelNumber", "electricalAntennaTilt", "geo-location", "mechanicalAntennaBearing", "mechanicalAntennaTilt", "positionWithinSector", "totalTilt", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_installed-at-site", "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_CD_sourceIds_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_CD_classifiers_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_CD_decorators_ANTENNAMODULE_INSTALLED_AT_SITE", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_ANTENNAMODULE", "REL_CD_sourceIds_SECTOR_GROUPS_ANTENNAMODULE", "REL_CD_classifiers_SECTOR_GROUPS_ANTENNAMODULE", "REL_CD_decorators_SECTOR_GROUPS_ANTENNAMODULE") FROM stdin;
+urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A       \N      5       11      POINT(39.4019881 67.9419888)    6       0       7       -900    ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1", "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1", "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,Equipment=1,AntennaUnitGroup=1,AntennaNearUnit=1,RetSubUnit=1", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]   []      {}      \N      \N      []      []      {}      Sector=2        urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=44F4F4FC906E9A7525065E4565246F7469CBD11FC7752C61EA6D74776845900AFF472DCAACA1F66443490B6CE0DD9AC9A5E1467022118599F6B4C6EC63400512  []      []      {}
+urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7       \N      5       11      POINT(49.4019881 68.9419888)    6       0       7       -900    ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1", "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaUnit=1,AntennaSubunit=1", "urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,Equipment=1,AntennaUnitGroup=1,AntennaNearUnit=1,RetSubUnit=1", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]        []      {}      \N      \N      []      []      {}      Sector=2        urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_ANTENNAMODULE=CEEC51BE136D671D2101C09FEDD8A1D95E1E177A4818E9FC0D6E63E610BC8FE26FC9C729A1E58AD43D70472F4CD54403E25CB1E5D2BBA66966625C21435C4A78  []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_GNBCUCPFunction" ("id", "gNBCUName", "gNBId", "gNBIdLength", "pLMNId", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION", "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUCPFunction=9        gnbcucp-9       9       1       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUCPFunction=9", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9   urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=0F7F3F3CEC7B3CDA05A7B7D2874D1EF39EBDAA18AD7D6F43CF219C087510114C59C6B78EC21F8E9C6F19B5F1999FBBA2DF8C3DDF76F416C874508303F0DA4AB4       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUCPFunction=10      gnbcucp-10      10      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUCPFunction=10", "urn:cmHandle:72FDA73D085F138FECC974CB91F1450E"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=7053BF6EEB9769084BB91850C356BF20E3C9D6AD8F0D7212911DC827AD1B4D42AEDA0C43FD5715C94E14334EF49FA09405A976451B777B442BBF397DE89528A4       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBCUCPFunction=13      gnbcucp-13      13      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBCUCPFunction=13", "urn:cmHandle:E5196035D0B49A65B00EAA392B4EE155"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=C88ACE9CD7BA7E56FD059C027DA8E4D0ED0A3E13F9E358D5F4A66EE004FC3767A9D20B0512661B6D2F5F82F106725C04C5DC8826D990DECB4D5AD571BE402BE0       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBCUCPFunction=14      gnbcucp-14      14      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBCUCPFunction=14", "urn:cmHandle:D67C0BD04FA613BBFD176B24B68FD6A4"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=F23FADEDC45AE38DBC567C57FC4DD5D61D239B0BEF3C93DD54DF85545E6D0C8B9B26A1D3911B56A3F8C2EB148A4F276D1EBAF7EE2D2E35C8B37F008F572DF7B6       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBCUCPFunction=16      gnbcucp-16      16      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBCUCPFunction=16", "urn:cmHandle:453431CC154F900606657D584700827A"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=5ECE0941DDBC9B4DEE8492333129A0AB80720CB6005A80B54C4D9247029A41FA42DB6D2C709F71D7ED5D82F5EA90CE2C0B553AC1BD860D8A6DFA218E2E790F1C       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBCUCPFunction=19      gnbcucp-19      19      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBCUCPFunction=19", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=63EA5A9F77FE5DED61CF6DC30233AB17A57D6E04283365D7C1976FF646961FAAF1889BBA618029EA10DA8761F8DAA643B707B602D4E61898A2B5259AA0118887       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBCUCPFunction=28      gnbcucp-28      28      2       {"mcc":"01","mnc":"234"}        ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBCUCPFunction=28", "urn:cmHandle:30C68865AF2F353F202056CB1921D418"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION=CD564BF182FD6DE77816BA69F25B664374AD02D642DF05FF8991E1009E7E09C50E92F6858A1E1B025CFDA933AB769B8C68FBAE0DBBAA140AE321DC55AED6C2A3       []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_GNBCUUPFunction" ("id", "gNBId", "gNBIdLength", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9        9       1       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBCUUPFunction=9", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9   urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=5255F37093F8EB3763CE5F017DFC1E162B44FC9DF6E13744C04DC1832C5E754AB7BE440DBE1187EE8EEE42FD04E652BB8148655C6F977B1FFDDA54FE87C6411A       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUUPFunction=10      10      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBCUUPFunction=10", "urn:cmHandle:72FDA73D085F138FECC974CB91F1450E"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=80D3B4C44B4F0BEFC7660AF0A4E91F89C8108DA814B09728F848C0C5C10E2D956A73FBC85EB2AE0A7EA4D95308A606856603B53C8C2669A50BCB58B9FC87D7F2       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBCUUPFunction=13      13      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBCUUPFunction=13", "urn:cmHandle:E5196035D0B49A65B00EAA392B4EE155"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=29DE1D3B8DA9C9FA1201C36F74FEBE14493F7C674E47E1FFCB6AADEED8EABB0460770EC21E7AC8EEBBB057ABC0E31269AB5C92D941E9BA53877164918C6EFB30       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBCUUPFunction=14      14      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBCUUPFunction=14", "urn:cmHandle:D67C0BD04FA613BBFD176B24B68FD6A4"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=4C571BDD5DF9B297C1B249D0242EB9DDC77052BB0A33E62DB851809A075259EE3A0C354FA3978276BD5EE0BBB8CFDBF19F7C3C7017F828B9A2EBAD020E7FDF98       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBCUUPFunction=16      16      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBCUUPFunction=16", "urn:cmHandle:453431CC154F900606657D584700827A"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=DD5E12CB8D14C89E1C199BDABBCC71908F76AB04FE8FD7F7334A9A403B5BE0D8BB5DA69B4258C7AF4834BF2D3E00B6D5C263AD38A83A22E7EC673ACE1CAF0CF2       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBCUUPFunction=19      19      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBCUUPFunction=19", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=2AF48E294918A4EE0E3E7C783A70841E1DEEF72CDD43FE3CD1DF6531CCA06203B574BE02553254220A637632AECB719951DAE2A3D0487D24EA1A090843563603       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBCUUPFunction=28      28      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBCUUPFunction=28", "urn:cmHandle:30C68865AF2F353F202056CB1921D418"]  []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION=140E8C8C56B1E717CD992D3FF0C61C04C1633E1FEF17ABB92A9A17C53E18CFAF5D72C4C71415E0026C99671657FB3EC1BD394174DD306261ADA8A6CDF4D42748       []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_GNBDUFunction" ("id", "dUpLMNId", "gNBDUId", "gNBId", "gNBIdLength", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9  {"mcc":"123","mnc":"82"}        \N      9       1       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]      ["test-app-module:Indoor","test-app-module:Weekend"]    {"test-app-module:textdata":"ORAN"}     urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9   urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=9243B48F7D6A6CF471226915C74CF5FE4BDA6FA3CF7D897473007B46DF7FC50230BD6B8B4256116A6AFBF4D822CF9379EB56DE9490C1C0B54238263F2574B426 []      ["test-app-module:Indoor","test-app-module:Weekend"]    {"test-app-module:textdata":"ORAN"}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10        {"mcc":"456","mnc":"83"}        \N      10      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10,GNBDUFunction=10", "urn:cmHandle:72FDA73D085F138FECC974CB91F1450E"]    []      {"test-app-module:textdata":"Budapest","test-app-module:intdata":123}   urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=10  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=661A89AD3C2702233CD9E96E97E738C05C35EC5FDF32DC78D149B773726350067315B72448D004C938BCD0263F0C4BCCC8A5F9CDD145B9B740983D1523664328 []      ["test-app-module:Rural","test-app-module:Weekend"]     {"test-app-module:textdata":"Budapest","test-app-module:intdata":123}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13        {"mcc":"789","mnc":"84"}        \N      13      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13,GNBDUFunction=13", "urn:cmHandle:E5196035D0B49A65B00EAA392B4EE155"]    ["test-app-module:Indoor"]      {"test-app-module:textdata":"Stockholm","test-app-module:intdata":456}  urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=13  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=DD9259A1B57FF2BB9DEC77C29DBFA4A5C49960D80622F603809ACA47E786DDD5C7ABD267D554A7C796477A9B2E02E072A8E682E4ED38F331BFB6DC3827CE4DB7 []      []      {"test-app-module:textdata":"Stockholm","test-app-module:intdata":456}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14        {"mcc":"123","mnc":"85"}        \N      14      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14,GNBDUFunction=14", "urn:cmHandle:D67C0BD04FA613BBFD176B24B68FD6A4"]    ["test-app-module:Rural","test-app-module:Weekend"]     {"test-app-module:textdata":"Stockholm","test-app-module:intdata":123}  urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=14  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6F7BFBD3DA2A9A592084C75242210A33C9DCF10CFCD53B761A6ACCD385132921679EC3C16394A4DEEE5883712C9719511388230151BA84FBF209DFCFB639E2EA []      []      {"test-app-module:textdata":"Stockholm","test-app-module:intdata":123}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16        {"mcc":"456","mnc":"86"}        16      16      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16,GNBDUFunction=16", "urn:cmHandle:453431CC154F900606657D584700827A"]    ["test-app-module:Indoor","test-app-module:Rural","test-app-module:Weekend"]    {"test-app-module:textdata":"Stockholm","test-app-module:intdata":123}  urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=16  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=D67357F682531C7B068486313B0FDAC3E719A166229520196FB9CE917E0236754226A5BCBF7BB7240E516D7ED3FEA852855EC3F121DD4BAFEC5646F2A37F57EE []      ["test-app-module:Indoor","test-app-module:Rural","test-app-module:Weekend"]    {"test-app-module:textdata":"Stockholm","test-app-module:intdata":123}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19        {"mcc":"789","mnc":"87"}        \N      19      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=6BD25E5C8FB7842F69010736253CC47F43535D7238E9E9A03E8092E8C019C83270DE47C96EF1049C40B83A130F9F129AE93B9C8538B6B004AE89BD0A098E48DD []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBDUFunction=28        {"mcc":"123","mnc":"88"}        \N      28      2       ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28,GNBDUFunction=28", "urn:cmHandle:30C68865AF2F353F202056CB1921D418"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=28  urn:o-ran:smo:teiv:sha512:MANAGEDELEMENT_MANAGES_GNBDUFUNCTION=ADD4A82DFBAF0409FA9D3C929A09314088627B447C733429D4EE7AAE2FFAEE4894F90826B6814B63431EC07140783C7861E463C5AF8330E29469D704675EAB43 []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_NRCellDU" ("id", "cellLocalId", "nCI", "nRPCI", "nRTAC", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRCELLDU", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_NRCELLDU", "REL_CD_sourceIds_SECTOR_GROUPS_NRCELLDU", "REL_CD_classifiers_SECTOR_GROUPS_NRCELLDU", "REL_CD_decorators_SECTOR_GROUPS_NRCELLDU") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1       1       1       789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]   []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=4E40BE000AFEA418CE1B9ED9E21D38DA51772175BD498BE825D9EA362F9B7393C36AB72F6FDEE702439143D578268A2E84719A9352C8EA70F847B7B7664E047C      []      []      {}      Sector=2        urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=4BBE73F685A98EF799968ACFE76F376D795F4CC3B56A6B867642048CDF4C1B8E323430EA7C6C38E4031FB891158763CC5459A8704E1A9FBFBD53CE8AD23BF463       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2       2       2       789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]   []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=78ECC09D4832328976EF0F9C19699EE05D98E3837368D386AE39AD027543494AC620086BD2A7403DACFAA7B474B3DEBD313E0906F1EDE7FA2B584E16542A706A      []      []      {}      Sector=2        urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=46AAB2CC5388BECD7B2180C89EEFA64B9A3BC197B614B57FD4BD9ADACE2475A89E16BA04291DE1674FAF2925483E23B8EDCAD4EE98759A9C08E2677CD88F4C43       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3       3       3       789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]   []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=714C1B73945C298CAA03FE0D800053CDD1C571BBF375DC647B9F23FDA861CEB369832A3593BB1AA4B8A7245AD187ED24ADDF6FB147130827CDC17BA8370C4838      []      []      {}      Sector=2        urn:o-ran:smo:teiv:sha512:SECTOR_GROUPS_NRCELLDU=F892571703F0E20A37F3950818DEFA9991ACF35828EEEBD3E43404218F947E1F522258A1F31F4C82A53E7E60D9E1A7AC7AC4219A0D9DD0D8FD192BC73BBB5101       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91    91      91      789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=91", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]        []      {}      \N      \N      []      []      {}      \N      \N      []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=92    92      92      789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=92", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]        []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19 urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=DDECCEFB8831FA4EB21B121BA35EAB07ED8D841B5A38580C5F3AD11E66FE73D2FC42E823C6C73288860C7562B610C3D07B6C39FD386171A3BE622096F4B3D006      []      []      {}      \N      \N      []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=93    93      93      789     456     ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19,NRCellDU=93", "urn:cmHandle:03661FA2E41EF3D12CAAD5954CD985AC"]        ["test-app-module:Rural"]       {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,GNBDUFunction=19 urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRCELLDU=7723E5D5B3332E0890EAA620C77A6A47065E15A2EA28AD83F3B3CFEA5A7E3BB5965AE78890F1BF000EAA89BF8DE209E506192BF5EA6871426603ED76CBFAF088      []      []      {}      \N      \N      []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_NRSectorCarrier" ("id", "arfcnDL", "arfcnUL", "bSChannelBwDL", "frequencyDL", "frequencyUL", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_CD_sourceIds_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_CD_classifiers_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_CD_decorators_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_FK_used-by-nrCellDu", "REL_ID_NRCELLDU_USES_NRSECTORCARRIER", "REL_CD_sourceIds_NRCELLDU_USES_NRSECTORCARRIER", "REL_CD_classifiers_NRCELLDU_USES_NRSECTORCARRIER", "REL_CD_decorators_NRCELLDU_USES_NRSECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_sourceIds_NRSECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_classifiers_NRSECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_decorators_NRSECTORCARRIER_USES_ANTENNACAPABILITY") FROM stdin;
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=1        507000  507000  10000   2535000 2535000 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=1", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER=BE61426CAEA457C85D8B551A1A75BFA157BBCE6F143110661C4C9D406A7AAF22D8522515CE924CFB3A9E54E68588A45D3A51065BD24ADBA62CC0FDA761AEE2FC       []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=1        urn:o-ran:smo:teiv:sha512:NRCELLDU_USES_NRSECTORCARRIER=7B9425BBD6977FEA6C180F6078CFBAEBE65400223B29E0EFA4F38424FAD66C690806778909177ECF1457CAC18E5BCF6FA4F24E3ECE524C89DE68108708D6D876        []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1   urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=11EDFC31E2BE240D3CB15DB1A3FA3B78C828524BC8FCA3365A615129A61A627C21DA8EBF6DD788CDBDEC668344D1F79A371749083D6AE04DDDD57CB4FA8C3ECB       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=2        507000  507000  10000   2535000 2535000 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=2", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER=C0E73797DB4599AB9ECACFC1FFE3543C92926070ECFBE77E7C15BA99DAFBB1D69352533D3DE5EB2D3D3CC84DAD51B242CB0FC594FF9E8B73C3B42106B0F9AF46       []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=2        urn:o-ran:smo:teiv:sha512:NRCELLDU_USES_NRSECTORCARRIER=2F87CE31F38D38B993786E3D75D253984DA2842F71504958AAF052D0728B309C73BB3132D6BEA011748BB0B94F489725DB5765AB5366702B812D5C76A772BD9C        []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1   urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=27DF07D016FE349EC565DE2FB09303EE7D8700346624046F79D8DAC176E7FA221E918E3030758B51931C430919E14FD7D16720460F6E1585000C72874A1641DA       []      []      {}
+urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=3        507000  507000  10000   2535000 2535000 ["urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRSectorCarrier=3", "urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]    []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9   urn:o-ran:smo:teiv:sha512:GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER=BD87BC547A6731B2905A989EBA493810C74258337C49BBB288F4F55734D28B4E40D9C719EC3564348253905BD93EC78EB7C88F2297FF20778911635E94800F74       []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,GNBDUFunction=9,NRCellDU=3        urn:o-ran:smo:teiv:sha512:NRCELLDU_USES_NRSECTORCARRIER=950ED4540349F9859CEA9E47884A28CD567BDD2505A3C5335C8851A7AADF2AF65542157BB42D607EE3847E4223D76DE88B90762D0590E48693822FD6DCAE60CD        []      []      {}      urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1   urn:o-ran:smo:teiv:sha512:NRSECTORCARRIER_USES_ANTENNACAPABILITY=1B891FCC4F5479BC71127ED2EB43EA26AC3452F8C47792786373442C10BBC408FE5B779BF1CF732C81220803342F4FB969E348F9C5CEEDEC78F9764E186C633F       []      []      {}
+\.
+
+COPY ties_data."CFC235E0404703D1E4454647DF8AAE2C193DB402" ("id", "aSide_AntennaModule", "bSide_AntennaCapability", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+urn:o-ran:smo:teiv:sha512:ANTENNAMODULE_SERVES_ANTENNACAPABILITY=ABD52B030DF1169F9F41C898913EF30F7BB5741F53352F482310B280C90AC569B7D31D52A2BB41F1F0099AE1EDD56CACF0B285D145A5584D376DD45DED1E2D65      urn:o-ran:smo:teiv:sha512:AntennaModule=308D6602D2FE1C923DF176A0F30688B1810DFA7BC4AD5B8050BF9E27361ECA86E86B47B8582DC28E8CE92EB81822DE248845E87094557A953FD9F15BA508B03A        urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=9,NodeSupport=1,SectorEquipmentFunction=1   []      []      {}
+urn:o-ran:smo:teiv:sha512:ANTENNAMODULE_SERVES_ANTENNACAPABILITY=8940999E2069725B463052BC35572FDB888C7B734459EE78A01B9F91E2607D87356425BC8EFF0B1C9057D852A4D3F9E1B09479D32FEE68C65EF2821B65F7BD80      urn:o-ran:smo:teiv:sha512:AntennaModule=971FCD28D02B78DDD982611639A0957140339C5522EAAF3FBACA1B8308CF7B0A870CFA80AE04E259805B2A2CB95E263261309883B4D4BF50183FA17AFBA47EA7        urn:3gpp:dn:SubNetwork=Europe,SubNetwork=Hungary,MeContext=1,ManagedElement=19,NodeSupport=1,SectorEquipmentFunction=1  []      []      {}
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_ENodeBFunction" ("id", "eNBId", "eNodeBPlmnId", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "REL_CD_sourceIds_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION") FROM stdin;
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_EUtranCell" ("id", "cellId", "channelBandwidth", "dlChannelBandwidth", "duplexType", "earfcn", "earfcndl", "earfcnul", "tac", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL", "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_EUTRANCELL", "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_EUTRANCELL", "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_EUTRANCELL", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_EUTRANCELL", "REL_CD_sourceIds_SECTOR_GROUPS_EUTRANCELL", "REL_CD_classifiers_SECTOR_GROUPS_EUTRANCELL", "REL_CD_decorators_SECTOR_GROUPS_EUTRANCELL") FROM stdin;
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_LTESectorCarrier" ("id", "sectorCarrierType", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_CD_sourceIds_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_CD_classifiers_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_CD_decorators_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_FK_used-by-euTranCell", "REL_ID_EUTRANCELL_USES_LTESECTORCARRIER", "REL_CD_sourceIds_EUTRANCELL_USES_LTESECTORCARRIER", "REL_CD_classifiers_EUTRANCELL_USES_LTESECTORCARRIER", "REL_CD_decorators_EUTRANCELL_USES_LTESECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_sourceIds_LTESECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_classifiers_LTESECTORCARRIER_USES_ANTENNACAPABILITY", "REL_CD_decorators_LTESECTORCARRIER_USES_ANTENNACAPABILITY") FROM stdin;
+\.
+
+COPY ties_data."o-ran-smo-teiv-ran_NRCellCU" ("id", "cellLocalId", "nCI", "nRTAC", "plmnId", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-gnbcucpFunction", "REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU", "REL_CD_sourceIds_GNBCUCPFUNCTION_PROVIDES_NRCELLCU", "REL_CD_classifiers_GNBCUCPFUNCTION_PROVIDES_NRCELLCU", "REL_CD_decorators_GNBCUCPFUNCTION_PROVIDES_NRCELLCU") FROM stdin;
+\.
+
+COPY ties_data."o-ran-smo-teiv-equipment_Site" ("id", "geo-location", "name", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+\.
+
+-- Test specific entries --
+
+CREATE TABLE IF NOT EXISTS ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (
+       "id"                    TEXT,
+       "6446B2D4BE5E367FB0396383C4BDEF42D51CF74F"                      TEXT,
+       "F03B534AFF0872651FED60C54AB56BEDADAB94B5"                      BIGINT,
+       "333177AA699C0DE6399503171DCF48FB396322B0"                      INTEGER,
+       "027B1A8019C6DEF04558B90D9D8B52253B82FEC6"                      BIGINT,
+       "478D043D81678134EF1C8BFB073A70F882C4AF12"                      DECIMAL,
+       "8252D18D44F633831557076D827993C45278024D"                      jsonb,
+       "68C48305AB6C3A30DD927F5D38562379374A4B31"                      jsonb,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_provided-by-entityTypeA"                        TEXT,
+       "REL_ID_F64052A4F8BB3CC533EC15BBFB5E224F600735B0"                       TEXT,
+       "REL_CD_F26C39EC1F710F3096BE0588F6783A03A378516A"                       jsonb,
+       "REL_CD_E2C3D598A06EA38133E23C1756ED58A66FE21386"                       jsonb,
+       "REL_CD_92559ED73C761B860682582A040E745ECEC194D5"                       jsonb
+);
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "REL_CD_F26C39EC1F710F3096BE0588F6783A03A378516A" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "REL_CD_E2C3D598A06EA38133E23C1756ED58A66FE21386" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ALTER COLUMN "REL_CD_92559ED73C761B860682582A040E745ECEC194D5" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" (
+       "id"                    TEXT,
+       "aSide_EntityTypeA"                     TEXT,
+       "bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515"                        TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."FB1E124031A12CD85D3335194B39B193723A0490" (
+       "id"                    TEXT,
+       "aSide_C812C285BEFA4EC42026AB075D9C65200A00F815"                        TEXT,
+       "bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515"                        TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb
+);
+
+ALTER TABLE ONLY ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+CREATE TABLE IF NOT EXISTS ties_data."test-built-in-module_EntityTypeA" (
+       "id"                    TEXT,
+       "CD_sourceIds"                  jsonb,
+       "CD_classifiers"                        jsonb,
+       "CD_decorators"                 jsonb,
+       "REL_FK_B7E43411C5C5079D49856E74A9FA63BD20C522C5"                       TEXT,
+       "REL_ID_31A5B55158140557F09AE15589A8B8038416689B"                       TEXT,
+       "REL_CD_AB6BDADE3F6C750C9FDB6CAD6059C4CBCE67236C"                       jsonb,
+       "REL_CD_75B161E740A96ADBAE6F08D4F85684ECC29049B9"                       jsonb,
+       "REL_CD_6F7211CAF505AECF9A565BC7A4AF56E7032CCC54"                       jsonb,
+       "REL_FK_A86937FEBD025CFDF6EE5BC386B4C569EB2652DA"                       TEXT,
+       "REL_ID_A974AD6DD8C4CA281D45693D3A61AE98FEE82845"                       TEXT,
+       "REL_CD_3B43F80D423BF8F96A2906643B7B4712604FC28B"                       jsonb,
+       "REL_CD_74A44B167FDF37D6C8E79B5033FEF8BC384C881A"                       jsonb,
+       "REL_CD_F5B24D9A7273119D4D1519473D9EC88CB407E5CA"                       jsonb
+);
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "CD_sourceIds" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "CD_classifiers" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "CD_decorators" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_AB6BDADE3F6C750C9FDB6CAD6059C4CBCE67236C" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_75B161E740A96ADBAE6F08D4F85684ECC29049B9" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_6F7211CAF505AECF9A565BC7A4AF56E7032CCC54" SET DEFAULT '{}';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_3B43F80D423BF8F96A2906643B7B4712604FC28B" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_74A44B167FDF37D6C8E79B5033FEF8BC384C881A" SET DEFAULT '[]';
+
+ALTER TABLE ONLY ties_data."test-built-in-module_EntityTypeA" ALTER COLUMN "REL_CD_F5B24D9A7273119D4D1519473D9EC88CB407E5CA" SET DEFAULT '{}';
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '10B9F515756871D3EF6558FAF1F112BAE207945D',
+ 'PK_7A421D526B36AA9EEF17964BC27011A12FF80DBB',
+ 'ALTER TABLE ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ADD CONSTRAINT "PK_7A421D526B36AA9EEF17964BC27011A12FF80DBB" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '54110F8D085BBBA7BB6DE5CE71B511562090F7EE',
+ 'PK_4C48AAFA2160D74F9D13364AA2BE4FDB8A60689D',
+ 'ALTER TABLE ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ADD CONSTRAINT "PK_4C48AAFA2160D74F9D13364AA2BE4FDB8A60689D" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'FB1E124031A12CD85D3335194B39B193723A0490',
+ 'PK_020B03AED5787D1B43ABBD9F2C26B494ADDBC7CD',
+ 'ALTER TABLE ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ADD CONSTRAINT "PK_020B03AED5787D1B43ABBD9F2C26B494ADDBC7CD" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'test-built-in-module_EntityTypeA',
+ 'PK_test-built-in-module_EntityTypeA_id',
+ 'ALTER TABLE ties_data."test-built-in-module_EntityTypeA" ADD CONSTRAINT "PK_test-built-in-module_EntityTypeA_id" PRIMARY KEY ("id");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '10B9F515756871D3EF6558FAF1F112BAE207945D',
+ 'FK_B0923C0CCED6CF47CFF759FFE1B810D6CA10D228',
+ 'ALTER TABLE ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ADD CONSTRAINT "FK_B0923C0CCED6CF47CFF759FFE1B810D6CA10D228" FOREIGN KEY ("REL_FK_provided-by-entityTypeA") REFERENCES ties_data."test-built-in-module_EntityTypeA" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '10B9F515756871D3EF6558FAF1F112BAE207945D',
+ 'UNIQUE_B1C2FC9A96300B2BE45785DE60E152D8E85FBE14',
+ 'ALTER TABLE ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ADD CONSTRAINT "UNIQUE_B1C2FC9A96300B2BE45785DE60E152D8E85FBE14" UNIQUE ("REL_ID_F64052A4F8BB3CC533EC15BBFB5E224F600735B0");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '54110F8D085BBBA7BB6DE5CE71B511562090F7EE',
+ 'FK_2839E6FFDF7F3DF2687DAC3E57082AD6B22E9B30',
+ 'ALTER TABLE ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ADD CONSTRAINT "FK_2839E6FFDF7F3DF2687DAC3E57082AD6B22E9B30" FOREIGN KEY ("aSide_EntityTypeA") REFERENCES ties_data."test-built-in-module_EntityTypeA" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       '54110F8D085BBBA7BB6DE5CE71B511562090F7EE',
+ 'FK_33B5669A341584011D9A73FB491FF2242A158057',
+ 'ALTER TABLE ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ADD CONSTRAINT "FK_33B5669A341584011D9A73FB491FF2242A158057" FOREIGN KEY ("bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515") REFERENCES ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (id) ON DELETE CASCADE;'
+);
+
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'FB1E124031A12CD85D3335194B39B193723A0490',
+ 'FK_2A5C84A2226EE0FCAAA513CC5AF4CD78DDDAF49F',
+ 'ALTER TABLE ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ADD CONSTRAINT "FK_2A5C84A2226EE0FCAAA513CC5AF4CD78DDDAF49F" FOREIGN KEY ("aSide_C812C285BEFA4EC42026AB075D9C65200A00F815") REFERENCES ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'FB1E124031A12CD85D3335194B39B193723A0490',
+ 'FK_FBFE10B6F165A8EC2086B8DEAFA238E0DD6643F5',
+ 'ALTER TABLE ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ADD CONSTRAINT "FK_FBFE10B6F165A8EC2086B8DEAFA238E0DD6643F5" FOREIGN KEY ("bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515") REFERENCES ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'test-built-in-module_EntityTypeA',
+ 'FK_02592FFA6AFD7EAC7AFAD936E3CD50708E4533E0',
+ 'ALTER TABLE ties_data."test-built-in-module_EntityTypeA" ADD CONSTRAINT "FK_02592FFA6AFD7EAC7AFAD936E3CD50708E4533E0" FOREIGN KEY ("REL_FK_B7E43411C5C5079D49856E74A9FA63BD20C522C5") REFERENCES ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'test-built-in-module_EntityTypeA',
+ 'UNIQUE_7715FF94E14F99CE4994ABBD8C2583CBA9EAE5BD',
+ 'ALTER TABLE ties_data."test-built-in-module_EntityTypeA" ADD CONSTRAINT "UNIQUE_7715FF94E14F99CE4994ABBD8C2583CBA9EAE5BD" UNIQUE ("REL_ID_31A5B55158140557F09AE15589A8B8038416689B");'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'test-built-in-module_EntityTypeA',
+ 'FK_5CD9BCFA08278DA0BF902BAFBCFCDFCE4FF25FEF',
+ 'ALTER TABLE ties_data."test-built-in-module_EntityTypeA" ADD CONSTRAINT "FK_5CD9BCFA08278DA0BF902BAFBCFCDFCE4FF25FEF" FOREIGN KEY ("REL_FK_A86937FEBD025CFDF6EE5BC386B4C569EB2652DA") REFERENCES ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" (id) ON DELETE CASCADE;'
+);
+
+SELECT ties_data.create_constraint_if_not_exists(
+       'test-built-in-module_EntityTypeA',
+ 'UNIQUE_67DB5E4BC34AB83BDC069A5CAF73B57967D5C2D9',
+ 'ALTER TABLE ties_data."test-built-in-module_EntityTypeA" ADD CONSTRAINT "UNIQUE_67DB5E4BC34AB83BDC069A5CAF73B57967D5C2D9" UNIQUE ("REL_ID_A974AD6DD8C4CA281D45693D3A61AE98FEE82845");'
+);
+
+COPY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ("id", "6446B2D4BE5E367FB0396383C4BDEF42D51CF74F", "F03B534AFF0872651FED60C54AB56BEDADAB94B5", "333177AA699C0DE6399503171DCF48FB396322B0", "027B1A8019C6DEF04558B90D9D8B52253B82FEC6", "478D043D81678134EF1C8BFB073A70F882C4AF12", "8252D18D44F633831557076D827993C45278024D", "68C48305AB6C3A30DD927F5D38562379374A4B31", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+LongEntityType1        someStringValue 9223372036854775807     2147483647      -9223372036854775807    1.1     ["1000", "2000"]        {"mcc":"01","mnc":"234"}        []      []      {}
+\.
+
+COPY ties_data."test-built-in-module_EntityTypeA" ("id", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_B7E43411C5C5079D49856E74A9FA63BD20C522C5", "REL_ID_31A5B55158140557F09AE15589A8B8038416689B", "REL_CD_AB6BDADE3F6C750C9FDB6CAD6059C4CBCE67236C", "REL_CD_75B161E740A96ADBAE6F08D4F85684ECC29049B9", "REL_CD_6F7211CAF505AECF9A565BC7A4AF56E7032CCC54", "REL_FK_A86937FEBD025CFDF6EE5BC386B4C569EB2652DA", "REL_ID_A974AD6DD8C4CA281D45693D3A61AE98FEE82845", "REL_CD_3B43F80D423BF8F96A2906643B7B4712604FC28B", "REL_CD_74A44B167FDF37D6C8E79B5033FEF8BC384C881A", "REL_CD_F5B24D9A7273119D4D1519473D9EC88CB407E5CA") FROM stdin;
+EntityType1    []      []      {}      \N      \N      []      []      {}      LongEntityType1 RelId_OneToOne_EntityType1_LongEntityType1      []      []      {}
+EntityType2    []      []      {}      LongEntityType1 Rel_ManyToOne_EntityType2_LongEntityType1       []      []      {}      \N      \N      []      []      {}
+\.
+
+COPY ties_data."10B9F515756871D3EF6558FAF1F112BAE207945D" ("id", "6446B2D4BE5E367FB0396383C4BDEF42D51CF74F", "F03B534AFF0872651FED60C54AB56BEDADAB94B5", "333177AA699C0DE6399503171DCF48FB396322B0", "027B1A8019C6DEF04558B90D9D8B52253B82FEC6", "478D043D81678134EF1C8BFB073A70F882C4AF12", "8252D18D44F633831557076D827993C45278024D", "68C48305AB6C3A30DD927F5D38562379374A4B31", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_FK_provided-by-entityTypeA", "REL_ID_F64052A4F8BB3CC533EC15BBFB5E224F600735B0", "REL_CD_F26C39EC1F710F3096BE0588F6783A03A378516A", "REL_CD_E2C3D598A06EA38133E23C1756ED58A66FE21386", "REL_CD_92559ED73C761B860682582A040E745ECEC194D5") FROM stdin;
+LongEntityType2        \N      \N      \N      \N      \N      \N      \N      []      []      {}      EntityType2     Rel_OneToMany_EntityType2_LongEntityType2       []      []      {}
+LongEntityType3        \N      \N      \N      \N      \N      \N      \N      []      []      {}      \N      \N      []      []      {}
+\.
+
+COPY ties_data."54110F8D085BBBA7BB6DE5CE71B511562090F7EE" ("id", "aSide_EntityTypeA", "bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+Rel_ManyToMany_EntityType1_LongEntityType1     EntityType1     LongEntityType1 []      []      {}
+\.
+
+COPY ties_data."FB1E124031A12CD85D3335194B39B193723A0490" ("id", "aSide_C812C285BEFA4EC42026AB075D9C65200A00F815", "bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515", "CD_sourceIds", "CD_classifiers", "CD_decorators") FROM stdin;
+Rel_OneToOne_SameEntity_LongEntityType1_LongEntityType2        LongEntityType1 LongEntityType2 ["urn:cmHandle:C4388D6BB970EC663F88B46CC14F8616"]       ["test-app-module:Weekday"]     {"test-app-module:textdata":"ORAN","test-app-module:intdata":123}
+Rel_OneToOne_SameEntity_LongEntityType2_LongEntityType3        LongEntityType2 LongEntityType3 ["urn:cmHandle:C4388D6BB970EC663F88B46CC14F8617"]       ["test-app-module:Weekend"]     {"test-app-module:textdata":"ORAN","test-app-module:intdata":234}
+\.
+
+COMMIT;
+
similarity index 62%
rename from teiv/src/test/resources/data/data.sql
rename to teiv/src/test/resources/pgsqlschema/data.sql
index a9dd18a..49dc28b 100644 (file)
 -- ============LICENSE_END=========================================================
 --
 
-COPY ties_data."CloudNativeSystem" ("id", "name", "REL_FK_deployed-managedElement" )  FROM stdin;
+
+COPY ties_data."163276fa439cdfccabb80f7acacb6fa638e8d314" ("id", "name", "REL_FK_deployed-managedElement" )  FROM stdin;
 \.
 
-COPY ties_data."003B7CAE0FA8C3C54BE1BAD8BB9A50985A2EA03F" ("id", "name", "REL_FK_C2F5EC33C0760F653CE7263A49C0B697FCA2D542" )  FROM stdin;
+COPY ties_data."ef701af8e1445ed5d377664ba1d3d1c645e31639" ("id", "name", "REL_FK_C2F5EC33C0760F653CE7263A49C0B697FCA2D542" )  FROM stdin;
 C4E311A55666726FD9FE25CA572AFAF9       Example Cloud Native System/1   \N
 \.
 
-COPY ties_data."ManagedElement" ("id", "cmId", "fdn", "REL_FK_deployed-as-cloudNativeSystem", "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-oam_ManagedElement" ("id", "cmId", "fdn", "REL_FK_deployed-as-cloudNativeSystem", "REL_ID_MANAGEDELEMENT_DEPLOYED_AS_CLOUDNATIVESYSTEM" )  FROM stdin;
 DA1039E77700A9EEFFA280049ECE9227       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=9   \N      \N
 6F02817AFE4D53237DB235EBE5378613       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=10  \N      \N
 27500EB447000209EE6E3CA1B31FBA92       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=13  \N      \N
@@ -36,7 +37,7 @@ DC86CA7724113F4C0DF42BFEAA17FD53      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubN
 E64371CD4D12ED0CED200DD3A7591784       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=28  \N      \N
 \.
 
-COPY ties_data."1EF2A41C34A961CD8AE603E020B7B8B57345267F" ("id", "cmId", "fdn", "REL_FK_26958E3A529C4C8B68A29FDA906F8CD290F66078", "REL_ID_B7945BFD83380F3E12CF99F2B0F838F364027F92" )  FROM stdin;
+COPY ties_data."fa2dceaf53e045c136ce9db9bc5faae65a29fa4d" ("id", "cmId", "fdn", "REL_FK_26958E3A529C4C8B68A29FDA906F8CD290F66078", "REL_ID_B7945BFD83380F3E12CF99F2B0F838F364027F92" )  FROM stdin;
 45EF31D8A1FD624D7276390A1215BFC3       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=1   C4E311A55666726FD9FE25CA572AFAF9        urn:base64:TWFuYWdlZEVsZW1lbnQ6NDVFRjMxRDhBMUZENjI0RDcyNzYzOTBBMTIxNUJGQzM6REVQTE9ZRURfQVM6Q2xvdWROYXRpdmVTeXN0ZW06QzRFMzExQTU1NjY2NzI2RkQ5RkUyNUNBNTcyQUZBRjk=
 DA1039E77700A9EEFFA280049ECE9227       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=9   \N      \N
 6F02817AFE4D53237DB235EBE5378613       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=10  \N      \N
@@ -47,73 +48,73 @@ DC86CA7724113F4C0DF42BFEAA17FD53    \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubN
 E64371CD4D12ED0CED200DD3A7591784       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/ManagedElement=28  \N      \N
 \.
 
-COPY ties_data."CloudSite" ("id", "geo-location", "name" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-cloud_CloudSite" ("id", "geo-location", "name" )  FROM stdin;
 16EE17AE89DF11B69E94B3F6827C2C0E       POINT(59.4019881 17.9419888)    ORAN
 \.
 
-COPY ties_data."NodeCluster" ("id", "name", "REL_FK_located-at-cloudSite", "REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-cloud_NodeCluster" ("id", "name", "REL_FK_located-at-cloudSite", "REL_ID_NODECLUSTER_LOCATED_AT_CLOUDSITE" )  FROM stdin;
 015C2DDBD7AC722B34ED6A20EDEEB9C3       Example NodeCluster/45  16EE17AE89DF11B69E94B3F6827C2C0E        urn:base64:Tm9kZUNsdXN0ZXI6MDE1QzJEREJEN0FDNzIyQjM0RUQ2QTIwRURFRUI5QzM6TE9DQVRFRF9BVDpDbG91ZFNpdGU6MTZFRTE3QUU4OURGMTFCNjlFOTRCM0Y2ODI3QzJDMEU=
 \.
 
-COPY ties_data."Namespace" ("id", "name", "REL_FK_deployed-on-nodeCluster", "REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-cloud_Namespace" ("id", "name", "REL_FK_deployed-on-nodeCluster", "REL_ID_NAMESPACE_DEPLOYED_ON_NODECLUSTER" )  FROM stdin;
 1C02E96B2AAE036C7AE404BC38C308E0       Example Namespace/1     \N      \N
 \.
 
-COPY ties_data."78682DB1FFA2533BA45F8E4FAA5596E1A98479FC" ("id", "name" )  FROM stdin;
+COPY ties_data."bc563e4310b0538e6bdd35f52684160af5b23671" ("id", "name" )  FROM stdin;
 1C02E96B2AAE036C7AE404BC38C308E0       Example Namespace/1
 \.
 
-COPY ties_data."CloudNativeApplication" ("id", "name", "REL_FK_realised-managedElement", "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "REL_FK_comprised-by-cloudNativeSystem", "REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION", "REL_FK_deployed-on-namespace", "REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" )  FROM stdin;
+COPY ties_data."e01fcb87ad2c34ce66c34420255e25aaca270e5e" ("id", "name", "REL_FK_realised-managedElement", "REL_ID_MANAGEDELEMENT_REALISED_BY_CLOUDNATIVEAPPLICATION", "REL_FK_comprised-by-cloudNativeSystem", "REL_ID_CLOUDNATIVESYSTEM_COMPRISES_CLOUDNATIVEAPPLICATION", "REL_FK_deployed-on-namespace", "REL_ID_CLOUDNATIVEAPPLICATION_DEPLOYED_ON_NAMESPACE" )  FROM stdin;
 AD42D90497E93D276215DF6D3B899E17       Cloud Native CUUPApp/8  \N      \N      \N      \N      \N      \N
 719BD5C7CD8A939D76A83DA95DA45C01       Example Cloud App/9     \N      \N      \N      \N      1C02E96B2AAE036C7AE404BC38C308E0        urn:base64:Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA=
 416F31E6EB09055326621F4919D35BFF       Example Cloud App/10    \N      \N      \N      \N      \N      \N
 C549905CF3CC890CE5746C5E10ACF00D       Example Cloud App/19    \N      \N      \N      \N      \N      \N
 \.
 
-COPY ties_data."25978231183BE3B9ADD7DBE6C77F5E59696CDE5F" ("id", "name", "REL_FK_AB87B417CCD05C332DDD0C60F0C6AB41D38B05E5", "REL_ID_FC2F6A5A12917357B548C83F4B0C1AD58FA61413", "REL_FK_8C98B70070BBD11F90F192DDA3ECF6302390E956", "REL_ID_AFBF10D23507AD3B6408947D2A9AF8465BA7B08C" )  FROM stdin;
+COPY ties_data."5f8facd51b2bbddc90d9dee9be697907441892d0" ("id", "name", "REL_FK_AB87B417CCD05C332DDD0C60F0C6AB41D38B05E5", "REL_ID_FC2F6A5A12917357B548C83F4B0C1AD58FA61413", "REL_FK_8C98B70070BBD11F90F192DDA3ECF6302390E956", "REL_ID_AFBF10D23507AD3B6408947D2A9AF8465BA7B08C" )  FROM stdin;
 AD42D90497E93D276215DF6D3B899E17       Cloud Native CUUPApp/8  \N      \N      \N      \N
 719BD5C7CD8A939D76A83DA95DA45C01       Example Cloud App/9     \N      \N      1C02E96B2AAE036C7AE404BC38C308E0        urn:base64:Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo3MTlCRDVDN0NEOEE5MzlENzZBODNEQTk1REE0NUMwMTpERVBMT1lFRF9PTjpOYW1lc3BhY2U6MUMwMkU5NkIyQUFFMDM2QzdBRTQwNEJDMzhDMzA4RTA=
 416F31E6EB09055326621F4919D35BFF       Example Cloud App/10    6F02817AFE4D53237DB235EBE5378613        urn:base64:TWFuYWdlZEVsZW1lbnQ6NkYwMjgxN0FGRTRENTMyMzdEQjIzNUVCRTUzNzg2MTM6UkVBTElTRURfQlk6Q2xvdWROYXRpdmVBcHBsaWNhdGlvbjo0MTZGMzFFNkVCMDkwNTUzMjY2MjFGNDkxOUQzNUJGRg== \N      \N
 C549905CF3CC890CE5746C5E10ACF00D       Example Cloud App/19    \N      \N      \N      \N
 \.
 
-COPY ties_data."Sector" ("id", "geo-location", "sectorId", "azimuth" )  FROM stdin;
+COPY ties_data."22174a23af5d5a96143c83ddfa78654df0acb697" ("id", "geo-location", "sectorId", "azimuth" )  FROM stdin;
 2F445AA5744FA3D230FD6838531F1407       POINT(59.4019881 17.9419888)    1       1
 F5128C172A70C4FCD4739650B06DE9E2       POINT(59.4019881 17.9419888)    2       2
 ADB1BAAC878C0BEEFE3175C60F44BB1D       POINT(59.4019881 17.9419888)    4       3
 \.
 
-COPY ties_data."GNBCUCPFunction" ("id", "pLMNId", "cmId", "fdn", "gNBCUName", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" )  FROM stdin;
+COPY ties_data."c4a425179d3089b5288fdf059079d0ea26977f0f" ("id", "pLMNId", "cmId", "fdn", "gNBCUName", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUCPFUNCTION" )  FROM stdin;
 \.
 
-COPY ties_data."GNBCUUPFunction" ("id", "cmId", "fdn", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" )  FROM stdin;
-BFEEAC2CE60273CB0A78319CC201A7FE       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBCUUPFunction=8  1       8       E64371CD4D12ED0CED200DD3A7591784        urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU=
+COPY ties_data."8fe520ccd54b8f72ef7b2d3061264ddc2481e4eb" ("id", "cmId", "fdn", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBCUUPFUNCTION" )  FROM stdin;
+BFEEAC2CE60273CB0A78319CC201A7FE       \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBCUUPFunction=8  1       8       E64371CD4D12ED0CED200DD3A7591784        urn:base64:TWFuYWdlZEVsZW1lbnQ6RTY0MzcxQ0Q0RDEyRUQwQ0VEMjAwREQzQTc1OTE3ODQ6TUFOQUdFUzpHTkJDVVVQRnVuY3Rpb246QkZFRUFDMkNFNjAyNzNDQjBBNzgzMTlDQzIwMUE3RkU= ["gnbcucp-gnbcuup-model:Weekend", "gnbcucp-gnbcuup-model:Weekday"]      {"gnbcucp-gnbcuup-model:metadata": "value1", "gnbcucp-gnbcuup-model:meta": "value2"}
 \.
 
-COPY ties_data."GNBDUFunction" ("id", "gNBDUId", "cmId", "fdn", "dUpLMNId", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "CD_sourceIds" )  FROM stdin;
-D3215E08570BE58339C7463626B50E37       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=9    {"mcc":"456","mnc":"82"}        1       9       DA1039E77700A9EEFFA280049ECE9227        urn:base64:TWFuYWdlZEVsZW1lbnQ6REExMDM5RTc3NzAwQTlFRUZGQTI4MDA0OUVDRTkyMjc6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOkQzMjE1RTA4NTcwQkU1ODMzOUM3NDYzNjI2QjUwRTM3     []
-1050570EBB1315E1AE7A9FD5E1400A00       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=10   {"mcc":"456","mnc":"82"}        2       10      6F02817AFE4D53237DB235EBE5378613        urn:base64:TWFuYWdlZEVsZW1lbnQ6NkYwMjgxN0FGRTRENTMyMzdEQjIzNUVCRTUzNzg2MTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjEwNTA1NzBFQkIxMzE1RTFBRTdBOUZENUUxNDAwQTAw     []
-25E690E22BDA90B9C4FEE1F083CBA597       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=13   {"mcc":"456","mnc":"82"}        2       13      27500EB447000209EE6E3CA1B31FBA92        urn:base64:TWFuYWdlZEVsZW1lbnQ6Mjc1MDBFQjQ0NzAwMDIwOUVFNkUzQ0ExQjMxRkJBOTI6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjI1RTY5MEUyMkJEQTkwQjlDNEZFRTFGMDgzQ0JBNTk3     []
-5A3085C3400C3096E2ED2321452766B1       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=14   {"mcc":"456","mnc":"82"}        2       14      06222D277EE209CD8DCA1FE61CE752E6        urn:base64:TWFuYWdlZEVsZW1lbnQ6MDYyMjJEMjc3RUUyMDlDRDhEQ0ExRkU2MUNFNzUyRTY6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBMzA4NUMzNDAwQzMwOTZFMkVEMjMyMTQ1Mjc2NkIx     []
-5A548EA9D166341776CA0695837E55D8       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16   {"mcc":"456","mnc":"82"}        2       16      DC86CA7724113F4C0DF42BFEAA17FD53        urn:base64:TWFuYWdlZEVsZW1lbnQ6REM4NkNBNzcyNDExM0Y0QzBERjQyQkZFQUExN0ZENTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBNTQ4RUE5RDE2NjM0MTc3NkNBMDY5NTgzN0U1NUQ4     ["urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16","urn:cmHandle:/395221E080CCF0FD1924103B15873814"]
-4CFF136200A2DE36205A13559C55DB2A       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=19   {"mcc":"456","mnc":"82"}        2       19      8D51EFC759166044DACBCA63C4EDFC51        urn:base64:TWFuYWdlZEVsZW1lbnQ6OEQ1MUVGQzc1OTE2NjA0NERBQ0JDQTYzQzRFREZDNTE6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjRDRkYxMzYyMDBBMkRFMzYyMDVBMTM1NTlDNTVEQjJB     []
+COPY ties_data."o-ran-smo-teiv-ran-logical_GNBDUFunction" ("id", "gNBDUId", "cmId", "fdn", "dUpLMNId", "gNBIdLength", "gNBId", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "CD_sourceIds", "CD_classifiers", "CD_decorators", "REL_CD_classifiers_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION", "REL_CD_decorators_MANAGEDELEMENT_MANAGES_GNBDUFUNCTION" )  FROM stdin;
+D3215E08570BE58339C7463626B50E37       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=9    {"mcc":{"mcca":"123","mccb":{"mccba":123}},"mcb":["a123","b123","c012"],"mnc":"82"}     1       9       DA1039E77700A9EEFFA280049ECE9227        urn:base64:TWFuYWdlZEVsZW1lbnQ6REExMDM5RTc3NzAwQTlFRUZGQTI4MDA0OUVDRTkyMjc6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOkQzMjE1RTA4NTcwQkU1ODMzOUM3NDYzNjI2QjUwRTM3     []      []      {}      []      {}
+1050570EBB1315E1AE7A9FD5E1400A00       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=10   {"mcc":{"mcca":"234","mccb":{"mccba":234}},"mcb":["a123","b123","c012"],"mnc":"82"}     2       10      6F02817AFE4D53237DB235EBE5378613        urn:base64:TWFuYWdlZEVsZW1lbnQ6NkYwMjgxN0FGRTRENTMyMzdEQjIzNUVCRTUzNzg2MTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjEwNTA1NzBFQkIxMzE1RTFBRTdBOUZENUUxNDAwQTAw     []      []      {}      []      {}
+25E690E22BDA90B9C4FEE1F083CBA597       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=13   {"mcc":{"mcca":"345","mccb":{"mccba":345}},"mcb":["a123","b123","c012"],"mnc":"82"}     2       13      27500EB447000209EE6E3CA1B31FBA92        urn:base64:TWFuYWdlZEVsZW1lbnQ6Mjc1MDBFQjQ0NzAwMDIwOUVFNkUzQ0ExQjMxRkJBOTI6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjI1RTY5MEUyMkJEQTkwQjlDNEZFRTFGMDgzQ0JBNTk3     []      []      {}      []      {}
+5A3085C3400C3096E2ED2321452766B1       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=14   {"mcc":{"mcca":"456","mccb":{"mccba":456}},"mcb":["a123","b123","c012"],"mnc":"82"}     2       14      06222D277EE209CD8DCA1FE61CE752E6        urn:base64:TWFuYWdlZEVsZW1lbnQ6MDYyMjJEMjc3RUUyMDlDRDhEQ0ExRkU2MUNFNzUyRTY6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBMzA4NUMzNDAwQzMwOTZFMkVEMjMyMTQ1Mjc2NkIx     []      []      {}      []      {}
+5A548EA9D166341776CA0695837E55D8       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16   {"mcc":{"mcca":"567","mccb":{"mccba":567}},"mcb":["a123","b123","c012"],"mnc":"82"}     2       16      DC86CA7724113F4C0DF42BFEAA17FD53        urn:base64:TWFuYWdlZEVsZW1lbnQ6REM4NkNBNzcyNDExM0Y0QzBERjQyQkZFQUExN0ZENTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBNTQ4RUE5RDE2NjM0MTc3NkNBMDY5NTgzN0U1NUQ4     ["urn:3gpp:dn:/SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16","urn:cmHandle:/395221E080CCF0FD1924103B15873814"] ["test-app-module:Indoor","test-app-module:Rural","test-app-module:Weekend"]    {"test-app-module:textdata":"Stockholm", "test-app-module:data":"test"} ["test-app-module:Indoor","test-app-module:Rural","test-app-module:Weekend"]    {"test-app-module:textdata":"Stockholm", "test-app-module:data":"test"}
+4CFF136200A2DE36205A13559C55DB2A       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=19   {"mcc":{"mcca":"678","mccb":{"mccba":678}},"mcb":["a123","b123","c012"],"mnc":"82"}     2       19      8D51EFC759166044DACBCA63C4EDFC51        urn:base64:TWFuYWdlZEVsZW1lbnQ6OEQ1MUVGQzc1OTE2NjA0NERBQ0JDQTYzQzRFREZDNTE6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjRDRkYxMzYyMDBBMkRFMzYyMDVBMTM1NTlDNTVEQjJB     []      []      {}      []      {}
 \.
 
-COPY ties_data."7D7AACEBB0E4E4732835BA4BFE708DDD3738962D" ("id", "gNBDUId", "cmId", "3786A6CA64C9422F9E7FC35B7B039F345BBDDA65", "dUpLMNId", "gNBIdLength", "gNBId", "REL_FK_48B14FA5B787C6398AD1DE5EE670AD0D2A2CB36F", "REL_ID_BDE0B6C74D14AC109D29A08D80E92D4D0DCAEB0B" )  FROM stdin;
+COPY ties_data."3fdb9cd7557edf559a0e4de88df220e7545884b5" ("id", "gNBDUId", "cmId", "3786A6CA64C9422F9E7FC35B7B039F345BBDDA65", "dUpLMNId", "gNBIdLength", "gNBId", "REL_FK_48B14FA5B787C6398AD1DE5EE670AD0D2A2CB36F", "REL_ID_BDE0B6C74D14AC109D29A08D80E92D4D0DCAEB0B" )  FROM stdin;
 D3215E08570BE58339C7463626B50E37       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=9    {"mcc":"456","mnc":"82"}        1       9       DA1039E77700A9EEFFA280049ECE9227        urn:base64:TWFuYWdlZEVsZW1lbnQ6REExMDM5RTc3NzAwQTlFRUZGQTI4MDA0OUVDRTkyMjc6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOkQzMjE1RTA4NTcwQkU1ODMzOUM3NDYzNjI2QjUwRTM3
 1050570EBB1315E1AE7A9FD5E1400A00       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=10   {"mcc":"456","mnc":"82"}        2       10      6F02817AFE4D53237DB235EBE5378613        urn:base64:TWFuYWdlZEVsZW1lbnQ6NkYwMjgxN0FGRTRENTMyMzdEQjIzNUVCRTUzNzg2MTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjEwNTA1NzBFQkIxMzE1RTFBRTdBOUZENUUxNDAwQTAw
 25E690E22BDA90B9C4FEE1F083CBA597       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=13   {"mcc":"456","mnc":"82"}        2       13      27500EB447000209EE6E3CA1B31FBA92        urn:base64:TWFuYWdlZEVsZW1lbnQ6Mjc1MDBFQjQ0NzAwMDIwOUVFNkUzQ0ExQjMxRkJBOTI6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjI1RTY5MEUyMkJEQTkwQjlDNEZFRTFGMDgzQ0JBNTk3
 5A3085C3400C3096E2ED2321452766B1       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=14   {"mcc":"456","mnc":"82"}        2       14      06222D277EE209CD8DCA1FE61CE752E6        urn:base64:TWFuYWdlZEVsZW1lbnQ6MDYyMjJEMjc3RUUyMDlDRDhEQ0ExRkU2MUNFNzUyRTY6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBMzA4NUMzNDAwQzMwOTZFMkVEMjMyMTQ1Mjc2NkIx
-5A548EA9D166341776CA0695837E55D8       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16   {"mcc":"456","mnc":"82"}        2       16      DC86CA7724113F4C0DF42BFEAA17FD53        urn:base64:TWFuYWdlZEVsZW1lbnQ6REM4NkNBNzcyNDExM0Y0QzBERjQyQkZFQUExN0ZENTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBNTQ4RUE5RDE2NjM0MTc3NkNBMDY5NTgzN0U1NUQ4
+5A548EA9D166341776CA0695837E55D8       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=16   {"mcc":"456","mnc":"82"}        2       16      DC86CA7724113F4C0DF42BFEAA17FD53        urn:base64:TWFuYWdlZEVsZW1lbnQ6REM4NkNBNzcyNDExM0Y0QzBERjQyQkZFQUExN0ZENTM6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjVBNTQ4RUE5RDE2NjM0MTc3NkNBMDY5NTgzN0U1NUD4
 4CFF136200A2DE36205A13559C55DB2A       \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/GNBDUFunction=19   {"mcc":"456","mnc":"82"}        2       19      8D51EFC759166044DACBCA63C4EDFC51        urn:base64:TWFuYWdlZEVsZW1lbnQ6OEQ1MUVGQzc1OTE2NjA0NERBQ0JDQTYzQzRFREZDNTE6TUFOQUdFUzpHTkJEVUZ1bmN0aW9uOjRDRkYxMzYyMDBBMkRFMzYyMDVBMTM1NTlDNTVEQjJB
 \.
 
-COPY ties_data."AntennaCapability" ("id", "nRFqBands", "eUtranFqBands", "cmId", "fdn", "geranFqBands", "REL_FK_used-by-lteSectorCarrier" )  FROM stdin;
+COPY ties_data."88f1bd76c7a935fb505cf235e6819f46c55ec98a" ("id", "nRFqBands", "eUtranFqBands", "cmId", "fdn", "geranFqBands", "REL_FK_used-by-lteSectorCarrier" )  FROM stdin;
 5835F77BE9D4E102316BD59195F6370B       ["123","456","789"]     ["123","4564","789"]    \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaCapability=1        ["123","456","789"]     \N
 A77B237A541B2D3225B4B61D3098E4AA       ["123","456","789"]     ["123","4564","789"]    \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaCapability=3        ["123","456","789"]     \N
 \.
 
-COPY ties_data."NRCellDU" ("id", "nRPCI", "cmId", "cellLocalId", "fdn", "nCI", "nRTAC", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_NRCELLDU", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-logical_NRCellDU" ("id", "nRPCI", "cmId", "cellLocalId", "fdn", "nCI", "nRTAC", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_NRCELLDU", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRCELLDU" )  FROM stdin;
 98C3A4591A37718E1330F0294E23B62A       789     \N      1       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=1 1       456     F5128C172A70C4FCD4739650B06DE9E2        urn:base64:U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==
 F9546E82313AC1D5E690DCD7BE55606F       789     \N      2       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=2 2       456     F5128C172A70C4FCD4739650B06DE9E2        urn:base64:U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTpGOTU0NkU4MjMxM0FDMUQ1RTY5MERDRDdCRTU1NjA2Rg==     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpGOTU0NkU4MjMxM0FDMUQ1RTY5MERDRDdCRTU1NjA2Rg==
 B480427E8A0C0B8D994E437784BB382F       789     \N      3       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=3 3       456     F5128C172A70C4FCD4739650B06DE9E2        urn:base64:U2VjdG9yOkY1MTI4QzE3MkE3MEM0RkNENDczOTY1MEIwNkRFOUUyOkdST1VQUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==
@@ -122,7 +123,7 @@ B480427E8A0C0B8D994E437784BB382F    789     \N      3       SubNetwork=SolarSystem/SubNetwork=Eart
 B3B0A1939EFCA654A37005B6A7F24BD7       789     \N      93      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=93        93      456     \N      \N      4CFF136200A2DE36205A13559C55DB2A        urn:base64:R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTpCM0IwQTE5MzlFRkNBNjU0QTM3MDA1QjZBN0YyNEJENw==
 \.
 
-COPY ties_data."50AC08AB775076E74FC4891954F1D99D3D293ACC" ("id", "nRPCI", "cmId", "020335B0F627C169E24167748C38FE756FB34AE2", "fdn", "nCI", "nRTAC", "REL_FK_609963BFEE15FF824280FBE201313C3CDACDDDCE", "REL_ID_040FC8B06B420BA5708AF4798102D1E65FB4DC61" )  FROM stdin;
+COPY ties_data."300672c8a708d6af0b9af2f9accdff5e6e005721" ("id", "nRPCI", "cmId", "020335B0F627C169E24167748C38FE756FB34AE2", "fdn", "nCI", "nRTAC", "REL_FK_609963BFEE15FF824280FBE201313C3CDACDDDCE", "REL_ID_040FC8B06B420BA5708AF4798102D1E65FB4DC61" )  FROM stdin;
 98C3A4591A37718E1330F0294E23B62A       789     \N      1       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=1 1       456     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTo5OEMzQTQ1OTFBMzc3MThFMTMzMEYwMjk0RTIzQjYyQQ==
 F9546E82313AC1D5E690DCD7BE55606F       789     \N      2       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=2 2       456     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpGOTU0NkU4MjMxM0FDMUQ1RTY5MERDRDdCRTU1NjA2Rg==
 B480427E8A0C0B8D994E437784BB382F       789     \N      3       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=3 3       456     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUkNlbGxEVTpCNDgwNDI3RThBMEMwQjhEOTk0RTQzNzc4NEJCMzgyRg==
@@ -132,86 +133,75 @@ B3B0A1939EFCA654A37005B6A7F24BD7  789     \N      93      SubNetwork=SolarSystem/SubNetwork=Ear
 F26F279E91D0941DB4F646E707EA403A       789     \N      94      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRCellDU=94        94      456     4CFF136200A2DE36205A13559C55DB2A        urn:base64:R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpQUk9WSURFUzpOUkNlbGxEVTpGMjZGMjc5RTkxRDA5NDFEQjRGNjQ2RTcwN0VBNDAzQQ==
 \.
 
-COPY ties_data."NRSectorCarrier" ("id", "fdn", "frequencyUL", "cmId", "essScLocalId", "arfcnUL", "frequencyDL", "arfcnDL", "REL_FK_used-by-nrCellDu", "REL_ID_NRCELLDU_USES_NRSECTORCARRIER", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY" )  FROM stdin;
-E49D942C16E0364E1E0788138916D70C       SubNetwork=SolarSyst3em/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRSectorCarrier=3 20      \N      20      3       20      20      B480427E8A0C0B8D994E437784BB382F        urn:base64:TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM=     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM= A77B237A541B2D3225B4B61D3098E4AA        urn:base64:TlJTZWN0b3JDYXJyaWVyOkU0OUQ5NDJDMTZFMDM2NEUxRTA3ODgxMzg5MTZENzBDOlVTRVM6QW50ZW5uYUNhcGFiaWxpdHk6QTc3QjIzN0E1NDFCMkQzMjI1QjRCNjFEMzA5OEU0QUE=
+COPY ties_data."39a335dca201ef99ae06f4ffd1908b534f8c6c39" ("id", "fdn", "frequencyUL", "cmId", "essScLocalId", "arfcnUL", "frequencyDL", "arfcnDL", "REL_FK_used-by-nrCellDu", "REL_ID_NRCELLDU_USES_NRSECTORCARRIER", "REL_FK_provided-by-gnbduFunction", "REL_ID_GNBDUFUNCTION_PROVIDES_NRSECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_NRSECTORCARRIER_USES_ANTENNACAPABILITY", "CD_classifiers", "CD_decorators" )  FROM stdin;
+E49D942C16E0364E1E0788138916D70C       SubNetwork=SolarSyst3em/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/NRSectorCarrier=3 20      \N      20      3       20      20      B480427E8A0C0B8D994E437784BB382F        urn:base64:TlJDZWxsRFU6QjQ4MDQyN0U4QTBDMEI4RDk5NEU0Mzc3ODRCQjM4MkY6VVNFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM=     D3215E08570BE58339C7463626B50E37        urn:base64:R05CRFVGdW5jdGlvbjpEMzIxNUUwODU3MEJFNTgzMzlDNzQ2MzYyNkI1MEUzNzpQUk9WSURFUzpOUlNlY3RvckNhcnJpZXI6RTQ5RDk0MkMxNkUwMzY0RTFFMDc4ODEzODkxNkQ3MEM= A77B237A541B2D3225B4B61D3098E4AA        urn:base64:TlJTZWN0b3JDYXJyaWVyOkU0OUQ5NDJDMTZFMDM2NEUxRTA3ODgxMzg5MTZENzBDOlVTRVM6QW50ZW5uYUNhcGFiaWxpdHk6QTc3QjIzN0E1NDFCMkQzMjI1QjRCNjFEMzA5OEU0QUE= ["gnbcucp-gnbcuup-model:Weekend", "gnbcucp-gnbcuup-model:Weekday"]      {"gnbcucp-gnbcuup-model:metadata": "value1", "gnbcucp-gnbcuup-model:meta": "value2"}
 \.
 
-COPY ties_data."AntennaModule" ("id", "mechanicalAntennaTilt", "fdn", "cmId", "antennaModelNumber", "totalTilt", "mechanicalAntennaBearing", "positionWithinSector", "electricalAntennaTilt", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_ANTENNAMODULE", "REL_FK_installed-at-site", "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE" )  FROM stdin;
-278A05C67D47D117C2DC5BDF5E00AE70       123     SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModule=1    \N      ['123-abc']     45      123     ['123', '456', '789']   1       ADB1BAAC878C0BEEFE3175C60F44BB1D        urn:base64:U2VjdG9yOkFEQjFCQUFDODc4QzBCRUVGRTMxNzVDNjBGNDRCQjFEOkdST1VQUzpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcw \N      \N
-279A05C67D47D117C2DC5BDF5E00AE70       456     SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModule=2    \N      ['123-xyz']     45      123     ['123', '456', '789']   1       \N      \N      \N      \N
+COPY ties_data."f8caf5ebe876c3001d67efe06e4d83abf0babe31" ("id", "mechanicalAntennaTilt", "antennaBeamWidth", "geo-location", "fdn", "cmId", "antennaModelNumber", "totalTilt", "mechanicalAntennaBearing", "positionWithinSector", "electricalAntennaTilt", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_ANTENNAMODULE", "REL_FK_installed-at-site", "REL_ID_ANTENNAMODULE_INSTALLED_AT_SITE" )  FROM stdin;
+278A05C67D47D117C2DC5BDF5E00AE70       123     \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModule=1    \N      ['123-abc']     45      123     ['123', '456', '789']   1       ADB1BAAC878C0BEEFE3175C60F44BB1D        urn:base64:U2VjdG9yOkFEQjFCQUFDODc4QzBCRUVGRTMxNzVDNjBGNDRCQjFEOkdST1VQUzpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcw \N      \N
+279A05C67D47D117C2DC5BDF5E00AE70       456     \N      \N      SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModule=2    \N      ['123-xyz']     45      123     ['123', '456', '789']   1       \N      \N      \N      \N
 \.
 
-COPY ties_data."B69D3E92CA22CE61B921AE61BD3CF031791CF714" ("id", "fdn" )  FROM stdin;
+COPY ties_data."341622dca4e0350289717b52df5883edc3fa0280" ("id", "fdn" )  FROM stdin;
 378A05C67D47D117C2DC5BDF5E00AE70       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=11
 379A05C67D47D117C2DC5BDF5E00AE70       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=12
 478A05C67D47D117C2DC5BDF5E00AE70       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=21
 479A05C67D47D117C2DC5BDF5E00AE70       SubNetwork=SolarSystem/SubNetwork=Earth/SubNetwork=Europe/SubNetwork=Hungary/AntennaModuleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee=22
 \.
 
-COPY ties_data."ENodeBFunction" ("id", "eNBId", "cmId", "eNodeBPlmnId", "fdn", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "REL_FK_realised-by-physicalNetworkAppliance", "REL_ID_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-logical_ENodeBFunction" ("id", "eNBId", "cmId", "eNodeBPlmnId", "fdn", "REL_FK_managed-by-managedElement", "REL_ID_MANAGEDELEMENT_MANAGES_ENODEBFUNCTION", "REL_FK_realised-by-physicalNetworkAppliance", "REL_ID_ENODEBFUNCTION_REALISED_BY_PHYSICALNETWORKAPPLIANCE" )  FROM stdin;
 \.
 
-COPY ties_data."EUtranCell" ("id", "cellId", "cmId", "earfcn", "duplexType", "tac", "fdn", "earfcndl", "earfcnul", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_EUTRANCELL", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-logical_EUtranCell" ("id", "cellId", "cmId", "earfcn", "duplexType", "tac", "fdn", "earfcndl", "earfcnul", "REL_FK_grouped-by-sector", "REL_ID_SECTOR_GROUPS_EUTRANCELL", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_EUTRANCELL" )  FROM stdin;
 \.
 
-COPY ties_data."LTESectorCarrier" ("id", "fdn", "cmId", "sectorCarrierType", "essScLocalId", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY", "REL_FK_used-by-euTranCell", "REL_ID_EUTRANCELL_USES_LTESECTORCARRIER" )  FROM stdin;
+COPY ties_data."c88307168935f02fdecc084ea5040bb9db16c701" ("id", "fdn", "cmId", "sectorCarrierType", "essScLocalId", "REL_FK_provided-by-enodebFunction", "REL_ID_ENODEBFUNCTION_PROVIDES_LTESECTORCARRIER", "REL_FK_used-antennaCapability", "REL_ID_LTESECTORCARRIER_USES_ANTENNACAPABILITY", "REL_FK_used-by-euTranCell", "REL_ID_EUTRANCELL_USES_LTESECTORCARRIER" )  FROM stdin;
 \.
 
-COPY ties_data."NRCellCU" ("id", "fdn", "cmId", "plmnId", "nCI", "cellLocalId", "nRTAC", "REL_FK_provided-by-gnbcucpFunction", "REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-logical_NRCellCU" ("id", "fdn", "cmId", "plmnId", "nCI", "cellLocalId", "nRTAC", "REL_FK_provided-by-gnbcucpFunction", "REL_ID_GNBCUCPFUNCTION_PROVIDES_NRCELLCU" )  FROM stdin;
 \.
 
-COPY ties_data."PhysicalNetworkAppliance" ("id", "geo-location", "cmId", "name", "type", "REL_FK_installed-at-site", "REL_ID_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" )  FROM stdin;
+COPY ties_data."57a20807ab3f39c86b0b5bf9a819e0881353fa1e" ("id", "geo-location", "cmId", "name", "type", "REL_FK_installed-at-site", "REL_ID_PHYSICALNETWORKAPPLIANCE_INSTALLED_AT_SITE" )  FROM stdin;
 \.
 
-COPY ties_data."Site" ("id", "geo-location", "cmId", "name" )  FROM stdin;
+COPY ties_data."o-ran-smo-teiv-ran-equipment_Site" ("id", "geo-location", "cmId", "name" )  FROM stdin;
 \.
 
-COPY ties_data."GNBCUCPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ("id", "aSide_GNBCUCPFunction", "bSide_CloudNativeApplication" )  FROM stdin;
+COPY ties_data."7cd7062ea24531b2f48e4f2fdc51eaf0b82f88c7" ("id", "aSide_GNBCUCPFunction", "bSide_CloudNativeApplication" )  FROM stdin;
 \.
 
-COPY ties_data."GNBCUUPFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ("id", "aSide_GNBCUUPFunction", "bSide_CloudNativeApplication" )  FROM stdin;
-urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc=        BFEEAC2CE60273CB0A78319CC201A7FE        AD42D90497E93D276215DF6D3B899E17
+COPY ties_data."70a4a84bca01ea022ab24d8cb82422c572922675" ("id", "aSide_GNBCUUPFunction", "bSide_CloudNativeApplication", "CD_classifiers", "CD_decorators" )  FROM stdin;
+urn:base64:R05CQ1VVUEZ1bmN0aW9uOkJGRUVBQzJDRTYwMjczQ0IwQTc4MzE5Q0MyMDFBN0ZFOlJFQUxJU0VEX0JZOkNsb3VkTmF0aXZlQXBwbGljYXRpb246QUQ0MkQ5MDQ5N0U5M0QyNzYyMTVERjZEM0I4OTlFMTc=        BFEEAC2CE60273CB0A78319CC201A7FE        AD42D90497E93D276215DF6D3B899E17        ["gnbcucp-gnbcuup-model:Weekend", "gnbcucp-gnbcuup-model:Weekday"]      {"gnbcucp-gnbcuup-model:metadata": "value1", "gnbcucp-gnbcuup-model:meta": "value2"}
 \.
 
-COPY ties_data."GNBDUFUNCTION_REALISED_BY_CLOUDNATIVEAPPLICATION" ("id", "aSide_GNBDUFunction", "bSide_CloudNativeApplication" )  FROM stdin;
+COPY ties_data."10484f157f490eb5b27e40dbfaf4d5f2be17c57c" ("id", "aSide_GNBDUFunction", "bSide_CloudNativeApplication" )  FROM stdin;
 urn:base64:R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE    4CFF136200A2DE36205A13559C55DB2A        C549905CF3CC890CE5746C5E10ACF00D
 \.
 
-COPY ties_data."AC201B3A42917A9A983A1E3683B67C38C50630FC" ("id", "aSide_B0FD0521695A211BFF76F413A31F28CBA32E57ED", "bSide_84EF1134719BB6FCF33A94FF770311FC722BCF41" )  FROM stdin;
+COPY ties_data."f86057a8762a50b1c7fb07af9d5c001bffaefd15" ("id", "aSide_B0FD0521695A211BFF76F413A31F28CBA32E57ED", "bSide_84EF1134719BB6FCF33A94FF770311FC722BCF41" )  FROM stdin;
 urn:base64:R05CRFVGdW5jdGlvbjo0Q0ZGMTM2MjAwQTJERTM2MjA1QTEzNTU5QzU1REIyQTpSRUFMSVNFRF9CWTpDbG91ZE5hdGl2ZUFwcGxpY2F0aW9uOkM1NDk5MDVDRjNDQzg5MENFNTc0NkM1RTEwQUNGMDBE    4CFF136200A2DE36205A13559C55DB2A        C549905CF3CC890CE5746C5E10ACF00D
 \.
 
-COPY ties_data."ANTENNACAPABILITY_REALISED_BY_ANTENNAMODULE" ("id", "aSide_AntennaCapability", "bSide_AntennaModule" )  FROM stdin;
+COPY ties_data."5b8a47d4a8297a0a1d31e091af06e26d25ef6caf" ("id", "aSide_AntennaCapability", "bSide_AntennaModule" )  FROM stdin;
 \.
 
-COPY ties_data."ANTENNAMODULE_REALISED_BY_ANTENNAMODULE" ("id", "aSide_AntennaModule", "bSide_AntennaModule" )  FROM stdin;
+COPY ties_data."5123d0adfb7b4a04e7f2e5e1783f476ed5cf76f6" ("id", "aSide_AntennaModule", "bSide_AntennaModule" )  FROM stdin;
 urn:base64:QW50ZW5uYU1vZHVsZToyNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjI3OEEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==    278A05C67D47D117C2DC5BDF5E00AE70        279A05C67D47D117C2DC5BDF5E00AE70
 \.
 
-COPY ties_data."B9B76FD20FF23B2A41C82CB5EDF6FA25B6AC2BC6" ("id", "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C", "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E" )  FROM stdin;
+COPY ties_data."cd39d44beed963d50df42cd301e63d288f911c97" ("id", "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C", "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E" )  FROM stdin;
 urn:base64:QW50ZW5uYU1vZHVsZTozNzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpSRUFMSVNFRF9CWTpBbnRlbm5hTW9kdWxlOjM3OUEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==    378A05C67D47D117C2DC5BDF5E00AE70        379A05C67D47D117C2DC5BDF5E00AE70
 \.
 
-COPY ties_data."C35AE10CFF62DEDC5E3FC3C40E47373B10800818" ("id", "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C", "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E" )  FROM stdin;
+COPY ties_data."c6f3a3396e9165e886da928c5fe1382fb20dc850" ("id", "aSide_2A2D3374BF907674FA1905478E30ACB8882DC03C", "bSide_EE6DD4A2CFD743779BBCBFC18FC296EF6D72EB1E" )  FROM stdin;
 urn:base64:QW50ZW5uYU1vZHVsZTo0NzhBMDVDNjdENDdEMTE3QzJEQzVCREY1RTAwQUU3MDpERVBMT1lFRF9CWTpBbnRlbm5hTW9kdWxlOjQ3OUEwNUM2N0Q0N0QxMTdDMkRDNUJERjVFMDBBRTcwCg==    478A05C67D47D117C2DC5BDF5E00AE70        479A05C67D47D117C2DC5BDF5E00AE70
 \.
 
-COPY ties_model.module_reference("name", "includedModules", "content", "ownerAppId", "status") FROM stdin;
-gnbdu-function-model   []      Z25kYnUtZnVuY3Rpb24tbW9kZWwgeWFuZyBtb2RlbCBmaWxlCg==    ADDITIONAL_MODULE       IN_USAGE
-gnbcucp-gnbcuup-model  []      Z25iY3VjcC1nbmJjdXVwLW1vZGVsIHlhbmcgbW9kZWwgZmlsZQo=    ADDITIONAL_MODULE       IN_USAGE
-gnbcucp-gnbcuup-old-model      []      Z25iY3VjcC1nbmJjdXVwLW1vZGVsIHlhbmcgbW9kZWwgZmlsZQo=    ADDITIONAL_MODULE       DEPRECATED
-\.
-
-COPY ties_model.decorators ("name", "dataType", "moduleReferenceName" )  FROM stdin;
-gnbdu-function-model:location  TEXT    gnbdu-function-model
-gnbcucp-gnbcuup-model:metadata JSONB   gnbcucp-gnbcuup-model
-gnbcucp-gnbcuup-old-model:metadata     JSONB   gnbcucp-gnbcuup-old-model
-\.
-
-COPY ties_model.classifiers ("name", "moduleReferenceName" )  FROM stdin;
-gnbdu-function-model:Rural     gnbdu-function-model
-gnbcucp-gnbcuup-model:Weekend  gnbcucp-gnbcuup-model
-gnbcucp-gnbcuup-old-model:Weekend      gnbcucp-gnbcuup-old-model
+COPY ties_model.module_reference("name", "namespace", "domain", "includedModules", "revision", "content") FROM stdin;
+gnbdu-function-model   \N      \N      []      2024-05-02      Z25kYnUtZnVuY3Rpb24tbW9kZWwgeWFuZyBtb2RlbCBmaWxlCg==
+gnbcucp-gnbcuup-model  \N      \N      []      2024-05-02      Z25iY3VjcC1nbmJjdXVwLW1vZGVsIHlhbmcgbW9kZWwgZmlsZQo=
+gnbcucp-gnbcuup-old-model      \N      \N      []      2024-05-02      Z25iY3VjcC1nbmJjdXVwLW1vZGVsIHlhbmcgbW9kZWwgZmlsZQo=
+module-rapp-module     \N      \N      []      2024-05-01      dGVzdE1vZHVsZQo=
 \.
 
 ;
\ No newline at end of file
diff --git a/teiv/src/test/resources/pgsqlschema/model.sql b/teiv/src/test/resources/pgsqlschema/model.sql
new file mode 100644 (file)
index 0000000..335817f
--- /dev/null
@@ -0,0 +1,91 @@
+--
+-- ============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=========================================================
+--
+
+BEGIN;
+
+COPY ties_model.hash_info("name", "hashedValue", "type") FROM stdin;
+FK_test-built-in-module_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_aSide_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       FK_2A5C84A2226EE0FCAAA513CC5AF4CD78DDDAF49F     CONSTRAINT
+FK_test-built-in-module_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_bSide_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       FK_FBFE10B6F165A8EC2086B8DEAFA238E0DD6643F5     CONSTRAINT
+FK_test-built-in-module_ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_aSide_EntityTypeA   FK_2839E6FFDF7F3DF2687DAC3E57082AD6B22E9B30     CONSTRAINT
+FK_test-built-in-module_ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_bSide_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters     FK_33B5669A341584011D9A73FB491FF2242A158057     CONSTRAINT
+FK_test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters_REL_FK_provided-by-entityTypeA       FK_B0923C0CCED6CF47CFF759FFE1B810D6CA10D228     CONSTRAINT
+FK_test-built-in-module_EntityTypeA_REL_FK_grouped-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters   FK_02592FFA6AFD7EAC7AFAD936E3CD50708E4533E0     CONSTRAINT
+FK_test-built-in-module_EntityTypeA_REL_FK_used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters      FK_5CD9BCFA08278DA0BF902BAFBCFCDFCE4FF25FEF     CONSTRAINT
+PK_test-built-in-module_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_id    PK_020B03AED5787D1B43ABBD9F2C26B494ADDBC7CD     CONSTRAINT
+PK_test-built-in-module_ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_id  PK_4C48AAFA2160D74F9D13364AA2BE4FDB8A60689D     CONSTRAINT
+PK_test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters_id   PK_7A421D526B36AA9EEF17964BC27011A12FF80DBB     CONSTRAINT
+PK_test-built-in-module_EntityTypeA_id PK_test-built-in-module_EntityTypeA_id  CONSTRAINT
+REL_CD_classifiers_ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS        REL_CD_75B161E740A96ADBAE6F08D4F85684ECC29049B9 COLUMN
+REL_CD_classifiers_ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS      REL_CD_E2C3D598A06EA38133E23C1756ED58A66FE21386 COLUMN
+REL_CD_classifiers_ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS  REL_CD_74A44B167FDF37D6C8E79B5033FEF8BC384C881A COLUMN
+REL_CD_decorators_ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS REL_CD_6F7211CAF505AECF9A565BC7A4AF56E7032CCC54 COLUMN
+REL_CD_decorators_ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS       REL_CD_92559ED73C761B860682582A040E745ECEC194D5 COLUMN
+REL_CD_decorators_ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS   REL_CD_F5B24D9A7273119D4D1519473D9EC88CB407E5CA COLUMN
+REL_CD_sourceIds_ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS  REL_CD_AB6BDADE3F6C750C9FDB6CAD6059C4CBCE67236C COLUMN
+REL_CD_sourceIds_ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS        REL_CD_F26C39EC1F710F3096BE0588F6783A03A378516A COLUMN
+REL_CD_sourceIds_ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS    REL_CD_3B43F80D423BF8F96A2906643B7B4712604FC28B COLUMN
+REL_FK_grouped-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       REL_FK_B7E43411C5C5079D49856E74A9FA63BD20C522C5 COLUMN
+REL_FK_provided-by-entityTypeA REL_FK_provided-by-entityTypeA  COLUMN
+REL_FK_used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters  REL_FK_A86937FEBD025CFDF6EE5BC386B4C569EB2652DA COLUMN
+REL_ID_ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS    REL_ID_31A5B55158140557F09AE15589A8B8038416689B COLUMN
+REL_ID_ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS  REL_ID_F64052A4F8BB3CC533EC15BBFB5E224F600735B0 COLUMN
+REL_ID_ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS      REL_ID_A974AD6DD8C4CA281D45693D3A61AE98FEE82845 COLUMN
+UNIQUE_test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters_REL_ID_ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS    UNIQUE_B1C2FC9A96300B2BE45785DE60E152D8E85FBE14 CONSTRAINT
+UNIQUE_test-built-in-module_EntityTypeA_REL_ID_ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS    UNIQUE_7715FF94E14F99CE4994ABBD8C2583CBA9EAE5BD CONSTRAINT
+UNIQUE_test-built-in-module_EntityTypeA_REL_ID_ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS      UNIQUE_67DB5E4BC34AB83BDC069A5CAF73B57967D5C2D9 CONSTRAINT
+aSide_EntityTypeA      aSide_EntityTypeA       COLUMN
+aSide_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters        aSide_C812C285BEFA4EC42026AB075D9C65200A00F815  COLUMN
+attributeA1WithAttributeNameLengthLongerThanSixtyThreeCharacters       6446B2D4BE5E367FB0396383C4BDEF42D51CF74F        COLUMN
+attributeA2WithAttributeNameLengthLongerThanSixtyThreeCharacters       F03B534AFF0872651FED60C54AB56BEDADAB94B5        COLUMN
+attributeA3WithAttributeNameLengthLongerThanSixtyThreeCharacters       333177AA699C0DE6399503171DCF48FB396322B0        COLUMN
+attributeA4WithAttributeNameLengthLongerThanSixtyThreeCharacters       027B1A8019C6DEF04558B90D9D8B52253B82FEC6        COLUMN
+attributeA5WithAttributeNameLengthLongerThanSixtyThreeCharacters       478D043D81678134EF1C8BFB073A70F882C4AF12        COLUMN
+attributeA6WithAttributeNameLengthLongerThanSixtyThreeCharacters       8252D18D44F633831557076D827993C45278024D        COLUMN
+attributeA7WithAttributeNameLengthLongerThanSixtyThreeCharacters       68C48305AB6C3A30DD927F5D38562379374A4B31        COLUMN
+bSide_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters        bSide_A85CE100A012A71EF2ABA306BABE484AC2AAE515  COLUMN
+test-built-in-module_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS  FB1E124031A12CD85D3335194B39B193723A0490        TABLE
+test-built-in-module_ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS        54110F8D085BBBA7BB6DE5CE71B511562090F7EE        TABLE
+test-built-in-module_EntityTypeA       test-built-in-module_EntityTypeA        TABLE
+test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters 10B9F515756871D3EF6558FAF1F112BAE207945D        TABLE
+\.
+
+COPY ties_model.module_reference("name", "namespace", "domain", "includedModules", "revision", "content") FROM stdin;
+test-existing-rapp-module      \N      \N      []      2024-05-02      dGVzdA==
+test-module-for-deletion       \N      \N      []      2024-05-02      dGVzdA==
+test-module-in-deleting-state  \N      \N      []      2024-05-02      dGVzdA==
+module-rapp-module     \N      \N      []      2024-05-01      dGVzdE1vZHVsZQo=
+test-built-in-module   test-built-in-namespace TEST    []      2024-05-24      bW9kdWxlIHRlc3QtYnVpbHQtaW4tbW9kdWxlIHsNCiAgICB5YW5nLXZlcnNpb24gMS4xOw0KICAgIG5hbWVzcGFjZSAidGVzdC1idWlsdC1pbi1uYW1lc3BhY2UiOw0KDQogICAgaW1wb3J0IG8tcmFuLXNtby10ZWl2LWNvbW1vbi15YW5nLXR5cGVzIHsgcHJlZml4IG9yLXRlaXYtdHlwZXM7IH0NCg0KICAgIGltcG9ydCBvLXJhbi1zbW8tdGVpdi1jb21tb24teWFuZy1leHRlbnNpb25zIHsgcHJlZml4IG9yLXRlaXYteWV4dDsgfQ0KDQogICAgaW1wb3J0IF8zZ3BwLWNvbW1vbi15YW5nLXR5cGVzIHsgcHJlZml4IHR5cGVzM2dwcDsgfQ0KDQogICAgaW1wb3J0IGlldGYtZ2VvLWxvY2F0aW9uIHsNCiAgICAgICAgcHJlZml4IGdlbzsNCiAgICAgICAgcmVmZXJlbmNlICJSRkMgOTE3OTogQSBZQU5HIEdyb3VwaW5nIGZvciBHZW9ncmFwaGljIExvY2F0aW9ucyI7DQogICAgfQ0KDQogICAgb3JnYW5pemF0aW9uICJFcmljc3NvbiBBQiI7DQogICAgY29udGFjdCAiRXJpY3Nzb24gZmlyc3QgbGluZSBzdXBwb3J0IHZpYSBlbWFpbCI7DQogICAgZGVzY3JpcHRpb24NCiAgICAiVGVzdCB0b3BvbG9neSBtb2RlbC4iOw0KDQogICAgcmV2aXNpb24gIjIwMjQtMDUtMjQiIHsNCiAgICAgICAgZGVzY3JpcHRpb24gIkluaXRpYWwgcmV2aXNpb24uIjsNCiAgICAgICAgb3ItdGVpdi15ZXh0OmxhYmVsIDAuMy4wOw0KICAgIH0NCg0KICAgIG9yLXRlaXYteWV4dDpkb21haW4gVEVTVDsNCg0KICAgIGxpc3QgRW50aXR5VHlwZUEgew0KDQogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7DQogICAgICAgIGtleSBpZDsNCg0KICAgIH0NCg0KICAgIGxpc3QgRW50aXR5VHlwZUFXaXRoRW50aXR5VHlwZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnMgew0KDQogICAgICAgIHVzZXMgb3ItdGVpdi10eXBlczpUb3BfR3JwX1R5cGU7DQogICAgICAgIGtleSBpZDsNCg0KICAgICAgICBjb250YWluZXIgYXR0cmlidXRlcyB7DQogICAgICAgICAgICBsZWFmIGF0dHJpYnV0ZUExV2l0aEF0dHJpYnV0ZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnMgew0KICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBsZWFmIGF0dHJpYnV0ZUEyV2l0aEF0dHJpYnV0ZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnMgew0KICAgICAgICAgICAgICAgIHR5cGUgdWludDMyOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBsZWFmIGF0dHJpYnV0ZUEzV2l0aEF0dHJpYnV0ZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnMgew0KICAgICAgICAgICAgICAgIHR5cGUgaW50MzI7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGxlYWYgYXR0cmlidXRlQTRXaXRoQXR0cmlidXRlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVycyB7DQogICAgICAgICAgICAgICAgdHlwZSBpbnQ2NDsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgbGVhZiBhdHRyaWJ1dGVBNVdpdGhBdHRyaWJ1dGVOYW1lTGVuZ3RoTG9uZ2VyVGhhblNpeHR5VGhyZWVDaGFyYWN0ZXJzIHsNCiAgICAgICAgICAgICAgICB0eXBlIGRlY2ltYWw2NHsNCiAgICAgICAgICAgICAgICAgICAgZnJhY3Rpb24tZGlnaXRzIDY7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHVuaXRzICJkZWdyZWVzIjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgbGVhZi1saXN0IGF0dHJpYnV0ZUE2V2l0aEF0dHJpYnV0ZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnMgew0KICAgICAgICAgICAgICAgIHR5cGUgc3RyaW5nOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBjb250YWluZXIgYXR0cmlidXRlQTdXaXRoQXR0cmlidXRlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVycyB7DQogICAgICAgICAgICAgICAgdXNlcyB0eXBlczNncHA6UExNTklkOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBFTlRJVFlUWVBFQV9VU0VTX0VOVElUWVRZUEVBV0lUSEVOVElUWVRZUEVOQU1FTEVOR1RITE9OR0VSVEhBTlNJWFRZVEhSRUVDSEFSQUNURVJTIHsgLy8gMC4uMSB0byAwLi4xDQoNCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsNCiAgICAgICAga2V5IGlkOw0KDQogICAgICAgIGxlYWYgdXNlZC1lbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVycyB7DQogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRW50aXR5VHlwZUE7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgfQ0KDQogICAgICAgIGxlYWYgdXNlZC1ieS1lbnRpdHlUeXBlQSB7DQogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgRW50aXR5VHlwZUFXaXRoRW50aXR5VHlwZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnM7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgfQ0KICAgIH0NCg0KICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5USVRZVFlQRUFfUFJPVklERVNfRU5USVRZVFlQRUFXSVRIRU5USVRZVFlQRU5BTUVMRU5HVEhMT05HRVJUSEFOU0lYVFlUSFJFRUNIQVJBQ1RFUlMgeyAvLyAwLi4xIHRvIDAuLm4NCg0KICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IHByb3ZpZGVkLWVudGl0eVR5cGVBV2l0aEVudGl0eVR5cGVOYW1lTGVuZ3RoTG9uZ2VyVGhhblNpeHR5VGhyZWVDaGFyYWN0ZXJzIHsNCiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBFbnRpdHlUeXBlQTsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICB9DQoNCiAgICAgICAgbGVhZiBwcm92aWRlZC1ieS1lbnRpdHlUeXBlQSB7DQogICAgICAgICAgICBvci10ZWl2LXlleHQ6YlNpZGUgRW50aXR5VHlwZUFXaXRoRW50aXR5VHlwZU5hbWVMZW5ndGhMb25nZXJUaGFuU2l4dHlUaHJlZUNoYXJhY3RlcnM7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgfQ0KICAgIH0NCg0KICAgIG9yLXRlaXYteWV4dDpiaURpcmVjdGlvbmFsVG9wb2xvZ3lSZWxhdGlvbnNoaXAgRU5USVRZVFlQRUFfR1JPVVBTX0VOVElUWVRZUEVBV0lUSEVOVElUWVRZUEVOQU1FTEVOR1RITE9OR0VSVEhBTlNJWFRZVEhSRUVDSEFSQUNURVJTIHsgLy8gMC4ubiB0byAwLi4xDQoNCiAgICAgICAgdXNlcyBvci10ZWl2LXR5cGVzOlRvcF9HcnBfVHlwZTsNCiAgICAgICAga2V5IGlkOw0KDQogICAgICAgIGxlYWYgZ3JvdXBlZC1lbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVycyB7DQogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRW50aXR5VHlwZUE7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgfQ0KDQogICAgICAgIGxlYWYtbGlzdCBncm91cGVkLWJ5LWVudGl0eVR5cGVBIHsNCiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBFbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVyczsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICB9DQogICAgfQ0KDQogICAgb3ItdGVpdi15ZXh0OmJpRGlyZWN0aW9uYWxUb3BvbG9neVJlbGF0aW9uc2hpcCBFTlRJVFlUWVBFQV9JTlNUQUxMRURfQVRfRU5USVRZVFlQRUFXSVRIRU5USVRZVFlQRU5BTUVMRU5HVEhMT05HRVJUSEFOU0lYVFlUSFJFRUNIQVJBQ1RFUlMgeyAvLyAwLi5uIHRvIDAuLm0NCg0KICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZi1saXN0IGluc3RhbGxlZC1hdC1lbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVycyB7DQogICAgICAgICAgICBvci10ZWl2LXlleHQ6YVNpZGUgRW50aXR5VHlwZUE7DQogICAgICAgICAgICB0eXBlIGluc3RhbmNlLWlkZW50aWZpZXI7DQogICAgICAgfQ0KDQogICAgICAgIGxlYWYtbGlzdCBpbnN0YWxsZWQtZW50aXR5VHlwZUEgew0KICAgICAgICAgICAgb3ItdGVpdi15ZXh0OmJTaWRlIEVudGl0eVR5cGVBV2l0aEVudGl0eVR5cGVOYW1lTGVuZ3RoTG9uZ2VyVGhhblNpeHR5VGhyZWVDaGFyYWN0ZXJzOw0KICAgICAgICAgICAgdHlwZSBpbnN0YW5jZS1pZGVudGlmaWVyOw0KICAgICAgIH0NCiAgICB9DQoNCiAgICBvci10ZWl2LXlleHQ6YmlEaXJlY3Rpb25hbFRvcG9sb2d5UmVsYXRpb25zaGlwIEVOVElUWVRZUEVBV0lUSEVOVElUWVRZUEVOQU1FTEVOR1RITE9OR0VSVEhBTlNJWFRZVEhSRUVDSEFSQUNURVJTX1VTRVNfRU5USVRZVFlQRUFXSVRIRU5USVRZVFlQRU5BTUVMRU5HVEhMT05HRVJUSEFOU0lYVFlUSFJFRUNIQVJBQ1RFUlMgeyAvLyAwLi4xIHRvIDAuLjENCg0KICAgICAgICB1c2VzIG9yLXRlaXYtdHlwZXM6VG9wX0dycF9UeXBlOw0KICAgICAgICBrZXkgaWQ7DQoNCiAgICAgICAgbGVhZiB1c2VkLWVudGl0eVR5cGVBV2l0aEVudGl0eVR5cGVOYW1lTGVuZ3RoTG9uZ2VyVGhhblNpeHR5VGhyZWVDaGFyYWN0ZXJzIHsNCiAgICAgICAgICAgIG9yLXRlaXYteWV4dDphU2lkZSBFbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVyczsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICB9DQoNCiAgICAgICAgbGVhZiB1c2VkLWJ5LWVudGl0eVR5cGVBV2l0aEVudGl0eVR5cGVOYW1lTGVuZ3RoTG9uZ2VyVGhhblNpeHR5VGhyZWVDaGFyYWN0ZXJzIHsNCiAgICAgICAgICAgIG9yLXRlaXYteWV4dDpiU2lkZSBFbnRpdHlUeXBlQVdpdGhFbnRpdHlUeXBlTmFtZUxlbmd0aExvbmdlclRoYW5TaXh0eVRocmVlQ2hhcmFjdGVyczsNCiAgICAgICAgICAgIHR5cGUgaW5zdGFuY2UtaWRlbnRpZmllcjsNCiAgICAgICB9DQogICAgfQ0KfQ==
+\.
+
+COPY ties_model.entity_info("storedAt", "name", "moduleReferenceName") FROM stdin;
+test-built-in-module_EntityTypeA       EntityTypeA     test-built-in-module
+test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module
+\.
+
+COPY ties_model.relationship_info("name", "aSideAssociationName", "aSideMOType", "aSideModule", "aSideMinCardinality", "aSideMaxCardinality", "bSideAssociationName", "bSideMOType", "bSideModule", "bSideMinCardinality", "bSideMaxCardinality", "associationKind", "connectSameEntity", "relationshipDataLocation", "storedAt", "moduleReferenceName") FROM stdin;
+ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS       used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters  EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       1       used-by-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       1       BI_DIRECTIONAL  true    RELATION        test-built-in-module_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS   test-built-in-module
+ENTITYTYPEA_GROUPS_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS   grouped-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       EntityTypeA     test-built-in-module    0       9223372036854775807     grouped-by-entityTypeA  EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       1       BI_DIRECTIONAL  false   A_SIDE  test-built-in-module_EntityTypeA        test-built-in-module
+ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS     installed-at-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters  EntityTypeA     test-built-in-module    0       9223372036854775807     installed-entityTypeA   EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       9223372036854775807     BI_DIRECTIONAL  false   RELATION        test-built-in-module_ENTITYTYPEA_INSTALLED_AT_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS test-built-in-module
+ENTITYTYPEA_PROVIDES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS provided-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters      EntityTypeA     test-built-in-module    0       1       provided-by-entityTypeA EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       9223372036854775807     BI_DIRECTIONAL  false   B_SIDE  test-built-in-module_EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters  test-built-in-module
+ENTITYTYPEA_USES_ENTITYTYPEAWITHENTITYTYPENAMELENGTHLONGERTHANSIXTYTHREECHARACTERS     used-entityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters  EntityTypeA     test-built-in-module    0       1       used-by-entityTypeA     EntityTypeAWithEntityTypeNameLengthLongerThanSixtyThreeCharacters       test-built-in-module    0       1       BI_DIRECTIONAL  false   A_SIDE  test-built-in-module_EntityTypeA        test-built-in-module
+\.
+
+COMMIT;
\ No newline at end of file