Skip to content

Commit

Permalink
Merge pull request #14960 from stuartwdouglas/testcontainers-demo
Browse files Browse the repository at this point in the history
DevServices Support
  • Loading branch information
geoand authored Feb 24, 2021
2 parents a9b7a96 + 88172b7 commit 5116e62
Show file tree
Hide file tree
Showing 89 changed files with 2,620 additions and 173 deletions.
39 changes: 39 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
<log4j-jboss-logmanager.version>1.2.0.Final</log4j-jboss-logmanager.version>
<avro.version>1.10.0</avro.version>
<jacoco.version>0.8.6</jacoco.version>
<testcontainers.version>1.15.2</testcontainers.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -322,6 +323,14 @@
<scope>import</scope>
</dependency>

<!-- Testcontainers, imported as BOM -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Quarkus core -->

<dependency>
Expand Down Expand Up @@ -517,6 +526,11 @@
<artifactId>quarkus-datasource-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-datasource-deployment-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-datasource</artifactId>
Expand All @@ -527,6 +541,31 @@
<artifactId>quarkus-datasource-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-postgresql</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-h2</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-mysql</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-mariadb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-derby</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client-common</artifactId>
Expand Down
2 changes: 0 additions & 2 deletions build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -485,14 +485,12 @@
<exclude>io.rest-assured:*</exclude>
<exclude>org.assertj:*</exclude>
<exclude>org.junit.jupiter:*</exclude>
<exclude>org.testcontainers:*</exclude>
</excludes>
<includes>
<include>io.quarkus:quarkus-test-*:*:*:test</include>
<include>io.rest-assured:*:*:*:test</include>
<include>org.assertj:*:*:*:test</include>
<include>org.junit.jupiter:*:*:*:test</include>
<include>org.testcontainers:*:*:*:test</include>
</includes>
<message>Found test dependencies with wrong scope:</message>
</bannedDependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.jboss.logmanager.EmbeddedConfigurator;
import org.objectweb.asm.Opcodes;

import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
import io.quarkus.deployment.annotations.BuildProducer;
Expand All @@ -22,6 +23,7 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.ConsoleFormatterBannerBuildItem;
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LogCategoryBuildItem;
import io.quarkus.deployment.builditem.LogConsoleFormatBuildItem;
import io.quarkus.deployment.builditem.LogHandlerBuildItem;
Expand All @@ -44,10 +46,14 @@
import io.quarkus.gizmo.MethodCreator;
import io.quarkus.gizmo.MethodDescriptor;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.configuration.ConfigInstantiator;
import io.quarkus.runtime.logging.CategoryBuildTimeConfig;
import io.quarkus.runtime.logging.CleanupFilterConfig;
import io.quarkus.runtime.logging.InheritableLevel;
import io.quarkus.runtime.logging.LogBuildTimeConfig;
import io.quarkus.runtime.logging.LogCleanupFilterElement;
import io.quarkus.runtime.logging.LogConfig;
import io.quarkus.runtime.logging.LogMetricsHandlerRecorder;
import io.quarkus.runtime.logging.LoggingSetupRecorder;
Expand Down Expand Up @@ -124,7 +130,9 @@ void miscSetup(
LoggingSetupBuildItem setupLoggingRuntimeInit(LoggingSetupRecorder recorder, LogConfig log, LogBuildTimeConfig buildLog,
List<LogHandlerBuildItem> handlerBuildItems,
List<NamedLogHandlersBuildItem> namedHandlerBuildItems, List<LogConsoleFormatBuildItem> consoleFormatItems,
Optional<ConsoleFormatterBannerBuildItem> possibleBannerBuildItem) {
Optional<ConsoleFormatterBannerBuildItem> possibleBannerBuildItem,
LaunchModeBuildItem launchModeBuildItem,
List<LogCleanupFilterBuildItem> logCleanupFilters) {
final List<RuntimeValue<Optional<Handler>>> handlers = handlerBuildItems.stream()
.map(LogHandlerBuildItem::getHandlerValue)
.collect(Collectors.toList());
Expand All @@ -142,6 +150,26 @@ LoggingSetupBuildItem setupLoggingRuntimeInit(LoggingSetupRecorder recorder, Log
recorder.initializeLogging(log, buildLog, handlers, namedHandlers,
consoleFormatItems.stream().map(LogConsoleFormatBuildItem::getFormatterValue).collect(Collectors.toList()),
possibleSupplier);
if (launchModeBuildItem.getLaunchMode() != LaunchMode.NORMAL) {
LogConfig logConfig = new LogConfig();
ConfigInstantiator.handleObject(logConfig);
for (LogCleanupFilterBuildItem i : logCleanupFilters) {
CleanupFilterConfig value = new CleanupFilterConfig();
LogCleanupFilterElement filterElement = i.getFilterElement();
value.ifStartsWith = filterElement.getMessageStarts();
value.targetLevel = filterElement.getTargetLevel() == null ? org.jboss.logmanager.Level.DEBUG
: filterElement.getTargetLevel();
logConfig.filters.put(filterElement.getLoggerName(), value);
}
LoggingSetupRecorder.initializeBuildTimeLogging(logConfig, buildLog);
((QuarkusClassLoader) Thread.currentThread().getContextClassLoader()).addCloseTask(new Runnable() {
@Override
public void run() {
InitialConfigurator.DELAYED_HANDLER.buildTimeComplete();
}
});
}

return new LoggingSetupBuildItem();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.jboss.logging.Logger;
import org.jboss.logmanager.handlers.DelayedHandler;

import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.bootstrap.logging.QuarkusDelayedHandler;
import io.quarkus.bootstrap.runner.Timing;
import io.quarkus.builder.Version;
import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
Expand Down Expand Up @@ -288,13 +288,14 @@ void build(List<StaticBytecodeRecorderBuildItem> staticInitTasks,

// an exception was thrown before logging was actually setup, we simply dump everything to the console
ResultHandle delayedHandler = cb
.readStaticField(FieldDescriptor.of(InitialConfigurator.class, "DELAYED_HANDLER", DelayedHandler.class));
ResultHandle isActivated = cb.invokeVirtualMethod(ofMethod(DelayedHandler.class, "isActivated", boolean.class),
.readStaticField(FieldDescriptor.of(InitialConfigurator.class, "DELAYED_HANDLER", QuarkusDelayedHandler.class));
ResultHandle isActivated = cb.invokeVirtualMethod(ofMethod(QuarkusDelayedHandler.class, "isActivated", boolean.class),
delayedHandler);
BytecodeCreator isActivatedFalse = cb.ifNonZero(isActivated).falseBranch();
ResultHandle handlersArray = isActivatedFalse.newArray(Handler.class, 1);
isActivatedFalse.writeArrayValue(handlersArray, 0, isActivatedFalse.newInstance(ofConstructor(ConsoleHandler.class)));
isActivatedFalse.invokeVirtualMethod(ofMethod(DelayedHandler.class, "setHandlers", Handler[].class, Handler[].class),
isActivatedFalse.invokeVirtualMethod(
ofMethod(QuarkusDelayedHandler.class, "setHandlers", Handler[].class, Handler[].class),
delayedHandler, handlersArray);
isActivatedFalse.breakScope();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.quarkus.runner.bootstrap;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -13,6 +15,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
Expand Down Expand Up @@ -132,6 +135,55 @@ public AugmentActionImpl(CuratedApplication curatedApplication, List<Consumer<Bu
this.devModeType = devModeType;
}

@Override
public void performCustomBuild(String resultHandler, Object context, String... finalOutputs) {
ClassLoader classLoader = curatedApplication.createDeploymentClassLoader();
Class<? extends BuildItem>[] targets = Arrays.stream(finalOutputs)
.map(new Function<String, Class<? extends BuildItem>>() {
@Override
public Class<? extends BuildItem> apply(String s) {
try {
return (Class<? extends BuildItem>) Class.forName(s, false, classLoader);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}).toArray(Class[]::new);
BuildResult result = runAugment(true, Collections.emptySet(), null, classLoader, targets);

String debugSourcesDir = BootstrapDebug.DEBUG_SOURCES_DIR;
if (debugSourcesDir != null) {
for (GeneratedClassBuildItem i : result.consumeMulti(GeneratedClassBuildItem.class)) {
try {
if (i.getSource() != null) {
File debugPath = new File(debugSourcesDir);
if (!debugPath.exists()) {
debugPath.mkdir();
}
File sourceFile = new File(debugPath, i.getName() + ".zig");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), i.getSource().getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE);
log.infof("Wrote source: %s", sourceFile.getAbsolutePath());
} else {
log.infof("Source not available: %s", i.getName());
}
} catch (Exception t) {
log.errorf(t, "Failed to write debug source file: %s", i.getName());
}
}
}
try {
BiConsumer<Object, BuildResult> consumer = (BiConsumer<Object, BuildResult>) Class
.forName(resultHandler, false, classLoader)
.getConstructor().newInstance();
consumer.accept(context, result);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException
| InvocationTargetException e) {
throw new RuntimeException(e);
}
}

@Override
public AugmentResult createProductionApplication() {
if (launchMode != LaunchMode.NORMAL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.logging.Handler;

import org.jboss.logmanager.LogContext;
import org.jboss.logmanager.handlers.DelayedHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -13,6 +12,7 @@
import com.oracle.svm.core.annotate.TargetClass;

import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.bootstrap.logging.QuarkusDelayedHandler;

/**
*/
Expand All @@ -38,7 +38,7 @@ public static Logger getLogger(Class<?> clazz) {
final class Target_io_quarkus_runtime_logging_InitialConfigurator {
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias)
@Alias
public static DelayedHandler DELAYED_HANDLER = new DelayedHandler();
public static QuarkusDelayedHandler DELAYED_HANDLER = new QuarkusDelayedHandler();
}

@TargetClass(java.util.logging.Logger.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ public class CleanupFilterConfig {
* The message starts to match
*/
@ConfigItem(defaultValue = "inherit")
List<String> ifStartsWith;
public List<String> ifStartsWith;

/**
* The new log level for the filtered message, defaults to DEBUG
*/
@ConfigItem(defaultValue = "DEBUG")
Level targetLevel;
public Level targetLevel;
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,65 @@ public void initializeLogging(LogConfig config, LogBuildTimeConfig buildConfig,
InitialConfigurator.DELAYED_HANDLER.setHandlers(handlers.toArray(EmbeddedConfigurator.NO_HANDLERS));
}

private Level getLogLevel(String categoryName, CategoryConfig categoryConfig, Map<String, CategoryConfig> categories,
public static void initializeBuildTimeLogging(LogConfig config, LogBuildTimeConfig buildConfig) {

final Map<String, CategoryConfig> categories = config.categories;
final LogContext logContext = LogContext.getLogContext();
final Logger rootLogger = logContext.getLogger("");

rootLogger.setLevel(config.level);

ErrorManager errorManager = new OnlyOnceErrorManager();
final Map<String, CleanupFilterConfig> filters = config.filters;
List<LogCleanupFilterElement> filterElements = new ArrayList<>(filters.size());
for (Entry<String, CleanupFilterConfig> entry : filters.entrySet()) {
filterElements.add(
new LogCleanupFilterElement(entry.getKey(), entry.getValue().targetLevel, entry.getValue().ifStartsWith));
}

final ArrayList<Handler> handlers = new ArrayList<>(3);

if (config.console.enable) {
final Handler consoleHandler = configureConsoleHandler(config.console, errorManager, filterElements,
Collections.emptyList(), new RuntimeValue<>(Optional.empty()));
errorManager = consoleHandler.getErrorManager();
handlers.add(consoleHandler);
}

Map<String, Handler> namedHandlers = createNamedHandlers(config, Collections.emptyList(), errorManager, filterElements);

for (Map.Entry<String, CategoryConfig> entry : categories.entrySet()) {
final CategoryBuildTimeConfig buildCategory = isSubsetOf(entry.getKey(), buildConfig.categories);
final Level logLevel = getLogLevel(entry.getKey(), entry.getValue(), categories, buildConfig.minLevel);
final Level minLogLevel = buildCategory == null
? buildConfig.minLevel
: buildCategory.minLevel.getLevel();

if (logLevel.intValue() < minLogLevel.intValue()) {
log.warnf("Log level %s for category '%s' set below minimum logging level %s, promoting it to %s", logLevel,
entry.getKey(), minLogLevel, minLogLevel);

entry.getValue().level = InheritableLevel.of(minLogLevel.toString());
}
}

for (Map.Entry<String, CategoryConfig> entry : categories.entrySet()) {
final String name = entry.getKey();
final Logger categoryLogger = logContext.getLogger(name);
final CategoryConfig categoryConfig = entry.getValue();
if (!categoryConfig.level.isInherited()) {
categoryLogger.setLevel(categoryConfig.level.getLevel());
}
categoryLogger.setUseParentHandlers(categoryConfig.useParentHandlers);
if (categoryConfig.handlers.isPresent()) {
addNamedHandlersToCategory(categoryConfig, namedHandlers, categoryLogger, errorManager);
}
}
InitialConfigurator.DELAYED_HANDLER.setAutoFlush(false);
InitialConfigurator.DELAYED_HANDLER.setBuildTimeHandlers(handlers.toArray(EmbeddedConfigurator.NO_HANDLERS));
}

private static Level getLogLevel(String categoryName, CategoryConfig categoryConfig, Map<String, CategoryConfig> categories,
Level rootMinLevel) {
if (Objects.isNull(categoryConfig))
return rootMinLevel;
Expand All @@ -195,7 +253,7 @@ private Level getLogLevel(String categoryName, CategoryConfig categoryConfig, Ma
return getLogLevel(parent, categories.get(parent), categories, rootMinLevel);
}

private CategoryBuildTimeConfig isSubsetOf(String categoryName, Map<String, CategoryBuildTimeConfig> categories) {
private static CategoryBuildTimeConfig isSubsetOf(String categoryName, Map<String, CategoryBuildTimeConfig> categories) {
return categories.entrySet().stream()
.filter(buildCategoryEntry -> categoryName.startsWith(buildCategoryEntry.getKey()))
.map(Entry::getValue)
Expand Down Expand Up @@ -233,7 +291,7 @@ private static void addToNamedHandlers(Map<String, Handler> namedHandlers, Handl
namedHandlers.put(handlerName, handler);
}

private void addNamedHandlersToCategory(CategoryConfig categoryConfig, Map<String, Handler> namedHandlers,
private static void addNamedHandlersToCategory(CategoryConfig categoryConfig, Map<String, Handler> namedHandlers,
Logger categoryLogger,
ErrorManager errorManager) {
for (String categoryNamedHandler : categoryConfig.handlers.get()) {
Expand Down
Loading

0 comments on commit 5116e62

Please sign in to comment.