-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
112 changed files
with
5,278 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>quarkus-flyway-multitenant-parent</artifactId> | ||
<groupId>io.quarkus</groupId> | ||
<version>999-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>quarkus-flyway-multitenant-deployment</artifactId> | ||
<name>Quarkus - Flyway - Multitenant - Deployment</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-core-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-arc-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-flyway-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-hibernate-orm-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-flyway-multitenant</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-vertx-http-dev-ui-tests</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-junit5-internal</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-test-h2</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-jdbc-h2-deployment</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-resteasy-jackson-deployment</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.rest-assured</groupId> | ||
<artifactId>rest-assured</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>default-compile</id> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-extension-processor</artifactId> | ||
<version>${project.version}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
<compilerArgs> | ||
<arg>-AlegacyConfigRoot=true</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
24 changes: 24 additions & 0 deletions
24
...nant/deployment/src/main/java/io/quarkus/flyway/multitenant/deployment/FlywayEnabled.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.quarkus.flyway.multitenant.deployment; | ||
|
||
import java.util.function.BooleanSupplier; | ||
|
||
import io.quarkus.flyway.multitenant.runtime.FlywayMultiTenantBuildTimeConfig; | ||
|
||
/** | ||
* Supplier that can be used to only run build steps | ||
* if the Flyway extension is enabled. | ||
*/ | ||
public class FlywayEnabled implements BooleanSupplier { | ||
|
||
private final FlywayMultiTenantBuildTimeConfig config; | ||
|
||
FlywayEnabled(FlywayMultiTenantBuildTimeConfig config) { | ||
this.config = config; | ||
} | ||
|
||
@Override | ||
public boolean getAsBoolean() { | ||
return config.enabled; | ||
} | ||
|
||
} |
14 changes: 14 additions & 0 deletions
14
...ava/io/quarkus/flyway/multitenant/deployment/FlywayMultiTenantAlwaysEnabledProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.quarkus.flyway.multitenant.deployment; | ||
|
||
import io.quarkus.deployment.Feature; | ||
import io.quarkus.deployment.annotations.BuildProducer; | ||
import io.quarkus.deployment.annotations.BuildStep; | ||
import io.quarkus.deployment.builditem.FeatureBuildItem; | ||
|
||
public class FlywayMultiTenantAlwaysEnabledProcessor { | ||
|
||
@BuildStep | ||
void build(BuildProducer<FeatureBuildItem> featureProducer) { | ||
featureProducer.produce(new FeatureBuildItem(Feature.FLYWAY_MULTITENANT)); | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
...main/java/io/quarkus/flyway/multitenant/deployment/FlywayMultiTenantCallbacksLocator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package io.quarkus.flyway.multitenant.deployment; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Modifier; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
|
||
import org.flywaydb.core.api.callback.Callback; | ||
import org.jboss.jandex.ClassInfo; | ||
import org.jboss.jandex.DotName; | ||
|
||
import io.quarkus.deployment.annotations.BuildProducer; | ||
import io.quarkus.deployment.builditem.CombinedIndexBuildItem; | ||
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; | ||
import io.quarkus.flyway.multitenant.runtime.FlywayMultiTenantBuildTimeConfig; | ||
|
||
/** | ||
* Logic to locate and process Flyway {@link Callback} classes. | ||
* This class also helps to keep the {@link FlywayMultiTenantProcessor} class as lean as possible to make it easier to maintain | ||
*/ | ||
class FlywayMultiTenantCallbacksLocator { | ||
private final Collection<String> persistenceUnitNames; | ||
private final FlywayMultiTenantBuildTimeConfig flywayBuildConfig; | ||
private final CombinedIndexBuildItem combinedIndexBuildItem; | ||
private final BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer; | ||
|
||
private FlywayMultiTenantCallbacksLocator(Collection<String> persistenceUnitNames, | ||
FlywayMultiTenantBuildTimeConfig flywayBuildConfig, | ||
CombinedIndexBuildItem combinedIndexBuildItem, BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer) { | ||
this.persistenceUnitNames = persistenceUnitNames; | ||
this.flywayBuildConfig = flywayBuildConfig; | ||
this.combinedIndexBuildItem = combinedIndexBuildItem; | ||
this.reflectiveClassProducer = reflectiveClassProducer; | ||
} | ||
|
||
public static FlywayMultiTenantCallbacksLocator with(Collection<String> persistenceUnitNames, | ||
FlywayMultiTenantBuildTimeConfig flywayBuildConfig, | ||
CombinedIndexBuildItem combinedIndexBuildItem, BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer) { | ||
return new FlywayMultiTenantCallbacksLocator(persistenceUnitNames, flywayBuildConfig, combinedIndexBuildItem, | ||
reflectiveClassProducer); | ||
} | ||
|
||
/** | ||
* Main logic to identify callbacks and return them to be processed by the {@link FlywayMultiTenantProcessor} | ||
* | ||
* @return Map containing the callbacks for each datasource. The datasource name is the map key | ||
* @exception ClassNotFoundException if the {@link Callback} class cannot be located by the Quarkus class loader | ||
* @exception InstantiationException if the {@link Callback} class represents an abstract class. | ||
* @exception InvocationTargetException if the underlying constructor throws an exception. | ||
* @exception IllegalAccessException if the {@link Callback} constructor is enforcing Java language access control | ||
* and the underlying constructor is inaccessible | ||
*/ | ||
public Map<String, Collection<Callback>> getCallbacks() | ||
throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException { | ||
final Map<String, Collection<Callback>> callbacks = new HashMap<>(); | ||
for (String dataSourceName : persistenceUnitNames) { | ||
final Collection<Callback> instances = callbacksForPersistenceUnit(dataSourceName); | ||
callbacks.put(dataSourceName, instances); | ||
} | ||
return callbacks; | ||
} | ||
|
||
/** | ||
* | ||
* Reads the configuration, instantiates the {@link Callback} class. Also, adds it to the reflective producer | ||
* | ||
* @return List of callbacks for the datasource | ||
* @exception ClassNotFoundException if the {@link Callback} class cannot be located by the Quarkus class loader | ||
* @exception InstantiationException if the {@link Callback} class represents an abstract class. | ||
* @exception InvocationTargetException if the underlying constructor throws an exception. | ||
* @exception IllegalAccessException if the {@link Callback} constructor is enforcing Java language access control | ||
* and the underlying constructor is inaccessible | ||
*/ | ||
private Collection<Callback> callbacksForPersistenceUnit(String persistenceUnitName) | ||
throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException { | ||
final Optional<List<String>> callbackConfig = flywayBuildConfig | ||
.getConfigForPersistenceUnitName(persistenceUnitName).callbacks; | ||
if (!callbackConfig.isPresent()) { | ||
return Collections.emptyList(); | ||
} | ||
final Collection<String> callbacks = callbackConfig.get(); | ||
final Collection<Callback> instances = new ArrayList<>(callbacks.size()); | ||
for (String callback : callbacks) { | ||
final ClassInfo clazz = combinedIndexBuildItem.getIndex().getClassByName(DotName.createSimple(callback)); | ||
Objects.requireNonNull(clazz, | ||
"Flyway callback not found, please verify the fully qualified name for the class: " + callback); | ||
if (Modifier.isAbstract(clazz.flags()) || !clazz.hasNoArgsConstructor()) { | ||
throw new IllegalArgumentException( | ||
"Invalid Flyway callback. It shouldn't be abstract and must have a default constructor"); | ||
} | ||
final Class<?> clazzType = Class.forName(callback, false, Thread.currentThread().getContextClassLoader()); | ||
final Callback instance = (Callback) clazzType.getConstructors()[0].newInstance(); | ||
instances.add(instance); | ||
reflectiveClassProducer | ||
.produce(ReflectiveClassBuildItem.builder(clazz.name().toString()).build()); | ||
} | ||
return instances; | ||
} | ||
} |
Oops, something went wrong.