diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml index 5f35e018..b52c3e2f 100644 --- a/.idea/checkstyle-idea.xml +++ b/.idea/checkstyle-idea.xml @@ -1,7 +1,7 @@ - 10.20.1 + 10.21.0 JavaOnlyWithTests true true diff --git a/CHANGELOG.md b/CHANGELOG.md index d61a3f87..658c675f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.5.0 + +* Updated org.springframework.boot.version to v3.4.1 +* Added support for the [micro-migration-Framework](https://github.com/xdev-software/micro-migration) + # 2.4.1 * Updated EclipseStore to v2.1.0 @@ -13,7 +18,6 @@ * Auto-Fix problems with adding ids to entities with existing data store. -~~~~ # 2.3.0 * Add support for shutting down the storage during application shutdown diff --git a/README.md b/README.md index 3dd6a3b9..75a52bd9 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,8 @@ instructions** are in the documentation](https://xdev-software.github.io/spring- | ``2.0.0-2.1.0`` | ``17`` | ``3.3.2`` | ``1.4.0`` | | ``2.2.0-2.3.1`` | ``17`` | ``3.3.4`` | ``1.4.0`` | | ``2.4.0`` | ``17`` | ``3.4.0`` | ``2.0.0`` | -| ``>= 2.4.1`` | ``17`` | ``3.4.0`` | ``2.1.0`` | +| ``2.4.1`` | ``17`` | ``3.4.0`` | ``2.1.0`` | +| ``>= 2.5.0`` | ``17`` | ``3.4.1`` | ``2.1.0`` | ## Demo diff --git a/docs/antora.yml b/docs/antora.yml index 096cac35..6bfa46c8 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -1,14 +1,14 @@ name: ROOT title: Spring-Data-Eclipse-Store version: master -display_version: '2.4.1' +display_version: '2.5.0' start_page: index.adoc nav: - modules/ROOT/nav.adoc asciidoc: attributes: product-name: 'Spring-Data-Eclipse-Store' - display-version: '2.4.1' - maven-version: '2.4.1' + display-version: '2.5.0' + maven-version: '2.5.0' page-editable: false page-out-of-support: false diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index ae44098a..b339858f 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -8,6 +8,8 @@ ** xref:features/queries.adoc[Queries] ** xref:features/transactions.adoc[Transactions] ** xref:features/versions.adoc[Versions] +** xref:features/versioned-migration.adoc[Versioned Migration] ** xref:features/rest-api.adoc[REST Interface] -* xref:migration.adoc[Migration from JPA] +** xref:features/validation-constraints.adoc[Validation Constraints] +* xref:migration-from-jpa.adoc[Migration from JPA] * xref:known-issues.adoc[Known issues] diff --git a/docs/modules/ROOT/pages/features/features.adoc b/docs/modules/ROOT/pages/features/features.adoc index de38b497..a9ccae5c 100644 --- a/docs/modules/ROOT/pages/features/features.adoc +++ b/docs/modules/ROOT/pages/features/features.adoc @@ -5,4 +5,6 @@ * xref:features/queries.adoc[Queries] * xref:features/transactions.adoc[Transactions] * xref:features/versions.adoc[Versions] +* xref:features/versioned-migration.adoc[Versioned Migration] * xref:features/rest-api.adoc[REST Interface] +* xref:features/validation-constraints.adoc[Validation Constraints] diff --git a/docs/modules/ROOT/pages/features/validation-constraints.adoc b/docs/modules/ROOT/pages/features/validation-constraints.adoc new file mode 100644 index 00000000..3dabb23c --- /dev/null +++ b/docs/modules/ROOT/pages/features/validation-constraints.adoc @@ -0,0 +1,19 @@ += Validation Constraints + +By using the https://jakarta.ee/learn/docs/jakartaee-tutorial/current/beanvalidation/bean-validation/bean-validation.html[Jakarta Bean Validation Constraints] developers with {product-name} can easily limit the allowed input of entities. +Here is a full list of supported validations: https://jakarta.ee/learn/docs/jakartaee-tutorial/current/beanvalidation/bean-validation/bean-validation.html#_using_jakarta_bean_validation_constraints[https://jakarta.ee/learn] + +[source,java,title="https://github.com/xdev-software/spring-data-eclipse-store/blob/develop/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/model/Person.java[Example from complex demo]"] +---- +package software.xdev.spring.data.eclipse.store.demo.complex.model; + +import jakarta.validation.constraints.NotBlank; + +public class Person extends BaseEntity +{ + @NotBlank + private String firstName; + //... +---- + +The ``jakarta.validation.Validator`` is provided by the https://github.com/xdev-software/spring-data-eclipse-store/tree/develop/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java[``EclipseStoreClientConfiguration``] and can be changed in the project-specific configuration. diff --git a/docs/modules/ROOT/pages/features/versioned-migration.adoc b/docs/modules/ROOT/pages/features/versioned-migration.adoc new file mode 100644 index 00000000..5ce7df97 --- /dev/null +++ b/docs/modules/ROOT/pages/features/versioned-migration.adoc @@ -0,0 +1,116 @@ += Versioned Migration + +To keep the data in the store up-to-date, {product-name} utilizes https://github.com/xdev-software/micro-migration[XDEV's Micro-Migration]. +This means the user can use versioning for the stored data and only apply changes for certain versions of data. +This can be very useful specifically with build-pipelines. https://github.com/xdev-software/micro-migration#intro[More info at Micro-Migration...] + +== Implementation + +This can be easily achieved by either of these 3 methods: + +=== 1. Reflective Scripts + +Simply implement a new component with a specific pattern of naming, that extends the ``ReflectiveDataMigrationScript``. + +[source,java,title="https://github.com/xdev-software/spring-data-eclipse-store/blob/develop/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/v1_0_0_Init.java[Reflective example from complex demo]"] +---- +package software.xdev.spring.data.eclipse.store.demo.complex.migration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +//... +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + +@Component +public class v1_0_0_Init extends ReflectiveDataMigrationScript +{ + private final OwnerService service; + + @Autowired + public v1_0_0_Init(final OwnerService service) + { + this.service = service; + } + + @Override + public void migrate(final Context context) + { + this.service.createNewOwnerAndVisit("Mick", "Fleetwood", "Isabella"); + } +} +---- + +Here the version number on which the data is updated on execution is derived from the class name. + +The ``MigrationVersion`` is stored in the root object in the data store. +Therefore, the storage always knows on which version the current data is and the ``DataMigrater`` will only execute the newer scripts. + +The scripts are automatically registered by declaring them as ``@Component``s. +That means that they can be anywhere as long as they are discovered by Spring as a component. + +=== 2. Custom Scripts + +Implementing a script without special naming is possible by implementing the +``DataMigrationScript``. + +[source,java,title="https://github.com/xdev-software/spring-data-eclipse-store/blob/develop/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/CustomNameScript.java[Custom script example from complex demo]"] +---- +package software.xdev.spring.data.eclipse.store.demo.complex.migration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +//... +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataMigrationScript; + +@Component +public class CustomNameScriptAddOwner implements DataMigrationScript +{ + private final OwnerService service; + + public CustomNameScriptAddOwner(@Autowired final OwnerService service) + { + this.service = service; + } + + @Override + public MigrationVersion getTargetVersion() + { + return new MigrationVersion(1, 1, 0); + } + + @Override + public void migrate(final Context context) + { + this.service.createNewOwnerAndVisit("John", "McVie", "Ivan"); + } +} +---- + +The version number must be returned explicitly in the ``#getTargetVersion``-method. + +=== 3. Custom Migrater + +If more customization is needed it is also possible to replace the ``DataMigrater`` completely and implement your own ``MicroMigrater``. +This should only be used if necessary since it adds a lot of complexity to the code. + +[source,java,title="https://github.com/xdev-software/spring-data-eclipse-store/blob/develop/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/CustomMigrater.java[Custom migrater from tests]"] +---- +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import software.xdev.micromigration.migrater.ExplicitMigrater; +import software.xdev.micromigration.migrater.MicroMigrater; +//... + +@Component +public class CustomMigrater implements MicroMigrater +{ +private final ExplicitMigrater explicitMigrater; + + @Autowired + public CustomMigrater(final PersistedEntityRepository repository) + { + this.explicitMigrater = new ExplicitMigrater(new v1_0_0_Init(repository)); + } +---- diff --git a/docs/modules/ROOT/pages/migration.adoc b/docs/modules/ROOT/pages/migration-from-jpa.adoc similarity index 100% rename from docs/modules/ROOT/pages/migration.adoc rename to docs/modules/ROOT/pages/migration-from-jpa.adoc diff --git a/pom.xml b/pom.xml index 7763b999..9726aae0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ software.xdev spring-data-eclipse-store-root - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT pom @@ -22,7 +22,7 @@ UTF-8 - 3.4.0 + 3.4.1 2.1.0 2.1.0 2.1.0 @@ -107,7 +107,7 @@ com.puppycrawl.tools checkstyle - 10.21.0 + 10.21.1 @@ -150,12 +150,12 @@ net.sourceforge.pmd pmd-core - 7.8.0 + 7.9.0 net.sourceforge.pmd pmd-java - 7.8.0 + 7.9.0 diff --git a/spring-data-eclipse-store-benchmark/pom.xml b/spring-data-eclipse-store-benchmark/pom.xml index 8cd771bd..a8db67fa 100644 --- a/spring-data-eclipse-store-benchmark/pom.xml +++ b/spring-data-eclipse-store-benchmark/pom.xml @@ -5,11 +5,11 @@ software.xdev spring-data-eclipse-store-root - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT spring-data-eclipse-store-benchmark - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT jar 2023 diff --git a/spring-data-eclipse-store-demo/pom.xml b/spring-data-eclipse-store-demo/pom.xml index 37bd6bbc..b511c91a 100644 --- a/spring-data-eclipse-store-demo/pom.xml +++ b/spring-data-eclipse-store-demo/pom.xml @@ -7,11 +7,11 @@ software.xdev spring-data-eclipse-store-root - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT spring-data-eclipse-store-demo - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT jar diff --git a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/ComplexDemoApplication.java b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/ComplexDemoApplication.java index fdb997ed..844d4727 100644 --- a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/ComplexDemoApplication.java +++ b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/ComplexDemoApplication.java @@ -55,10 +55,7 @@ public void run(final String... args) */ private void ownerCalls() { - this.ownerService.logOwners(); - this.ownerService.deleteAll(); - this.ownerService.logOwners(); - this.ownerService.createNewOwnerAndVisit(); + this.ownerService.createNewOwnerAndVisit("Stevie", "Nicks", "Peter"); this.ownerService.logOwnersAndVisits(); } diff --git a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/OwnerService.java b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/OwnerService.java index 606619ad..cef33d8d 100644 --- a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/OwnerService.java +++ b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/OwnerService.java @@ -88,16 +88,16 @@ public void logOwnersAndVisits() /** * Transactional */ - public void createNewOwnerAndVisit() + public void createNewOwnerAndVisit(final String ownerFirstName, final String ownerLastName, final String petName) { new TransactionTemplate(this.transactionManager).execute( status -> { - final Owner owner = this.createOwner(); + final Owner owner = this.createOwner(ownerFirstName, ownerLastName, petName); this.ownerRepository.save(owner); final Visit visit = this.createVisit(); - owner.addVisit("Peter", visit); + owner.addVisit(petName, visit); this.ownerRepository.save(owner); LOG.info("----Stored new owner and visit----"); return null; @@ -113,14 +113,14 @@ private Visit createVisit() } @SuppressWarnings("checkstyle:MagicNumber") - private Owner createOwner() + private Owner createOwner(final String ownerFirstName, final String ownerLastName, final String petName) { final Owner owner = new Owner(); - owner.setFirstName("Stevie"); - owner.setLastName("Nicks"); + owner.setFirstName(ownerFirstName); + owner.setLastName(ownerLastName); final Pet pet = new Pet(); pet.setBirthDate(LocalDate.now().minusWeeks(6)); - pet.setName("Peter"); + pet.setName(petName); final PetType petType = new PetType(); petType.setName("Dog"); pet.setType(petType); diff --git a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/CustomNameScript.java b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/CustomNameScript.java new file mode 100644 index 00000000..6d95522c --- /dev/null +++ b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/CustomNameScript.java @@ -0,0 +1,57 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.demo.complex.migration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.demo.complex.OwnerService; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataMigrationScript; + + +/** + * This is automatically called by the + * {@link software.xdev.spring.data.eclipse.store.repository.root.data.version.DataMigrater} through dependency + * injection. + *

+ * In contrast to {@link v1_0_0_Init} the version of this script is defined in the method {@link #getTargetVersion()}. + */ +@Component +public class CustomNameScript implements DataMigrationScript +{ + private final OwnerService service; + + public CustomNameScript(@Autowired final OwnerService service) + { + this.service = service; + } + + @Override + public MigrationVersion getTargetVersion() + { + return new MigrationVersion(1, 1, 0); + } + + @Override + public void migrate(final Context context) + { + this.service.createNewOwnerAndVisit("John", "McVie", "Ivan"); + } +} diff --git a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/v1_0_0_Init.java b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/v1_0_0_Init.java new file mode 100644 index 00000000..2e9c3d84 --- /dev/null +++ b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/migration/v1_0_0_Init.java @@ -0,0 +1,53 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.demo.complex.migration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.demo.complex.OwnerService; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + + +/** + * This is automatically called by the + * {@link software.xdev.spring.data.eclipse.store.repository.root.data.version.DataMigrater} through dependency + * injection. + *

+ * In contrast to {@link CustomNameScript} the version of this script is defined by + * the name of the class defines the version. + */ +@SuppressWarnings("checkstyle:TypeName") +@Component +public class v1_0_0_Init extends ReflectiveDataMigrationScript +{ + private final OwnerService service; + + @Autowired + public v1_0_0_Init(final OwnerService service) + { + this.service = service; + } + + @Override + public void migrate(final Context context) + { + this.service.createNewOwnerAndVisit("Mick", "Fleetwood", "Isabella"); + } +} diff --git a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/model/Person.java b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/model/Person.java index b1eb515e..b0ede23d 100644 --- a/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/model/Person.java +++ b/spring-data-eclipse-store-demo/src/main/java/software/xdev/spring/data/eclipse/store/demo/complex/model/Person.java @@ -15,8 +15,12 @@ */ package software.xdev.spring.data.eclipse.store.demo.complex.model; +import jakarta.validation.constraints.NotBlank; + + public class Person extends BaseEntity { + @NotBlank private String firstName; private String lastName; diff --git a/spring-data-eclipse-store-jpa/pom.xml b/spring-data-eclipse-store-jpa/pom.xml index 44e55b6d..7bc0d4a6 100644 --- a/spring-data-eclipse-store-jpa/pom.xml +++ b/spring-data-eclipse-store-jpa/pom.xml @@ -7,11 +7,11 @@ software.xdev spring-data-eclipse-store-root - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT spring-data-eclipse-store-jpa - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT jar 2023 diff --git a/spring-data-eclipse-store/pom.xml b/spring-data-eclipse-store/pom.xml index 98717c69..3a03d420 100644 --- a/spring-data-eclipse-store/pom.xml +++ b/spring-data-eclipse-store/pom.xml @@ -6,7 +6,7 @@ software.xdev spring-data-eclipse-store - 2.4.2-SNAPSHOT + 2.5.0-SNAPSHOT jar spring-data-eclipse-store @@ -51,13 +51,14 @@ UTF-8 - 3.4.0 + 3.4.1 2.1.0 2.1.0 8.0.2.Final 6.0.1 6.0.0-M1 6.6.4.Final + 3.0.1 @@ -156,7 +157,7 @@ software.xdev micro-migration - 2.0.0 + ${micro-migration.version} storage-embedded @@ -442,7 +443,7 @@ com.puppycrawl.tools checkstyle - 10.21.0 + 10.21.1 @@ -484,12 +485,12 @@ net.sourceforge.pmd pmd-core - 7.8.0 + 7.9.0 net.sourceforge.pmd pmd-java - 7.8.0 + 7.9.0 diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java index c772fabb..105fb7a0 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java @@ -39,7 +39,9 @@ import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreClientConfiguration; import software.xdev.spring.data.eclipse.store.repository.config.EclipseStoreStorageFoundationProvider; import software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreRepository; +import software.xdev.spring.data.eclipse.store.repository.root.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataVersion; import software.xdev.spring.data.eclipse.store.repository.root.v2_4.EntityData; import software.xdev.spring.data.eclipse.store.repository.support.SimpleEclipseStoreRepository; import software.xdev.spring.data.eclipse.store.repository.support.concurrency.ReadWriteLock; @@ -92,7 +94,7 @@ public EclipseStoreStorage(final EclipseStoreClientConfiguration storeConfigurat this.classLoaderProvider = storeConfiguration.getClassLoaderProvider(); } - public StorageManager getInstanceOfStorageManager() + public EmbeddedStorageManager getInstanceOfStorageManager() { this.ensureEntitiesInRoot(); return this.storageManager; @@ -120,7 +122,7 @@ private synchronized void ensureEntitiesInRoot() this.root.getCurrentRootData().getEntityTypesCount(), this.root.getCurrentRootData().getEntityCount() ); - EclipseStoreMigrator.migrate(this.root, this.storageManager); + EclipseStoreMigrator.migrateStructure(this.root, this.storageManager); } } @@ -492,6 +494,11 @@ public Object getObject(final long objectId) return this.storageManager.getObject(objectId); } + public DataVersion getDataVersion() + { + return this.getRoot().getDataVersion(); + } + @Override public ReadWriteLock getReadWriteLock() { diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java index 43d9991a..07626b18 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/Root.java @@ -22,8 +22,8 @@ /** - * This is the root object for all versions <2.0.0 and is used for upgrading to the new root. - * @deprecated should not be initialised any more. Version for <2.0.0 + * This is the root object for all versions {@literal <}2.0.0 and is used for upgrading to the new root. + * @deprecated should not be initialised any more. Version for {@literal <}2.0.0 */ @Deprecated(forRemoval = false, since = "2.0.0") public class Root diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java index b75a22b4..3dc0d0b3 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/config/EclipseStoreClientConfiguration.java @@ -17,6 +17,7 @@ import jakarta.validation.Validation; import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.eclipse.serializer.reflect.ClassLoaderProvider; import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties; @@ -24,6 +25,7 @@ import org.eclipse.store.storage.embedded.types.EmbeddedStorageFoundation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -31,11 +33,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.transaction.PlatformTransactionManager; +import software.xdev.micromigration.migrater.MicroMigrater; import software.xdev.spring.data.eclipse.store.repository.EclipseStoreStorage; +import software.xdev.spring.data.eclipse.store.repository.root.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.transactions.EclipseStoreTransactionManager; @@ -83,6 +89,8 @@ public abstract class EclipseStoreClientConfiguration implements EclipseStoreSto @Value("${spring.devtools.restart.enabled:true}") protected boolean springDevtoolsRestartEnabled; + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + @Lazy @Autowired protected EclipseStoreClientConfiguration( final EclipseStoreProperties defaultEclipseStoreProperties, @@ -206,6 +214,33 @@ public void shutdownStorageOnContextClosed(final ContextClosedEvent event) @Bean public Validator getValidator() { - return Validation.buildDefaultValidatorFactory().getValidator(); + try(final ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) + { + return factory.getValidator(); + } + } + + /** + * "Why don't you migrate the data wherever you call EclipseStoreMigrator.migrateStructure?" - Because in + * order to be able to access repositories in DataMigrationScripts, we can't have the migration-method block the + * start of the storage. That would lead to a deadlock, and we don't want that. + */ + @EventListener + public void migrateDataOnContextStarted(final ContextRefreshedEvent event) + { + try + { + final MicroMigrater dataMigrater = event.getApplicationContext().getBean(MicroMigrater.class); + this.getStorageInstance().start(); // In case the storage hasn't started yet. + EclipseStoreMigrator.migrateData( + this.getStorageInstance().getRoot(), + dataMigrater, + this.getStorageInstance().getInstanceOfStorageManager() + ); + } + catch(final NoSuchBeanDefinitionException e) + { + LOG.info("No migration of data needed since there is no migrater defined."); + } } } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EclipseStoreMigrator.java similarity index 63% rename from spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java rename to spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EclipseStoreMigrator.java index 695f0504..a8943a46 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreMigrator.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EclipseStoreMigrator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package software.xdev.spring.data.eclipse.store.repository; +package software.xdev.spring.data.eclipse.store.repository.root; import java.util.TreeSet; @@ -21,9 +21,10 @@ import software.xdev.micromigration.eclipsestore.MigrationManager; import software.xdev.micromigration.migrater.ExplicitMigrater; +import software.xdev.micromigration.migrater.MicroMigrater; import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript; import software.xdev.micromigration.version.MigrationVersion; -import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataVersion; import software.xdev.spring.data.eclipse.store.repository.root.update.scripts.v2_0_0_InitializeVersioning; import software.xdev.spring.data.eclipse.store.repository.root.update.scripts.v2_4_0_InitializeLazy; @@ -40,12 +41,40 @@ private EclipseStoreMigrator() { } - public static void migrate(final VersionedRoot versionedRoot, final EmbeddedStorageManager storageManager) + public static void migrateStructure(final VersionedRoot versionedRoot, final EmbeddedStorageManager storageManager) { final ExplicitMigrater migrater = new ExplicitMigrater(SCRIPTS); new MigrationManager(versionedRoot, migrater, storageManager).migrate(versionedRoot); } + public static void migrateData( + final VersionedRoot versionedRoot, + final MicroMigrater migrater, + final EmbeddedStorageManager storageManager) + { + if(migrater != null) + { + final DataVersion dataVersion = versionedRoot.getDataVersion(); + new MigrationManager( + dataVersion::getVersion, + dataVersion::setVersion, + newVersion -> EclipseStoreMigrator.versionStorer(versionedRoot, storageManager, newVersion), + migrater, + storageManager) + .migrate(dataVersion); + } + } + + private static void versionStorer( + final VersionedRoot versionedRoot, + final EmbeddedStorageManager currentStorageManager, + final MigrationVersion newVersion) + { + currentStorageManager.store(versionedRoot); + currentStorageManager.store(versionedRoot.getDataVersion()); + currentStorageManager.store(newVersion); + } + public static MigrationVersion getLatestVersion() { final ExplicitMigrater migrater = new ExplicitMigrater(SCRIPTS); diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java index 1ed25d39..cc30bac3 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java @@ -24,8 +24,8 @@ /** - * This is a object for all versions <2.4.0 and is used for upgrading to the new root. - * @deprecated should not be initialised anymore. Version for <2.4.0 + * This is a object for all versions {@literal <}2.4.0 and is used for upgrading to the new root. + * @deprecated should not be initialised anymore. Version for {@literal <}2.4.0 * * @param type of entity to store * @param type of id of the entity to store. Can be {@link Void} if no ID is used. diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java index 56e9e4e1..fe5d4c4f 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/RootDataV2.java @@ -21,8 +21,8 @@ /** - * This is a object for all versions <2.4.0 and is used for upgrading to the new root. - * @deprecated should not be initialised anymore. Version for <2.4.0 + * This is a object for all versions {@literal <}2.4.0 and is used for upgrading to the new root. + * @deprecated should not be initialised anymore. Version for {@literal <}2.4.0 */ @Deprecated(forRemoval = false, since = "2.4.0") @SuppressWarnings({"java:S119", "unchecked"}) diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java index 5df1f28c..f1e59e28 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/VersionedRoot.java @@ -17,8 +17,8 @@ import software.xdev.micromigration.version.MigrationVersion; import software.xdev.micromigration.version.Versioned; -import software.xdev.spring.data.eclipse.store.repository.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.repository.Root; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataVersion; import software.xdev.spring.data.eclipse.store.repository.root.v2_4.RootDataV2_4; @@ -27,6 +27,8 @@ public class VersionedRoot implements Versioned { private MigrationVersion version; + private DataVersion dataVersion; + private Root rootDataV1; private RootDataV2 rootDataV2; @@ -40,7 +42,7 @@ public VersionedRoot() } /** - * @param rootDataV1 is only filled if this is a old version <2.0.0 and needs upgrading + * @param rootDataV1 is only filled if this is a old version {@literal <}2.0.0 and needs upgrading */ public VersionedRoot(final Root rootDataV1) { @@ -104,4 +106,13 @@ public MigrationVersion getVersion() { return this.version; } + + public DataVersion getDataVersion() + { + if(this.dataVersion == null) + { + this.dataVersion = new DataVersion(); + } + return this.dataVersion; + } } diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrater.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrater.java new file mode 100644 index 00000000..d23e39b3 --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrater.java @@ -0,0 +1,102 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.repository.root.data.version; + +import java.util.List; +import java.util.TreeSet; +import java.util.function.Consumer; + +import software.xdev.micromigration.migrater.ExplicitMigrater; +import software.xdev.micromigration.migrater.MicroMigrater; +import software.xdev.micromigration.notification.ScriptExecutionNotificationWithScriptReference; +import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager; + +public class DataMigrater implements MicroMigrater +{ + private final List scripts; + private ExplicitMigrater explicitMigrater; + + public DataMigrater(final List scripts) + { + this.scripts = scripts; + } + + private ExplicitMigrater ensureExplicitMigrater() + { + if(this.explicitMigrater == null) + { + this.explicitMigrater = new ExplicitMigrater(this.scripts.toArray(DataMigrationScript[]::new)); + } + return this.explicitMigrater; + } + + private boolean isUseful() + { + return this.scripts != null && !this.scripts.isEmpty(); + } + + @Override + public TreeSet> getSortedScripts() + { + if(this.isUseful()) + { + return this.ensureExplicitMigrater().getSortedScripts(); + } + // noinspection SortedCollectionWithNonComparableKeys + return new TreeSet<>(); + } + + @Override + public > MigrationVersion migrateToNewest( + final MigrationVersion fromVersion, + final E storageManager, + final Object root) + { + if(this.isUseful()) + { + return this.ensureExplicitMigrater().migrateToNewest(fromVersion, storageManager, root); + } + return null; + } + + @Override + public > MigrationVersion migrateToVersion( + final MigrationVersion fromVersion, + final MigrationVersion targetVersion, + final E storageManager, + final Object objectToMigrate) + { + if(this.isUseful()) + { + return this.ensureExplicitMigrater() + .migrateToVersion(fromVersion, targetVersion, storageManager, objectToMigrate); + } + return null; + } + + @Override + public void registerNotificationConsumer( + final Consumer notificationConsumer + ) + { + if(this.isUseful()) + { + this.ensureExplicitMigrater().registerNotificationConsumer(notificationConsumer); + } + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigraterFactory.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigraterFactory.java new file mode 100644 index 00000000..b852401c --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigraterFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.repository.root.data.version; + +import java.util.List; +import java.util.Optional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.migrater.MicroMigrater; + + +@Component +public class DataMigraterFactory +{ + @Bean + @ConditionalOnMissingBean(MicroMigrater.class) + public MicroMigrater getDataMigrater(final Optional> scripts) + { + return new DataMigrater(scripts.orElse(List.of())); + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrationScript.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrationScript.java new file mode 100644 index 00000000..2f2cf9df --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataMigrationScript.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.repository.root.data.version; + +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; + + +@Component +public interface DataMigrationScript + extends VersionAgnosticMigrationScript +{ +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataVersion.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataVersion.java new file mode 100644 index 00000000..69fa9eff --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/DataVersion.java @@ -0,0 +1,57 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.repository.root.data.version; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import software.xdev.micromigration.notification.ScriptExecutionNotificationWithoutScriptReference; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.micromigration.version.Versioned; +import software.xdev.micromigration.version.VersionedAndKeeperOfHistory; + + +public class DataVersion implements Versioned, VersionedAndKeeperOfHistory +{ + private MigrationVersion currentVersion; + private final List migrationHistory = new ArrayList<>(); + + @Override + public void addExecutedScript(final ScriptExecutionNotificationWithoutScriptReference executedScriptInformation) + { + this.migrationHistory.add(Objects.requireNonNull(executedScriptInformation)); + } + + @Override + public List getMigrationHistory() + { + return this.migrationHistory; + } + + @Override + public void setVersion(final MigrationVersion version) + { + Objects.requireNonNull(version); + this.currentVersion = version; + } + + @Override + public MigrationVersion getVersion() + { + return this.currentVersion; + } +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/ReflectiveDataMigrationScript.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/ReflectiveDataMigrationScript.java new file mode 100644 index 00000000..36616e95 --- /dev/null +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/data/version/ReflectiveDataMigrationScript.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.repository.root.data.version; + +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.ReflectiveVersionMigrationScript; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; + + +@Component +public abstract class ReflectiveDataMigrationScript + extends ReflectiveVersionMigrationScript + implements DataMigrationScript +{ +} diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java index 71b03434..0603618d 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/LoggingUpdateScript.java @@ -21,12 +21,13 @@ import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; import software.xdev.micromigration.scripts.Context; import software.xdev.micromigration.scripts.ReflectiveVersionMigrationScript; +import software.xdev.spring.data.eclipse.store.repository.root.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; /** * All migration scripts must be added to - * {@link software.xdev.spring.data.eclipse.store.repository.EclipseStoreMigrator#SCRIPTS}! + * {@link EclipseStoreMigrator#SCRIPTS}! */ public abstract class LoggingUpdateScript extends ReflectiveVersionMigrationScript diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitializeVersioning.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitializeVersioning.java index 73eba636..99dd0e84 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitializeVersioning.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_0_0_InitializeVersioning.java @@ -20,6 +20,7 @@ import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.repository.root.RootDataV2; import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; import software.xdev.spring.data.eclipse.store.repository.root.v2_4.EntityData; @@ -30,7 +31,7 @@ * version of Root({@link RootDataV2}). *

* All migration scripts must be added to - * {@link software.xdev.spring.data.eclipse.store.repository.EclipseStoreMigrator#SCRIPTS}! + * {@link EclipseStoreMigrator#SCRIPTS}! */ @SuppressWarnings({"checkstyle:TypeName", "deprecation"}) public class v2_0_0_InitializeVersioning extends LoggingUpdateScript diff --git a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_4_0_InitializeLazy.java b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_4_0_InitializeLazy.java index c34032e2..c57abcad 100644 --- a/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_4_0_InitializeLazy.java +++ b/spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/update/scripts/v2_4_0_InitializeLazy.java @@ -20,6 +20,7 @@ import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.EclipseStoreMigrator; import software.xdev.spring.data.eclipse.store.repository.root.RootDataV2; import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; @@ -29,7 +30,7 @@ * version of Root({@link RootDataV2}). *

* All migration scripts must be added to - * {@link software.xdev.spring.data.eclipse.store.repository.EclipseStoreMigrator#SCRIPTS}! + * {@link EclipseStoreMigrator#SCRIPTS}! */ @SuppressWarnings({"checkstyle:TypeName", "deprecation"}) public class v2_4_0_InitializeLazy extends LoggingUpdateScript diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java index 04420126..d83c5844 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/TestConfiguration.java @@ -40,7 +40,7 @@ public class TestConfiguration extends EclipseStoreClientConfiguration { private final String storageDirectory = StorageDirectoryNameProvider.getNewStorageDirectoryPath(); - + @Autowired protected TestConfiguration( final EclipseStoreProperties defaultEclipseStoreProperties, diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintDaoObject.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintDaoObject.java index 7d113e96..54c18e35 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintDaoObject.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintDaoObject.java @@ -65,7 +65,7 @@ public class ConstraintDaoObject @DecimalMin("5.00") BigDecimal discountMin5; - @DecimalMax("30.00") + @DecimalMax("20.00") BigDecimal discountMax20; @Email @@ -116,8 +116,8 @@ public class ConstraintDaoObject @PositiveOrZero int positiveOrZeroField; - @Size(min = 2, max = 240) - String messageMin2AndMax240; + @Size(min = 2, max = 10) + String messageMin2AndMax10; public ConstraintDaoObject() { @@ -141,7 +141,7 @@ public ConstraintDaoObject() this.phoneNumber = "(123)456-7890"; this.area = BigDecimal.valueOf(1); this.positiveOrZeroField = 1; - this.messageMin2AndMax240 = ".."; + this.messageMin2AndMax10 = ".."; } @AssertFalse @@ -186,12 +186,12 @@ public void setDiscountMin5(final @DecimalMin("5.00") BigDecimal discountMin5) this.discountMin5 = discountMin5; } - public @DecimalMax("30.00") BigDecimal getDiscountMax20() + public @DecimalMax("20.00") BigDecimal getDiscountMax20() { return this.discountMax20; } - public void setDiscountMax20(final @DecimalMax("30.00") BigDecimal discountMax20) + public void setDiscountMax20(final @DecimalMax("20.00") BigDecimal discountMax20) { this.discountMax20 = discountMax20; } @@ -361,13 +361,13 @@ public void setPositiveOrZeroField(@PositiveOrZero final int positiveOrZeroField this.positiveOrZeroField = positiveOrZeroField; } - public @Size(min = 2, max = 240) String getMessageMin2AndMax240() + public @Size(min = 2, max = 10) String getMessageMin2AndMax10() { - return this.messageMin2AndMax240; + return this.messageMin2AndMax10; } - public void setMessageMin2AndMax240(final @Size(min = 2, max = 240) String messageMin2AndMax240) + public void setMessageMin2AndMax10(final @Size(min = 2, max = 10) String messageMin2AndMax10) { - this.messageMin2AndMax240 = messageMin2AndMax240; + this.messageMin2AndMax10 = messageMin2AndMax10; } } diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintsTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintsTest.java index 5578cea9..ea8016a1 100644 --- a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintsTest.java +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/constraints/ConstraintsTest.java @@ -15,11 +15,20 @@ */ package software.xdev.spring.data.eclipse.store.integration.isolated.tests.constraints; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_CLASS; + +import java.math.BigDecimal; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.function.Consumer; + import jakarta.validation.ConstraintViolationException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import software.xdev.spring.data.eclipse.store.integration.isolated.IsolatedTestAnnotations; @@ -32,6 +41,8 @@ */ @IsolatedTestAnnotations @ContextConfiguration(classes = {ConstraintsTestConfiguration.class}) +@SuppressWarnings("checkstyle:MethodName") +@DirtiesContext(classMode = BEFORE_CLASS) class ConstraintsTest { @Autowired @@ -42,19 +53,432 @@ class ConstraintsTest @Test void assertFalseWithTrue() { - final ConstraintDaoObject constraintDaoObject = new ConstraintDaoObject(); - constraintDaoObject.setAlwaysFalse(true); - Assertions.assertThrows( - ConstraintViolationException.class, - () -> this.repository.save(constraintDaoObject) - ); + this.assertConstraintViolationChange(o -> o.setAlwaysFalse(true)); } @Test void assertFalseWithFalse() + { + this.assertGoodChange(o -> o.setAlwaysFalse(false)); + } + + @Test + void assertTrueWithTrue() + { + this.assertGoodChange(o -> o.setAlwaysTrue(true)); + } + + @Test + void assertTrueWithFalse() + { + this.assertConstraintViolationChange(o -> o.setAlwaysTrue(false)); + } + + @Test + void assertDigitsGood() + { + this.assertGoodChange(o -> o.setPrice(BigDecimal.valueOf(123456.78))); + } + + @Test + void assertDigitsTooMuchInteger() + { + this.assertConstraintViolationChange(o -> o.setPrice(BigDecimal.valueOf(1234567))); + } + + @Test + void assertDigitsTooMuchFraction() + { + this.assertConstraintViolationChange(o -> o.setPrice(BigDecimal.valueOf(0.123))); + } + + @Test + void assertDecimalMinGoodExact() + { + this.assertGoodChange(o -> o.setDiscountMin5(BigDecimal.valueOf(5))); + } + + @Test + void assertDecimalMinGoodGreater() + { + this.assertGoodChange(o -> o.setDiscountMin5(BigDecimal.valueOf(6))); + } + + @Test + void assertDecimalMinBadSmaller() + { + this.assertConstraintViolationChange(o -> o.setDiscountMin5(BigDecimal.valueOf(4))); + } + + @Test + void assertDecimalMinBadNegative() + { + this.assertConstraintViolationChange(o -> o.setDiscountMin5(BigDecimal.valueOf(-1))); + } + + @Test + void assertDecimalMaxGoodExact() + { + this.assertGoodChange(o -> o.setDiscountMax20(BigDecimal.valueOf(20))); + } + + @Test + void assertDecimalMaxGoodSmaller() + { + this.assertGoodChange(o -> o.setDiscountMax20(BigDecimal.ONE)); + } + + @Test + void assertDecimalMaxGoodZero() + { + this.assertGoodChange(o -> o.setDiscountMax20(BigDecimal.ZERO)); + } + + @Test + void assertDecimalMaxBadBigger() + { + this.assertConstraintViolationChange(o -> o.setDiscountMax20(BigDecimal.valueOf(21))); + } + + @Test + void assertDecimalMaxBadBiggest() + { + this.assertConstraintViolationChange(o -> o.setDiscountMax20(BigDecimal.valueOf(Double.MAX_VALUE))); + } + + @Test + void assertDecimalMaxGoodNegative() + { + this.assertGoodChange(o -> o.setDiscountMax20(BigDecimal.valueOf(-1))); + } + + @Test + void assertEmailGood() + { + this.assertGoodChange(o -> o.setEmailField("a@b.c")); + } + + @Test + void assertEmailBad_MissingAt() + { + this.assertConstraintViolationChange(o -> o.setEmailField("a.b")); + } + + @Test + void assertEmailGood_MissingDot() + { + this.assertGoodChange(o -> o.setEmailField("a@b")); + } + + @Test + void assertEmailBad_NoPrefixBeforeAt() + { + this.assertConstraintViolationChange(o -> o.setEmailField("@b.c")); + } + + @Test + void assertEmailGood_Empty() + { + this.assertGoodChange(o -> o.setEmailField("")); + } + + @Test + void assertEmailGood_Null() + { + this.assertGoodChange(o -> o.setEmailField(null)); + } + + @Test + void assertFutureFieldGood() + { + this.assertGoodChange(o -> o.setFutureField(Date.from(Instant.now().plus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertFutureFieldBad_Now() + { + this.assertConstraintViolationChange(o -> o.setFutureField(Date.from(Instant.now()))); + } + + @Test + void assertFutureFieldBad_Yesterday() + { + this.assertConstraintViolationChange(o -> o.setFutureField(Date.from(Instant.now().minus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertFutureOrPresentFieldGood() + { + this.assertGoodChange(o -> o.setFutureOrPresentField(Date.from(Instant.now().plus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertFutureOrPresentFieldBad_Yesterday() + { + this.assertConstraintViolationChange(o -> o.setFutureOrPresentField(Date.from(Instant.now() + .minus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertPastFieldBad() + { + this.assertConstraintViolationChange(o -> o.setPastField(Date.from(Instant.now().plus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertPastFieldGood_Now() + { + this.assertGoodChange(o -> o.setPastField(Date.from(Instant.now()))); + } + + @Test + void assertPastFieldGood_Yesterday() + { + this.assertGoodChange(o -> o.setPastField(Date.from(Instant.now().minus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertPastOrPresentFieldBad() + { + this.assertConstraintViolationChange(o -> o.setPastOrPresentField(Date.from(Instant.now() + .plus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertPastOrPresentFieldGood_Now() + { + this.assertGoodChange(o -> o.setPastOrPresentField(Date.from(Instant.now()))); + } + + @Test + void assertPastOrPresentFieldGood_Yesterday() + { + this.assertGoodChange(o -> o.setPastOrPresentField(Date.from(Instant.now().minus(1, ChronoUnit.DAYS)))); + } + + @Test + void assertMaxGood() + { + this.assertGoodChange(o -> o.setQuantityMax10(10)); + } + + @Test + void assertMaxBad() + { + this.assertConstraintViolationChange(o -> o.setQuantityMax10(11)); + } + + @Test + void assertMinGood() + { + this.assertGoodChange(o -> o.setQuantityMin5(5)); + } + + @Test + void assertMinBad() + { + this.assertConstraintViolationChange(o -> o.setQuantityMin5(3)); + } + + @Test + void assertNegativeFieldGood() + { + this.assertGoodChange(o -> o.setNegativeField(-1)); + } + + @Test + void assertNegativeFieldBad() + { + this.assertConstraintViolationChange(o -> o.setNegativeField(1)); + } + + @Test + void assertNegativeFieldBad_Zero() + { + this.assertConstraintViolationChange(o -> o.setNegativeField(0)); + } + + @Test + void assertNegativeOrZeroFieldGood_Zero() + { + this.assertGoodChange(o -> o.setNegativeOrZeroField(0)); + } + + @Test + void assertNegativeOrZeroFieldGood() + { + this.assertGoodChange(o -> o.setNegativeOrZeroField(-1)); + } + + @Test + void assertNegativeOrZeroFieldBad() + { + this.assertConstraintViolationChange(o -> o.setNegativeOrZeroField(1)); + } + + @Test + void assertNotBlankGood() + { + this.assertGoodChange(o -> o.setMessageNotBlank("a")); + } + + @Test + void assertNotBlankBad_Null() + { + this.assertConstraintViolationChange(o -> o.setMessageNotBlank(null)); + } + + @Test + void assertNotBlankBad_Empty() + { + this.assertConstraintViolationChange(o -> o.setMessageNotBlank("")); + } + + @Test + void assertNotBlankBad_Space() + { + this.assertConstraintViolationChange(o -> o.setMessageNotBlank(" ")); + } + + @Test + void assertNotEmptyGood() + { + this.assertGoodChange(o -> o.setMessageNotEmpty("a")); + } + + @Test + void assertNotEmptyBad_Null() + { + this.assertConstraintViolationChange(o -> o.setMessageNotEmpty(null)); + } + + @Test + void assertNotEmptyBad_Empty() + { + this.assertConstraintViolationChange(o -> o.setMessageNotEmpty("")); + } + + @Test + void assertNotEmptyGood_Space() + { + this.assertGoodChange(o -> o.setUsername(" ")); + } + + @Test + void assertNotNullGood() + { + this.assertGoodChange(o -> o.setUsername("a")); + } + + @Test + void assertNotNullBad_Null() + { + this.assertConstraintViolationChange(o -> o.setUsername(null)); + } + + @Test + void assertNotNullGood_Empty() + { + this.assertGoodChange(o -> o.setUsername("")); + } + + @Test + void assertNotNullGood_Space() + { + this.assertGoodChange(o -> o.setUsername(" ")); + } + + @Test + void assertPatternGood() + { + this.assertGoodChange(o -> o.setPhoneNumber("(123)456-7890")); + } + + @Test + void assertPatternBad() + { + this.assertConstraintViolationChange(o -> o.setPhoneNumber("456-7890")); + } + + @Test + void assertPositiveGood() + { + this.assertGoodChange(o -> o.setArea(BigDecimal.ONE)); + } + + @Test + void assertPositiveBad() + { + this.assertConstraintViolationChange(o -> o.setArea(BigDecimal.valueOf(-1))); + } + + @Test + void assertPositiveBad_Zero() + { + this.assertConstraintViolationChange(o -> o.setArea(BigDecimal.ZERO)); + } + + @Test + void assertPositiveOrZeroGood() + { + this.assertGoodChange(o -> o.setPositiveOrZeroField(1)); + } + + @Test + void assertPositiveOrZeroBad() + { + this.assertConstraintViolationChange(o -> o.setPositiveOrZeroField(-1)); + } + + @Test + void assertPositiveOrZeroGood_Zero() + { + this.assertGoodChange(o -> o.setPositiveOrZeroField(0)); + } + + @Test + void assertStringMinAndMaxGood() + { + this.assertGoodChange(o -> o.setMessageMin2AndMax10("123")); + } + + @Test + void assertStringMinAndMaxBad_TooSmall() + { + this.assertConstraintViolationChange(o -> o.setMessageMin2AndMax10("1")); + } + + @Test + void assertStringMinAndMaxBad_TooBig() + { + this.assertConstraintViolationChange(o -> o.setMessageMin2AndMax10("1234567890-")); + } + + /// ////-------------Help Functions -------------////////////// + private void assertGoodChange(final Consumer change) { final ConstraintDaoObject constraintDaoObject = new ConstraintDaoObject(); - constraintDaoObject.setAlwaysFalse(false); + change.accept(constraintDaoObject); + this.assertGoodSave(constraintDaoObject); + } + + private void assertGoodSave(final ConstraintDaoObject constraintDaoObject) + { Assertions.assertDoesNotThrow(() -> this.repository.save(constraintDaoObject)); } + + private void assertConstraintViolationChange(final Consumer change) + { + final ConstraintDaoObject constraintDaoObject = new ConstraintDaoObject(); + change.accept(constraintDaoObject); + this.assertConstraintViolationSave(constraintDaoObject); + } + + private void assertConstraintViolationSave(final ConstraintDaoObject constraintDaoObject) + { + Assertions.assertThrows( + ConstraintViolationException.class, + () -> this.repository.save(constraintDaoObject) + ); + } } diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/CustomMigrater.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/CustomMigrater.java new file mode 100644 index 00000000..d7d7a73f --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/CustomMigrater.java @@ -0,0 +1,75 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import java.util.TreeSet; +import java.util.function.Consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.migrater.ExplicitMigrater; +import software.xdev.micromigration.migrater.MicroMigrater; +import software.xdev.micromigration.notification.ScriptExecutionNotificationWithScriptReference; +import software.xdev.micromigration.scripts.VersionAgnosticMigrationScript; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.micromigration.versionagnostic.VersionAgnosticMigrationEmbeddedStorageManager; + + +@Component +public class CustomMigrater implements MicroMigrater +{ + private final ExplicitMigrater explicitMigrater; + + @Autowired + public CustomMigrater(final PersistedEntityRepository repository) + { + this.explicitMigrater = new ExplicitMigrater(new v1_0_0_Init(repository)); + } + + @Override + public TreeSet> getSortedScripts() + { + return this.explicitMigrater.getSortedScripts(); + } + + @Override + public > MigrationVersion migrateToNewest( + final MigrationVersion fromVersion, + final E storageManager, + final Object root) + { + return this.explicitMigrater.migrateToNewest(fromVersion, storageManager, root); + } + + @Override + public > MigrationVersion migrateToVersion( + final MigrationVersion fromVersion, + final MigrationVersion targetVersion, + final E storageManager, + final Object objectToMigrate) + { + return this.explicitMigrater.migrateToVersion(fromVersion, targetVersion, storageManager, objectToMigrate); + } + + @Override + public void registerNotificationConsumer( + final Consumer notificationConsumer + ) + { + this.explicitMigrater.registerNotificationConsumer(notificationConsumer); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTest.java new file mode 100644 index 00000000..f35e26a2 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTest.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.helper.TestUtil; +import software.xdev.spring.data.eclipse.store.integration.isolated.IsolatedTestAnnotations; + + +@IsolatedTestAnnotations +@ContextConfiguration(classes = {DataMigrationWithMigraterTestConfiguration.class}) +class DataMigrationWithMigraterTest +{ + @Autowired + private DataMigrationWithMigraterTestConfiguration configuration; + @Autowired + private PersistedEntityRepository repository; + + @Test + void assertUpdateV1Executed() + { + Assertions.assertEquals(1, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 0, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + + @Test + void assertNotUpdatedAfterMigration() + { + TestUtil.doBeforeAndAfterRestartOfDatastore( + this.configuration, + () -> { + Assertions.assertEquals(1, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 0, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + ); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTestConfiguration.java new file mode 100644 index 00000000..d205b0b3 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/DataMigrationWithMigraterTestConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import org.eclipse.serializer.reflect.ClassLoaderProvider; +import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties; +import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import software.xdev.spring.data.eclipse.store.integration.TestConfiguration; +import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories; + + +@ComponentScan({"software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater"}) +@Configuration +@EnableEclipseStoreRepositories +public class DataMigrationWithMigraterTestConfiguration extends TestConfiguration +{ + @Autowired + protected DataMigrationWithMigraterTestConfiguration( + final EclipseStoreProperties defaultEclipseStoreProperties, + final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider, + final ClassLoaderProvider classLoaderProvider) + { + super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntity.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntity.java new file mode 100644 index 00000000..82eda477 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntity.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + + +public class PersistedEntity +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntityRepository.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntityRepository.java new file mode 100644 index 00000000..9fbffdc0 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/PersistedEntityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import org.springframework.data.repository.CrudRepository; + + +public interface PersistedEntityRepository extends CrudRepository +{ +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/v1_0_0_Init.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/v1_0_0_Init.java new file mode 100644 index 00000000..94c9cfd3 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/migrater/v1_0_0_Init.java @@ -0,0 +1,40 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.migrater; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + + +@SuppressWarnings("checkstyle:TypeName") +public class v1_0_0_Init extends ReflectiveDataMigrationScript +{ + private final PersistedEntityRepository + repository; + + public v1_0_0_Init(final PersistedEntityRepository repository) + { + this.repository = repository; + } + + @Override + public void migrate(final Context context) + { + this.repository.save(new PersistedEntity()); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTest.java new file mode 100644 index 00000000..516064a2 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTest.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.helper.TestUtil; +import software.xdev.spring.data.eclipse.store.integration.isolated.IsolatedTestAnnotations; + + +@IsolatedTestAnnotations +@ContextConfiguration(classes = {DataMigrationWithMultipleScriptsTestConfiguration.class}) +class DataMigrationWithMultipleScriptsTest +{ + @Autowired + private DataMigrationWithMultipleScriptsTestConfiguration configuration; + @Autowired + private PersistedEntityRepository repository; + + @Test + void assertUpdateV1Executed() + { + Assertions.assertEquals(3, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 2, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + + @Test + void assertNotUpdatedAfterMigration() + { + TestUtil.doBeforeAndAfterRestartOfDatastore( + this.configuration, + () -> { + Assertions.assertEquals(3, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 2, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + ); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTestConfiguration.java new file mode 100644 index 00000000..1e934721 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/DataMigrationWithMultipleScriptsTestConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.eclipse.serializer.reflect.ClassLoaderProvider; +import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties; +import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import software.xdev.spring.data.eclipse.store.integration.TestConfiguration; +import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories; + + +@ComponentScan({ + "software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts"}) +@Configuration +@EnableEclipseStoreRepositories +public class DataMigrationWithMultipleScriptsTestConfiguration extends TestConfiguration +{ + @Autowired + protected DataMigrationWithMultipleScriptsTestConfiguration( + final EclipseStoreProperties defaultEclipseStoreProperties, + final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider, + final ClassLoaderProvider classLoaderProvider) + { + super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntity.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntity.java new file mode 100644 index 00000000..ede993b2 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntity.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + + +public class PersistedEntity +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntityRepository.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntityRepository.java new file mode 100644 index 00000000..7d9c4791 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/PersistedEntityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.springframework.data.repository.CrudRepository; + + +public interface PersistedEntityRepository extends CrudRepository +{ +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_0_0_Init.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_0_0_Init.java new file mode 100644 index 00000000..609edd8f --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_0_0_Init.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + +@SuppressWarnings("checkstyle:TypeName") +@Component +public class v1_0_0_Init extends ReflectiveDataMigrationScript +{ + private final PersistedEntityRepository + repository; + + public v1_0_0_Init(@Autowired final PersistedEntityRepository repository) + { + this.repository = repository; + } + + @Override + public void migrate(final Context context) + { + this.repository.save(new PersistedEntity()); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_1_0_NextScript.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_1_0_NextScript.java new file mode 100644 index 00000000..85bcd62c --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_1_0_NextScript.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + +@SuppressWarnings("checkstyle:TypeName") +@Component +public class v1_1_0_NextScript extends ReflectiveDataMigrationScript +{ + private final PersistedEntityRepository + repository; + + public v1_1_0_NextScript(@Autowired final PersistedEntityRepository repository) + { + this.repository = repository; + } + + @Override + public void migrate(final Context context) + { + this.repository.save(new PersistedEntity()); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_2_0_CustomNamedScript.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_2_0_CustomNamedScript.java new file mode 100644 index 00000000..654cd327 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/multiple/scripts/v1_2_0_CustomNamedScript.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.multiple.scripts; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.DataMigrationScript; + +@SuppressWarnings("checkstyle:TypeName") +@Component +public class v1_2_0_CustomNamedScript implements DataMigrationScript +{ + private final PersistedEntityRepository + repository; + + public v1_2_0_CustomNamedScript(@Autowired final PersistedEntityRepository repository) + { + this.repository = repository; + } + + @Override + public MigrationVersion getTargetVersion() + { + return new MigrationVersion(1, 2, 0); + } + + @Override + public void migrate(final Context context) + { + this.repository.save(new PersistedEntity()); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTest.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTest.java new file mode 100644 index 00000000..3970616c --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTest.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +import software.xdev.micromigration.version.MigrationVersion; +import software.xdev.spring.data.eclipse.store.helper.TestUtil; +import software.xdev.spring.data.eclipse.store.integration.isolated.IsolatedTestAnnotations; + + +@IsolatedTestAnnotations +@ContextConfiguration(classes = {DataMigrationWithScriptTestConfiguration.class}) +class DataMigrationWithScriptTest +{ + @Autowired + private DataMigrationWithScriptTestConfiguration configuration; + @Autowired + private PersistedEntityRepository repository; + + @Test + void assertUpdateV1Executed() + { + Assertions.assertEquals(1, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 0, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + + @Test + void assertNotUpdatedAfterMigration() + { + TestUtil.doBeforeAndAfterRestartOfDatastore( + this.configuration, + () -> { + Assertions.assertEquals(1, this.repository.count()); + Assertions.assertEquals( + new MigrationVersion(1, 0, 0), + this.configuration.getStorageInstance().getRoot().getDataVersion().getVersion()); + } + ); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTestConfiguration.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTestConfiguration.java new file mode 100644 index 00000000..c1d44162 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/DataMigrationWithScriptTestConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script; + +import org.eclipse.serializer.reflect.ClassLoaderProvider; +import org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties; +import org.eclipse.store.integrations.spring.boot.types.factories.EmbeddedStorageFoundationFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import software.xdev.spring.data.eclipse.store.integration.TestConfiguration; +import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories; + + +@ComponentScan({"software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script"}) +@Configuration +@EnableEclipseStoreRepositories +public class DataMigrationWithScriptTestConfiguration extends TestConfiguration +{ + @Autowired + protected DataMigrationWithScriptTestConfiguration( + final EclipseStoreProperties defaultEclipseStoreProperties, + final EmbeddedStorageFoundationFactory defaultEclipseStoreProvider, + final ClassLoaderProvider classLoaderProvider) + { + super(defaultEclipseStoreProperties, defaultEclipseStoreProvider, classLoaderProvider); + } +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntity.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntity.java new file mode 100644 index 00000000..61f5a771 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntity.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script; + +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + + +public class PersistedEntity +{ + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntityRepository.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntityRepository.java new file mode 100644 index 00000000..062fbaa8 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/PersistedEntityRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script; + +import org.springframework.data.repository.CrudRepository; + + +public interface PersistedEntityRepository extends CrudRepository +{ +} diff --git a/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/v1_0_0_Init.java b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/v1_0_0_Init.java new file mode 100644 index 00000000..07697ef2 --- /dev/null +++ b/spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/data/migration/with/script/v1_0_0_Init.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 XDEV Software (https://xdev.software) + * + * 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. + */ +package software.xdev.spring.data.eclipse.store.integration.isolated.tests.data.migration.with.script; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import software.xdev.micromigration.eclipsestore.MigrationEmbeddedStorageManager; +import software.xdev.micromigration.scripts.Context; +import software.xdev.spring.data.eclipse.store.repository.root.VersionedRoot; +import software.xdev.spring.data.eclipse.store.repository.root.data.version.ReflectiveDataMigrationScript; + + +@SuppressWarnings("checkstyle:TypeName") +@Component +public class v1_0_0_Init extends ReflectiveDataMigrationScript +{ + private final PersistedEntityRepository repository; + + public v1_0_0_Init(@Autowired final PersistedEntityRepository repository) + { + this.repository = repository; + } + + @Override + public void migrate(final Context context) + { + this.repository.save(new PersistedEntity()); + } +}