Springboot Integration tests improvements
Creation of CpsIntegrationSpecBase
Demonstration of test class implementing CpsIntegrationSpecBase in CpsPersistenceSpec
Tests use reduced liquibase steps, basic bookstore yang model and bookstore json payload
Issue-ID: CPS-1379
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: I38202d0888808d08d85fce1aab45fc43e8b0cec3
diff --git a/integration-test/pom.xml b/integration-test/pom.xml
new file mode 100644
index 0000000..d6f55dd
--- /dev/null
+++ b/integration-test/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (c) 2023 Nordix Foundation
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.onap.cps</groupId>
+ <artifactId>cps-parent</artifactId>
+ <version>3.2.1-SNAPSHOT</version>
+ <relativePath>../cps-parent/pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>integration-test</artifactId>
+
+<dependencies>
+ <dependency>
+ <groupId>org.onap.cps</groupId>
+ <artifactId>cps-ri</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.cps</groupId>
+ <artifactId>cps-service</artifactId>
+ </dependency>
+ <!-- T E S T D E P E N D E N C I E S -->
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.spockframework</groupId>
+ <artifactId>spock-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.spockframework</groupId>
+ <artifactId>spock-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>postgresql</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>spock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.kafka</groupId>
+ <artifactId>spring-kafka-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+</dependencies>
+</project>
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy
new file mode 100644
index 0000000..9604832
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/CpsIntegrationSpecBase.groovy
@@ -0,0 +1,112 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration
+
+import org.onap.cps.api.impl.CpsAdminServiceImpl
+import org.onap.cps.api.impl.CpsDataServiceImpl
+import org.onap.cps.api.impl.CpsModuleServiceImpl
+import org.onap.cps.spi.CascadeDeleteAllowed
+import org.onap.cps.spi.repository.DataspaceRepository
+import org.onap.cps.spi.impl.utils.CpsValidatorImpl
+import org.onap.cps.utils.ContentType
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.boot.autoconfigure.domain.EntityScan
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.context.annotation.Lazy
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories
+import org.testcontainers.spock.Testcontainers
+import spock.lang.Shared
+import spock.lang.Specification
+
+import java.time.OffsetDateTime
+
+@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl])
+@Testcontainers
+@EnableAutoConfiguration
+@EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
+@ComponentScan(basePackages = ["org.onap.cps.api", "org.onap.cps.spi.repository"])
+@EntityScan("org.onap.cps.spi.entities")
+class CpsIntegrationSpecBase extends Specification {
+
+ @Shared
+ DatabaseTestContainer databaseTestContainer = DatabaseTestContainer.getInstance()
+
+ @Autowired
+ @Lazy
+ CpsAdminServiceImpl cpsAdminService
+
+ @Autowired
+ @Lazy
+ CpsDataServiceImpl cpsDataService
+
+ @Autowired
+ @Lazy
+ CpsModuleServiceImpl cpsModuleService
+
+
+ def static TEST_DATASPACE = 'testDataspace'
+ def static BOOKSTORE_SCHEMA_SET = 'bookstoreSchemaSet'
+ def static TEST_ANCHOR = 'testAnchor'
+
+ def createDataspaceSchemaSetAnchor(String dataspaceName, String schemaSetName, String schemaSetFileName, String anchorName) {
+ cpsAdminService.createDataspace(dataspaceName)
+ createSchemaSetAnchor(dataspaceName, schemaSetName, schemaSetFileName, anchorName)
+ }
+
+ def createSchemaSetAnchor(String dataspaceName, String schemaSetName, String schemaSetFileName, String anchorName) {
+ def bookstoreFileContent = readResourceFile(schemaSetFileName)
+ cpsModuleService.createSchemaSet(dataspaceName, schemaSetName, [(schemaSetFileName) : bookstoreFileContent])
+ cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName)
+ }
+
+ def saveDataNodes(String dataspaceName, String anchorName, String parentNodeXpath, String dataNodesFileName) {
+ def dataNodesAsJSON = readResourceFile(dataNodesFileName)
+ if (isRootXpath(parentNodeXpath)) {
+ cpsDataService.saveData(dataspaceName, anchorName, dataNodesAsJSON,
+ OffsetDateTime.now(), ContentType.JSON);
+ } else {
+ cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath,
+ dataNodesAsJSON, OffsetDateTime.now(), ContentType.JSON);
+ }
+ }
+
+ def deleteAllFromTestDataspace() {
+ def anchors = cpsAdminService.getAnchors(TEST_DATASPACE)
+ for(anchor in anchors) {
+ cpsDataService.deleteDataNodes(TEST_DATASPACE, anchor.getName(), OffsetDateTime.now())
+ cpsAdminService.deleteAnchor(TEST_DATASPACE, anchor.getName())
+ }
+ def schemaSets = cpsModuleService.getSchemaSets(TEST_DATASPACE)
+ for(schemaSet in schemaSets) {
+ cpsModuleService.deleteSchemaSet(TEST_DATASPACE, schemaSet.getName(), CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED)
+ }
+ }
+
+ def static readResourceFile(String filename) {
+ return new File('src/test/resources/data/' + filename).text
+ }
+
+ def static isRootXpath(final String xpath) {
+ return "/".equals(xpath);
+ }
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy
new file mode 100644
index 0000000..94bcb0a
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/CpsPersistenceSpec.groovy
@@ -0,0 +1,61 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration
+
+import org.onap.cps.spi.FetchDescendantsOption
+
+class CpsPersistenceSpec extends CpsIntegrationSpecBase{
+
+ def 'Test creation of test data'() {
+ when: 'A dataspace, schema set and anchor are persisted'
+ createDataspaceSchemaSetAnchor(TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'bookstore.yang', TEST_ANCHOR)
+ and: 'data nodes are persisted under the created anchor'
+ saveDataNodes(TEST_DATASPACE, TEST_ANCHOR, '/', 'BookstoreDataNodes.json')
+ then: 'The dataspace has been persisted successfully'
+ cpsAdminService.getDataspace(TEST_DATASPACE).getName() == TEST_DATASPACE
+ and: 'The schema set has been persisted successfully'
+ cpsModuleService.getSchemaSet(TEST_DATASPACE, BOOKSTORE_SCHEMA_SET).getName() == BOOKSTORE_SCHEMA_SET
+ and: 'The anchor has been persisted successfully'
+ cpsAdminService.getAnchor(TEST_DATASPACE, TEST_ANCHOR).getName() == TEST_ANCHOR
+ and: 'The data nodes have been persisted successfully'
+ cpsDataService.getDataNode(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).xpath == '/bookstore'
+ }
+
+ def 'Test deletion of all test data'() {
+ when: 'delete all from test dataspace method is called'
+ deleteAllFromTestDataspace()
+ and: 'the test dataspace is deleted'
+ cpsAdminService.deleteDataspace(TEST_DATASPACE)
+ then: 'there is no test dataspace'
+ !cpsAdminService.getAllDataspaces().contains(TEST_DATASPACE)
+ }
+
+ def 'Read test for persisted data nodes'() {
+ given:'There is a test dataspace created'
+ cpsAdminService.createDataspace(TEST_DATASPACE)
+ and: 'There is a schema set and anchor for the test dataspace'
+ createSchemaSetAnchor(TEST_DATASPACE, 'bookstoreSchemaSet', 'bookstore.yang', TEST_ANCHOR)
+ when: 'data is persisted to the database'
+ saveDataNodes(TEST_DATASPACE, TEST_ANCHOR, "/", "BookstoreDataNodes.json")
+ then: 'the correct data is saved'
+ cpsDataService.getDataNode(TEST_DATASPACE, TEST_ANCHOR, '/bookstore', FetchDescendantsOption.OMIT_DESCENDANTS).leaves['bookstore-name'] == 'Easons'
+ }
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy
new file mode 100644
index 0000000..273d7bb
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/TestConfig.groovy
@@ -0,0 +1,111 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.notification.NotificationService
+import org.onap.cps.spi.CpsDataPersistenceService
+import org.onap.cps.spi.CpsModulePersistenceService
+import org.onap.cps.spi.impl.CpsAdminPersistenceServiceImpl
+import org.onap.cps.spi.impl.CpsDataPersistenceServiceImpl
+import org.onap.cps.spi.impl.CpsModulePersistenceServiceImpl
+import org.onap.cps.spi.repository.AnchorRepository
+import org.onap.cps.spi.repository.DataspaceRepository
+import org.onap.cps.spi.repository.FragmentRepository
+import org.onap.cps.spi.repository.ModuleReferenceRepository
+import org.onap.cps.spi.repository.SchemaSetRepository
+import org.onap.cps.spi.repository.YangResourceRepository
+import org.onap.cps.spi.utils.SessionManager
+import org.onap.cps.utils.JsonObjectMapper
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.context.annotation.Lazy
+import spock.lang.Specification
+
+@Configuration
+class TestConfig extends Specification{
+ @Autowired
+ @Lazy
+ DataspaceRepository dataspaceRepository
+
+ @Autowired
+ @Lazy
+ AnchorRepository anchorRepository
+
+ @Autowired
+ @Lazy
+ SchemaSetRepository schemaSetRepository
+
+ @Autowired
+ @Lazy
+ YangResourceRepository yangResourceRepository
+
+ @Autowired
+ @Lazy
+ FragmentRepository fragmentRepository
+
+ @Autowired
+ @Lazy
+ ModuleReferenceRepository moduleReferenceRepository
+
+ @Autowired
+ @Lazy
+ JsonObjectMapper jsonObjectMapper
+
+ @Autowired
+ @Lazy
+ NotificationService stubbedNotificationService
+
+ @Autowired
+ @Lazy
+ SessionManager stubbedSessionManager
+
+ @Bean
+ CpsAdminPersistenceServiceImpl cpsAdminPersistenceService() {
+ new CpsAdminPersistenceServiceImpl(dataspaceRepository, anchorRepository, schemaSetRepository, yangResourceRepository)
+ }
+
+ @Bean
+ CpsDataPersistenceService cpsDataPersistenceService() {
+ return (CpsDataPersistenceService) new CpsDataPersistenceServiceImpl(dataspaceRepository, anchorRepository, fragmentRepository, jsonObjectMapper, stubbedSessionManager)
+ }
+
+ @Bean
+ CpsModulePersistenceService cpsModulePersistenceService() {
+ return (CpsModulePersistenceService) new CpsModulePersistenceServiceImpl(yangResourceRepository, schemaSetRepository, dataspaceRepository, cpsAdminPersistenceService(), moduleReferenceRepository)
+ }
+
+ @Bean
+ JsonObjectMapper jsonObjectMapper() {
+ return new JsonObjectMapper(new ObjectMapper())
+ }
+
+ @Bean
+ NotificationService notificationService() {
+ return Stub(NotificationService)
+ }
+
+ @Bean
+ SessionManager sessionManager() {
+ return Stub(SessionManager)
+ }
+}
\ No newline at end of file
diff --git a/integration-test/src/test/java/org/onap/cps/integration/DatabaseTestContainer.java b/integration-test/src/test/java/org/onap/cps/integration/DatabaseTestContainer.java
new file mode 100644
index 0000000..acf94b7
--- /dev/null
+++ b/integration-test/src/test/java/org/onap/cps/integration/DatabaseTestContainer.java
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration;
+
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ * The Postgresql database test container wrapper.
+ * Singleton implementation allows saving time on database initialization which otherwise would occur on each test.
+ * for debugging/developing purposes you can suspend any test and connect to this database:
+ * docker exec -it {container-id} sh
+ * psql -d test -U test
+ */
+public class DatabaseTestContainer extends PostgreSQLContainer<DatabaseTestContainer> {
+ private static final String IMAGE_VERSION = "registry.nordix.org/onaptest/postgres:14.1";
+ private static DatabaseTestContainer databaseTestContainer;
+
+ private DatabaseTestContainer() {
+ super(DockerImageName.parse(IMAGE_VERSION).asCompatibleSubstituteFor("postgres"));
+ }
+
+ /**
+ * Provides an instance of test container wrapper.
+ * The returned value expected to be assigned to static variable annotated with @ClassRule.
+ * This will allow to initialize DB connection env variables before DataSource object
+ * is initialized by Spring framework.
+ *
+ */
+ public static DatabaseTestContainer getInstance() {
+ if (databaseTestContainer == null) {
+ databaseTestContainer = new DatabaseTestContainer();
+ Runtime.getRuntime().addShutdownHook(new Thread(databaseTestContainer::terminate));
+ }
+ return databaseTestContainer;
+ }
+
+ @Override
+ public void start() {
+ super.start();
+ System.setProperty("DB_URL", databaseTestContainer.getJdbcUrl());
+ System.setProperty("DB_USERNAME", databaseTestContainer.getUsername());
+ System.setProperty("DB_PASSWORD", databaseTestContainer.getPassword());
+ }
+
+ @Override
+ public void stop() {
+ // do nothing on test completion, image removal will be performed via terminate() on JVM shutdown
+ }
+
+ private void terminate() {
+ super.stop();
+ }
+}
diff --git a/integration-test/src/test/resources/application.yml b/integration-test/src/test/resources/application.yml
new file mode 100644
index 0000000..0aefac8
--- /dev/null
+++ b/integration-test/src/test/resources/application.yml
@@ -0,0 +1,37 @@
+# ============LICENSE_START=======================================================
+# Copyright (C) 2023 Nordix Foundation.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+spring:
+ jpa:
+ ddl-auto: create
+ show-sql: false
+ properties:
+ hibernate:
+ enable_lazy_load_no_trans: true
+ dialect: org.hibernate.dialect.PostgreSQLDialect
+ format_sql: true
+ show_sql: false
+
+ datasource:
+ url: ${DB_URL}
+ username: ${DB_USERNAME}
+ password: ${DB_PASSWORD}
+ driverClassName: org.postgresql.Driver
+ initialization-mode: always
+
+ liquibase:
+ change-log: classpath:liquibase/test-changelog.yaml
diff --git a/integration-test/src/test/resources/data/BookstoreDataNodes.json b/integration-test/src/test/resources/data/BookstoreDataNodes.json
new file mode 100644
index 0000000..1c6cb88
--- /dev/null
+++ b/integration-test/src/test/resources/data/BookstoreDataNodes.json
@@ -0,0 +1,54 @@
+{
+ "bookstore": {
+ "bookstore-name": "Easons",
+ "categories": [
+ {
+ "code": 1,
+ "name": "Children",
+ "books" : [
+ {
+ "title": "Matilda",
+ "lang": "English",
+ "authors": ["Roald Dahl"],
+ "pub_year": 1988,
+ "price": 10
+ },
+ {
+ "title": "The Gruffalo",
+ "lang": "English",
+ "authors": ["Julia Donaldson"],
+ "pub_year": 1999,
+ "price": 15
+ }
+ ]
+ },
+ {
+ "code": 2,
+ "name": "Thriller",
+ "books" : [
+ {
+ "title": "Annihilation",
+ "lang": "English",
+ "authors": ["Jeff VanderMeer"],
+ "pub_year": 2014,
+ "price": 15
+ }
+ ]
+ },
+ {
+ "code": 3,
+ "name": "Comedy",
+ "books" : [
+ {
+ "title": "Good Omens",
+ "lang": "English",
+ "authors": ["Neil Gaiman", "Terry Pratchett"],
+ "pub_year": 2006,
+ "price": 13
+ }
+ ]
+ }
+
+ ]
+ }
+}
\ No newline at end of file
diff --git a/integration-test/src/test/resources/data/bookstore.yang b/integration-test/src/test/resources/data/bookstore.yang
new file mode 100644
index 0000000..2179fb9
--- /dev/null
+++ b/integration-test/src/test/resources/data/bookstore.yang
@@ -0,0 +1,57 @@
+module stores {
+ yang-version 1.1;
+ namespace "org:onap:ccsdk:sample";
+
+ prefix book-store;
+
+ revision "2020-09-15" {
+ description
+ "Sample Model";
+ }
+
+ typedef year {
+ type uint16 {
+ range "1000..9999";
+ }
+ }
+
+ container bookstore {
+
+ leaf bookstore-name {
+ type string;
+ }
+
+ list categories {
+
+ key "code";
+
+ leaf code {
+ type string;
+ }
+
+ leaf name {
+ type string;
+ }
+
+ list books {
+ key title;
+
+ leaf title {
+ type string;
+ }
+ leaf lang {
+ type string;
+ }
+ leaf-list authors {
+ type string;
+ }
+ leaf pub_year {
+ type year;
+ }
+ leaf price {
+ type uint64;
+ }
+ }
+ }
+ }
+}
diff --git a/integration-test/src/test/resources/hibernate.cfg.xml b/integration-test/src/test/resources/hibernate.cfg.xml
new file mode 100644
index 0000000..513c00a
--- /dev/null
+++ b/integration-test/src/test/resources/hibernate.cfg.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+ <session-factory>
+ <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
+ <property name="hibernate.connection.url">${DB_URL}</property>
+ <property name="hibernate.connection.username">${DB_USERNAME}</property>
+ <property name="hibernate.connection.password">${DB_PASSWORD}</property>
+ <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>
+ <property name="show_sql">true</property>
+ <property name="hibernate.hbm2ddl.auto">none</property>
+ </session-factory>
+</hibernate-configuration>
\ No newline at end of file
diff --git a/integration-test/src/test/resources/liquibase/test-changelog.yaml b/integration-test/src/test/resources/liquibase/test-changelog.yaml
new file mode 100644
index 0000000..0c881b8
--- /dev/null
+++ b/integration-test/src/test/resources/liquibase/test-changelog.yaml
@@ -0,0 +1,615 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2023 Nordix Foundation.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+
+databaseChangeLog:
+ - changeSet:
+ id: 1-1
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: anchor_pkey
+ name: id
+ type: BIGINT
+ - column:
+ name: name
+ type: TEXT
+ - column:
+ name: schema_set_id
+ type: INTEGER
+ - column:
+ constraints:
+ nullable: false
+ name: dataspace_id
+ type: INTEGER
+ tableName: anchor
+ - changeSet:
+ id: 1-2
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: from_fragment_id
+ type: BIGINT
+ - column:
+ constraints:
+ nullable: false
+ name: to_fragment_id
+ type: BIGINT
+ - column:
+ constraints:
+ nullable: false
+ name: relation_type_id
+ type: INTEGER
+ - column:
+ constraints:
+ nullable: false
+ name: from_rel_xpath
+ type: TEXT
+ - column:
+ constraints:
+ nullable: false
+ name: to_rel_xpath
+ type: TEXT
+ tableName: relation
+ - changeSet:
+ id: 1-3
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: relation_type
+ type: TEXT
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: relation_type_pkey
+ name: id
+ type: INTEGER
+ tableName: relation_type
+ - changeSet:
+ id: 1-4
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: fragment_pkey
+ name: id
+ type: BIGINT
+ - column:
+ constraints:
+ nullable: false
+ name: xpath
+ type: TEXT
+ - column:
+ name: attributes
+ type: JSONB
+ - column:
+ name: anchor_id
+ type: BIGINT
+ - column:
+ name: parent_id
+ type: BIGINT
+ - column:
+ constraints:
+ nullable: false
+ name: dataspace_id
+ type: INTEGER
+ - column:
+ name: schema_node_id
+ type: INTEGER
+ tableName: fragment
+ - changeSet:
+ id: 1-5
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: schema_set_pkey
+ name: id
+ type: INTEGER
+ - column:
+ constraints:
+ nullable: false
+ name: name
+ type: TEXT
+ - column:
+ constraints:
+ nullable: false
+ name: dataspace_id
+ type: BIGINT
+ tableName: schema_set
+ - changeSet:
+ id: 1-6
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: yang_resource_pkey
+ name: id
+ type: INTEGER
+ - column:
+ constraints:
+ nullable: false
+ name: name
+ type: TEXT
+ - column:
+ constraints:
+ nullable: false
+ name: content
+ type: TEXT
+ - column:
+ constraints:
+ nullable: false
+ name: checksum
+ type: TEXT
+ tableName: yang_resource
+ - changeSet:
+ id: 1-7
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: dataspace_pkey
+ name: id
+ type: INTEGER
+ - column:
+ constraints:
+ nullable: false
+ name: name
+ type: TEXT
+ tableName: dataspace
+ - changeSet:
+ id: 1-8
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: schema_node_identifier
+ type: TEXT
+ - column:
+ autoIncrement: true
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: schema_node_pkey
+ name: id
+ type: INTEGER
+ tableName: schema_node
+ - changeSet:
+ id: 1-9
+ author: cps
+ changes:
+ - createTable:
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: schema_set_id
+ type: BIGINT
+ - column:
+ constraints:
+ nullable: false
+ name: yang_resource_id
+ type: BIGINT
+ tableName: schema_set_yang_resources
+ - changeSet:
+ id: 1-10
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: schema_set_id
+ indexName: FKI_ANCHOR_SCHEMA_SET_ID_FK
+ tableName: anchor
+ - changeSet:
+ id: 1-11
+ author: cps
+ changes:
+ - addUniqueConstraint:
+ columnNames: dataspace_id, name
+ constraintName: anchor_dataspace_id_name_key
+ tableName: anchor
+ - changeSet:
+ id: 1-12
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: anchor_id
+ baseTableName: fragment
+ constraintName: fragment_anchor_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: anchor
+ validate: true
+ - changeSet:
+ id: 1-13
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: from_fragment_id
+ indexName: FKI_RELATIONS_FROM_ID_FK
+ tableName: relation
+ - changeSet:
+ id: 1-14
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: to_fragment_id
+ indexName: FKI_RELATIONS_TO_ID_FK
+ tableName: relation
+ - changeSet:
+ id: 1-15
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: relation_type_id
+ indexName: FKI_RELATION_TYPE_ID_FK
+ tableName: relation
+ - changeSet:
+ id: 1-16
+ author: cps
+ changes:
+ - addPrimaryKey:
+ columnNames: to_fragment_id, from_fragment_id, relation_type_id
+ constraintName: relation_pkey
+ tableName: relation
+ - changeSet:
+ id: 1-17
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: anchor_id
+ indexName: FKI_FRAGMENT_ANCHOR_ID_FK
+ tableName: fragment
+ - changeSet:
+ id: 1-18
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: dataspace_id
+ indexName: FKI_FRAGMENT_DATASPACE_ID_FK
+ tableName: fragment
+ - changeSet:
+ id: 1-19
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: parent_id
+ indexName: FKI_FRAGMENT_PARENT_ID_FK
+ tableName: fragment
+ - changeSet:
+ id: 1-20
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: schema_node_id
+ indexName: FKI_SCHEMA_NODE_ID_TO_ID
+ tableName: fragment
+ - changeSet:
+ id: 1-21
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: xpath
+ - column:
+ name: dataspace_id
+ indexName: UQ_FRAGMENT_XPATH
+ tableName: fragment
+ unique: true
+ - changeSet:
+ id: 1-22
+ author: cps
+ changes:
+ - addUniqueConstraint:
+ columnNames: dataspace_id, anchor_id, xpath
+ constraintName: fragment_dataspace_id_anchor_id_xpath_key
+ tableName: fragment
+ - changeSet:
+ id: 1-23
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: from_fragment_id
+ baseTableName: relation
+ constraintName: relation_from_fragment_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: fragment
+ validate: true
+ - changeSet:
+ id: 1-24
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: to_fragment_id
+ baseTableName: relation
+ constraintName: relation_to_fragment_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: fragment
+ validate: true
+ - changeSet:
+ id: 1-25
+ author: cps
+ changes:
+ - addUniqueConstraint:
+ columnNames: name, dataspace_id
+ constraintName: schema_set_name_dataspace_id_key
+ tableName: schema_set
+ - changeSet:
+ id: 1-26
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: schema_set_id
+ baseTableName: schema_set_yang_resources
+ constraintName: schema_set_resource
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: CASCADE
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: schema_set
+ validate: true
+ - changeSet:
+ id: 1-27
+ author: cps
+ changes:
+ - addUniqueConstraint:
+ columnNames: checksum
+ constraintName: yang_resource_checksum_key
+ tableName: yang_resource
+ - changeSet:
+ id: 1-28
+ author: cps
+ changes:
+ - addUniqueConstraint:
+ columnNames: name
+ constraintName: UQ_NAME
+ tableName: dataspace
+ - changeSet:
+ id: 1-29
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: dataspace_id
+ baseTableName: fragment
+ constraintName: fragment_dataspace_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: dataspace
+ validate: true
+ - changeSet:
+ id: 1-30
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: dataspace_id
+ baseTableName: schema_set
+ constraintName: schema_set_dataspace
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: CASCADE
+ onUpdate: CASCADE
+ referencedColumnNames: id
+ referencedTableName: dataspace
+ validate: true
+ - changeSet:
+ id: 1-31
+ author: cps
+ changes:
+ - createIndex:
+ columns:
+ - column:
+ name: schema_node_identifier
+ indexName: PERF_SCHEMA_NODE_SCHEMA_NODE_ID
+ tableName: schema_node
+ - changeSet:
+ id: 1-32
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: yang_resource_id
+ baseTableName: schema_set_yang_resources
+ constraintName: schema_set_yang_resources_yang_resource_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: yang_resource
+ validate: true
+ - changeSet:
+ id: 1-33
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: dataspace_id
+ baseTableName: anchor
+ constraintName: anchor_dataspace_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: dataspace
+ validate: true
+ - changeSet:
+ id: 1-34
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: schema_set_id
+ baseTableName: anchor
+ constraintName: anchor_schema_set_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: schema_set
+ validate: true
+ - changeSet:
+ id: 1-35
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: relation_type_id
+ baseTableName: relation
+ constraintName: relation_relation_type_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: relation_type
+ validate: true
+ - changeSet:
+ id: 1-36
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: parent_id
+ baseTableName: fragment
+ constraintName: fragment_parent_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: fragment
+ validate: true
+ - changeSet:
+ id: 1-37
+ author: cps
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: schema_node_id
+ baseTableName: fragment
+ constraintName: fragment_schema_node_id_fkey
+ deferrable: false
+ initiallyDeferred: false
+ onDelete: NO ACTION
+ onUpdate: NO ACTION
+ referencedColumnNames: id
+ referencedTableName: schema_node
+ validate: true
+
+
+ - changeSet:
+ id: 1-38
+ label: add-module-name-and-revision-column
+ author: cps
+ changes:
+ - addColumn:
+ tableName: yang_resource
+ columns:
+ - column:
+ name: module_name
+ type: TEXT
+ - column:
+ name: revision
+ type: TEXT
+
+ - changeSet:
+ id: 1-39
+ label: update-previous-data-module-name-and-revision
+ author: cps
+ changes:
+ - sql:
+ sql: update yang_resource set module_name = 'dummy_module_name', revision = '2021-08-04' where module_name is null and revision is null
+ rollback:
+ sql: update yang_resource set module_name = null, revision = null where module_name = 'dummy_module_name' and revision = '2021-08-04'
+
+ - changeSet:
+ author: cps
+ label: yang-resource-rename-column
+ id: 1-40
+ changes:
+ - renameColumn:
+ tableName: yang_resource
+ columnDataType: TEXT
+ oldColumnName: name
+ newColumnName: file_name
+ rollback:
+ - sql:
+ sql: alter table yang_resource rename column file_name to name