How to migrate from Mongock 4 to 5 with MongockAnnotationProcessor
mraible opened this issue · comments
Description
I'm trying to migrate the JHipster Quarkus blueprint from using Mongock 4 to 5. The following class doesn't compile because there is no longer a MongockAnnotationProcessor
class. Any idea how to fix?
package io.github.jhipster.sample.config;
import io.mongock.driver.mongodb.sync.v4.driver.MongoSync4Driver;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.oracle.svm.core.annotate.AutomaticFeature;
import io.mongock.runner.standalone.MongockStandalone;
import io.quarkus.runtime.StartupEvent;
import java.util.List;
import java.util.stream.Collectors;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeReflection;
import org.reflections.Reflections;
@ApplicationScoped
public class MongockConfiguration {
private static final List<Class<?>> changeLogs;
static {
changeLogs =
new MongockAnnotationProcessor()
.getChangeLogAnnotationClass()
.stream()
.flatMap(changeLogClass ->
new Reflections("io.github.jhipster.sample.config.dbmigrations").getTypesAnnotatedWith(changeLogClass).stream()
)
.collect(Collectors.toList());
}
@ConfigProperty(name = "quarkus.mongodb.database")
String databaseName;
void onStart(@Observes StartupEvent ev) {
MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder().build());
MongockStandalone
.builder()
.setDriver(MongoSync4Driver.withDefaultLock(mongoClient, databaseName))
.addMigrationClasses(changeLogs)
.buildRunner()
.execute();
}
@AutomaticFeature
private static class NativeSupport implements Feature {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
changeLogs.forEach(clazz -> {
RuntimeReflection.register(clazz);
RuntimeReflection.register(clazz.getConstructors());
RuntimeReflection.register(clazz.getMethods());
});
}
}
}
I'm also curious to know how I should migrate the following class to the new annotations? When I try changing them to io.mongock
, IntelliJ keeps reverting them back to the old imports.
package io.github.jhipster.sample.config.dbmigrations;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
import com.github.cloudyrock.mongock.ChangeLog;
import com.github.cloudyrock.mongock.ChangeSet;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoDatabase;
import io.github.jhipster.sample.domain.Authority;
import io.github.jhipster.sample.domain.User;
import io.github.jhipster.sample.security.AuthoritiesConstants;
import java.time.Instant;
import java.util.Arrays;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
/**
* Creates the initial database setup.
*/
@ChangeLog(order = "001")
public class InitialSetupMigration {
@ChangeSet(order = "01", author = "initiator", id = "01-addAuthorities")
public void addAuthorities(MongoDatabase db) {
Authority adminAuthority = new Authority(AuthoritiesConstants.ADMIN);
Authority userAuthority = new Authority(AuthoritiesConstants.USER);
db.createCollection("jhi_authority");
db
.getCollection("jhi_authority", Authority.class)
.withCodecRegistry(getCodecRegistry())
.insertMany(Arrays.asList(adminAuthority, userAuthority));
}
@ChangeSet(order = "02", author = "initiator", id = "02-addUsers")
public void addUsers(MongoDatabase db) {
Authority adminAuthority = new Authority(AuthoritiesConstants.ADMIN);
Authority userAuthority = new Authority(AuthoritiesConstants.USER);
User anonymousUser = new User();
anonymousUser.id = "user-1";
anonymousUser.login = "anonymoususer";
anonymousUser.password = "$2a$10$j8S5d7Sr7.8VTOYNviDPOeWX8KcYILUVJBsYV83Y5NtECayypx9lO";
anonymousUser.firstName = "Anonymous";
anonymousUser.lastName = "User";
anonymousUser.email = "anonymous@localhost";
anonymousUser.activated = true;
anonymousUser.langKey = "en";
anonymousUser.createdDate = Instant.now();
User adminUser = new User();
adminUser.id = "user-2";
adminUser.login = "admin";
adminUser.password = "$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC";
adminUser.firstName = "admin";
adminUser.lastName = "Administrator";
adminUser.email = "admin@localhost";
adminUser.activated = true;
adminUser.langKey = "en";
adminUser.createdDate = Instant.now();
adminUser.authorities.add(adminAuthority);
adminUser.authorities.add(userAuthority);
User userUser = new User();
userUser.id = "user-3";
userUser.login = "user";
userUser.password = "$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K";
userUser.firstName = "";
userUser.lastName = "User";
userUser.email = "user@localhost";
userUser.activated = true;
userUser.langKey = "en";
userUser.createdDate = Instant.now();
userUser.authorities.add(userAuthority);
db.createCollection("jhi_user");
db
.getCollection("jhi_user", User.class)
.withCodecRegistry(getCodecRegistry())
.insertMany(Arrays.asList(adminUser, anonymousUser, userUser));
}
private CodecRegistry getCodecRegistry() {
CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
return fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
}
}
PRIORITY
MINOR
Version and environment
Mongock
- Mongock version: 5.1.6
- How Mongock is used(builder or annotation approach, etc.): annotation
Environment
- Framework and libraries versions. Quarkus 2.13.0.Final
- Infrastructure: Maven
Steps to Reproduce
See the in-progress PR at jhipster/generator-jhipster-quarkus#247.
Clone the following branch:
git clone -b upgrade-dependencies https://github.com/vishal423/generator-jhipster-quarkus.git
cd generator-jhipster-quarkus
npm install
npm link
Create a new directory (e.g. ~/Downloads/jhipster-quarkus
), then create an app.jdl
file in it.
application {
config {
applicationType monolith
authenticationType jwt
baseName jhipsterSampleApplication
buildTool maven
databaseType mongodb
packageName io.github.jhipster.sample
devDatabaseType mongodb
prodDatabaseType mongodb
enableHibernateCache false
cacheProvider caffeine
testFrameworks [cypress]
}
entities *
}
entity BankAccount {
name String required,
balance BigDecimal required
}
entity Label {
label String required minlength(3)
}
entity Operation {
date Instant required,
description String,
amount BigDecimal required unique
}
paginate Operation with infinite-scroll
Then, run:
jhipster-quarkus jdl app.jdl
When it's finished generating, find and replace com.github.cloudyrock
with io.mongock
and change the bom version to 5.1.6:
<mongock-bom.version>5.1.6</mongock-bom.version>
Behaviour
Expected behavior: I'd expect a migration path from 4 to 5.
Actual behavior: MongockAnnotationProcessor
is not found.
How often the bug happens: No solution yet.
Link to repository using Mongock
https://github.com/vishal423/generator-jhipster-quarkus/tree/upgrade-dependencies
Hello @mraible , about the first question, MongockStandalone
builder provides the method addMigrationScanPackage
which receives the package where you have your ChangeUnit
classes (previous ChangeLog
classes).
So, could you try this:
.addMigrationScanPackage("io.github.jhipster.sample.config.dbmigrations")
instead of this:
.addMigrationClasses(changeLogs)
About how to migrate ChangeLog/ChangeSet classes to ChangeUnit, I'd recommend you to view our documentation and examples. Here are the links:
Documentation - Migrate from version 4 to 5 - ChangeUnits
Sample project - Mongock Standalone with MongoDB
Let me know if it works for you.
Thanks for using Mongock!
@osantana85 Using addMigrationScanPackage()
will solve most of my issue. Is there a way to get the changelogs from the builder? I need it to add native support to Quarkus (I think):
@AutomaticFeature
private static class NativeSupport implements Feature {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
changeLogs.forEach(clazz -> {
RuntimeReflection.register(clazz);
RuntimeReflection.register(clazz.getConstructors());
RuntimeReflection.register(clazz.getMethods());
});
}
}
@mraible in that case, you can use ChangeLog.class
directly, this way:
new Reflections("io.github.jhipster.sample.config.dbmigrations").getTypesAnnotatedWith(ChangeLog.class).stream()
If you migrate to ChangeUnit.class
, you'll have to take it into account, to use both annotation classes.
Thank you! I'll close this issue since you solved my problems.