use of io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem in project kogito-runtimes by kiegroup.
the class KogitoDevServicesProcessor method startTrustyServiceDevService.
@SuppressWarnings("unused")
@BuildStep(onlyIf = { GlobalDevServicesConfig.Enabled.class, IsDevelopment.class })
public void startTrustyServiceDevService(final DevServicesConfig devServicesConfig, final BuildProducer<SystemPropertyBuildItem> systemProperties, final BuildProducer<TrustyServiceAvailableBuildItem> trustyServiceAvailableBuildItemBuildProducer, final LaunchModeBuildItem launchMode, final KogitoBuildTimeConfig buildTimeConfig, final List<DevServicesSharedNetworkBuildItem> devServicesSharedNetwork, final Optional<ConsoleInstalledBuildItem> consoleInstalled, final CuratedApplicationShutdownBuildItem applicationShutdown, final LoggingSetupBuildItem loggingSetup) {
LOGGER.info("Docker Containers configuration...");
DockerClientFactory.lazyClient().listContainersCmd().exec().forEach(c -> {
LOGGER.debug("----> Image: " + c.getImage());
if (Objects.nonNull(c.getNames())) {
Arrays.stream(c.getNames()).forEach(n -> LOGGER.debug(String.format("----> Name: %s", n)));
}
if (Objects.nonNull(c.getLabels())) {
c.getLabels().forEach((key, value) -> LOGGER.debug(String.format("----> Label: [%s]=[%s]", key, value)));
}
LOGGER.debug("----> Ports: " + Arrays.stream(c.getPorts()).map(p -> p.getPrivatePort() + ">>" + p.getPublicPort()).collect(Collectors.joining(", ")));
LOGGER.debug("----> Network: " + (Objects.isNull(c.getNetworkSettings()) ? "" : c.getNetworkSettings().getNetworks().entrySet().stream().map(n -> String.format("%s=%s [%s]", n.getKey(), n.getValue(), n.getValue().getIpAddress())).collect(Collectors.joining(", "))));
});
final TrustyServiceDevServiceConfig configuration = getConfiguration(buildTimeConfig);
if (closeable != null) {
boolean shouldShutdown = !configuration.equals(cfg);
if (!shouldShutdown) {
// Signal the service is (still) available when DevServices may have restarted but the service not
trustyServiceAvailableBuildItemBuildProducer.produce(new TrustyServiceAvailableBuildItem());
return;
}
shutdownTrustyService();
cfg = null;
}
final StartupLogCompressor compressor = new StartupLogCompressor((launchMode.isTest() ? "(test) " : "") + "Kogito TrustyService DevService starting:", consoleInstalled, loggingSetup);
TrustyServiceInstance trustyService = null;
try {
trustyService = startTrustyService(configuration, devServicesConfig, launchMode, !devServicesSharedNetwork.isEmpty());
if (trustyService != null) {
// Signal the service is available
trustyServiceAvailableBuildItemBuildProducer.produce(new TrustyServiceAvailableBuildItem());
closeable = trustyService.getCloseable();
}
compressor.close();
} catch (Throwable t) {
compressor.closeAndDumpCaptured();
throw new RuntimeException("Failed to start Kogito TrustyService DevServices", t);
}
// Discover TrustyService container
LOGGER.info("Discovering TrustyService instance...");
DockerClientFactory.lazyClient().listContainersCmd().exec().stream().filter(container -> isTrustyServiceImage(container, configuration)).findFirst().ifPresent(container -> {
Optional<Integer> port = Optional.empty();
Optional<String> ipAddress = Optional.empty();
final ContainerPort[] containerPorts = container.getPorts();
final ContainerNetworkSettings networkSettings = container.getNetworkSettings();
if (Objects.nonNull(containerPorts)) {
port = Arrays.stream(containerPorts).map(ContainerPort::getPrivatePort).filter(Objects::nonNull).findFirst();
}
if (Objects.nonNull(networkSettings)) {
ipAddress = networkSettings.getNetworks().values().stream().map(ContainerNetwork::getIpAddress).filter(Objects::nonNull).findFirst();
}
LOGGER.debug(String.format("[TrustyService] Private Port: %s", port.orElse(0)));
LOGGER.debug(String.format("[TrustyService] IP Address: %s", ipAddress.orElse("<None>")));
if (ipAddress.isPresent() && port.isPresent()) {
final String trustyServiceServer = String.format("http://%s:%s", ipAddress.get(), port.get());
LOGGER.debug(String.format("Setting System Property '%s' to '%s'", KOGITO_TRUSTY_SERVICE, trustyServiceServer));
systemProperties.produce(new SystemPropertyBuildItem(KOGITO_TRUSTY_SERVICE, trustyServiceServer));
}
});
// Configure the watch dog
if (first) {
first = false;
final Runnable closeTask = () -> {
if (closeable != null) {
shutdownTrustyService();
}
first = true;
closeable = null;
cfg = null;
};
applicationShutdown.addCloseTask(closeTask, true);
}
cfg = configuration;
if (trustyService != null && trustyService.isOwner()) {
LOGGER.info("DevServices for Kogito TrustyService started at {}", trustyService.getUrl());
}
}
use of io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem in project quarkus by quarkusio.
the class QuarkusAugmentor method run.
public BuildResult run() throws Exception {
if (!JavaVersionUtil.isJava11OrHigher()) {
throw new IllegalStateException("Quarkus applications require Java 11 or higher to build");
}
long time = System.currentTimeMillis();
log.debug("Beginning Quarkus augmentation");
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
QuarkusBuildCloseablesBuildItem buildCloseables = new QuarkusBuildCloseablesBuildItem();
try {
Thread.currentThread().setContextClassLoader(deploymentClassLoader);
final BuildChainBuilder chainBuilder = BuildChain.builder();
chainBuilder.setClassLoader(deploymentClassLoader);
// provideCapabilities(chainBuilder);
// TODO: we load everything from the deployment class loader
// this allows the deployment config (application.properties) to be loaded, but in theory could result
// in additional stuff from the deployment leaking in, this is unlikely but has a bit of a smell.
ExtensionLoader.loadStepsFrom(deploymentClassLoader, buildSystemProperties == null ? new Properties() : buildSystemProperties, effectiveModel, launchMode, devModeType).accept(chainBuilder);
Thread.currentThread().setContextClassLoader(classLoader);
chainBuilder.loadProviders(classLoader);
chainBuilder.addInitial(QuarkusBuildCloseablesBuildItem.class).addInitial(ArchiveRootBuildItem.class).addInitial(ShutdownContextBuildItem.class).addInitial(RawCommandLineArgumentsBuildItem.class).addInitial(LaunchModeBuildItem.class).addInitial(LiveReloadBuildItem.class).addInitial(AdditionalApplicationArchiveBuildItem.class).addInitial(CuratedApplicationShutdownBuildItem.class).addInitial(BuildSystemTargetBuildItem.class).addInitial(AppModelProviderBuildItem.class);
for (Class<? extends BuildItem> i : finalResults) {
chainBuilder.addFinal(i);
}
for (Consumer<BuildChainBuilder> i : buildChainCustomizers) {
i.accept(chainBuilder);
}
if (launchMode.isDevOrTest()) {
chainBuilder.addFinal(RuntimeApplicationShutdownBuildItem.class);
}
final ArchiveRootBuildItem.Builder rootBuilder = ArchiveRootBuildItem.builder();
if (root != null) {
rootBuilder.addArchiveRoots(root);
}
rootBuilder.setExcludedFromIndexing(excludedFromIndexing);
BuildChain chain = chainBuilder.build();
BuildExecutionBuilder execBuilder = chain.createExecutionBuilder("main").produce(buildCloseables).produce(liveReloadBuildItem).produce(rootBuilder.build(buildCloseables)).produce(new ShutdownContextBuildItem()).produce(new RawCommandLineArgumentsBuildItem()).produce(new CuratedApplicationShutdownBuildItem((QuarkusClassLoader) deploymentClassLoader.getParent(), !liveReloadBuildItem.isLiveReload())).produce(new LaunchModeBuildItem(launchMode, devModeType == null ? Optional.empty() : Optional.of(devModeType), auxiliaryApplication, auxiliaryDevModeType, test)).produce(new BuildSystemTargetBuildItem(targetDir, baseName, rebuild, buildSystemProperties == null ? new Properties() : buildSystemProperties)).produce(new AppModelProviderBuildItem(effectiveModel));
for (PathCollection i : additionalApplicationArchives) {
execBuilder.produce(new AdditionalApplicationArchiveBuildItem(i));
}
BuildResult buildResult = execBuilder.execute();
String message = "Quarkus augmentation completed in " + (System.currentTimeMillis() - time) + "ms";
if (launchMode == LaunchMode.NORMAL) {
log.info(message);
} else {
// test and dev mode already report the total startup time, no need to add noise to the logs
log.debug(message);
}
return buildResult;
} finally {
try {
ConfigProviderResolver.instance().releaseConfig(ConfigProviderResolver.instance().getConfig(deploymentClassLoader));
} catch (Exception ignore) {
}
if (deploymentClassLoader instanceof Closeable) {
((Closeable) deploymentClassLoader).close();
}
Thread.currentThread().setContextClassLoader(originalClassLoader);
buildCloseables.close();
}
}
use of io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem in project quarkus by quarkusio.
the class DevServicesDatasourceProcessor method launchDatabases.
@BuildStep(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class)
DevServicesDatasourceResultBuildItem launchDatabases(CurateOutcomeBuildItem curateOutcomeBuildItem, DockerStatusBuildItem dockerStatusBuildItem, List<DefaultDataSourceDbKindBuildItem> installedDrivers, List<DevServicesDatasourceProviderBuildItem> devDBProviders, DataSourcesBuildTimeConfig dataSourceBuildTimeConfig, LaunchModeBuildItem launchMode, List<DevServicesDatasourceConfigurationHandlerBuildItem> configurationHandlerBuildItems, BuildProducer<DevServicesResultBuildItem> devServicesResultBuildItemBuildProducer, Optional<ConsoleInstalledBuildItem> consoleInstalledBuildItem, CuratedApplicationShutdownBuildItem closeBuildItem, LoggingSetupBuildItem loggingSetupBuildItem, GlobalDevServicesConfig globalDevServicesConfig) {
// if not and the DB's have already started we just return
if (databases != null) {
boolean restartRequired = false;
if (!restartRequired) {
for (Map.Entry<String, String> entry : cachedProperties.entrySet()) {
if (!Objects.equals(entry.getValue(), trim(ConfigProvider.getConfig().getOptionalValue(entry.getKey(), String.class).orElse(null)))) {
restartRequired = true;
break;
}
}
}
if (!restartRequired) {
// devservices properties may have been added
for (var name : ConfigProvider.getConfig().getPropertyNames()) {
if (name.startsWith("quarkus.datasource.") && name.contains(".devservices.") && !cachedProperties.containsKey(name)) {
restartRequired = true;
break;
}
}
}
if (!restartRequired) {
for (RunningDevService database : databases) {
devServicesResultBuildItemBuildProducer.produce(database.toBuildItem());
}
// keep the previous behaviour of producing DevServicesDatasourceResultBuildItem only when the devservice first starts.
return null;
}
for (Closeable i : databases) {
try {
i.close();
} catch (Throwable e) {
log.error("Failed to stop database", e);
}
}
databases = null;
cachedProperties = null;
}
DevServicesDatasourceResultBuildItem.DbResult defaultResult;
Map<String, DevServicesDatasourceResultBuildItem.DbResult> namedResults = new HashMap<>();
// now we need to figure out if we need to launch some databases
// note that because we run in dev and test mode only we know the runtime
// config at build time, as they both execute in the same JVM
// to keep things simpler for now we are only going to support this for the default datasource
// support for named datasources will come later
Map<String, String> propertiesMap = new HashMap<>();
List<RunningDevService> runningDevServices = new ArrayList<>();
Map<String, List<DevServicesDatasourceConfigurationHandlerBuildItem>> configHandlersByDbType = configurationHandlerBuildItems.stream().collect(Collectors.toMap(DevServicesDatasourceConfigurationHandlerBuildItem::getDbKind, Collections::singletonList, (configurationHandlerBuildItems1, configurationHandlerBuildItems2) -> {
List<DevServicesDatasourceConfigurationHandlerBuildItem> ret = new ArrayList<>();
ret.addAll(configurationHandlerBuildItems1);
ret.addAll(configurationHandlerBuildItems2);
return ret;
}));
Map<String, DevServicesDatasourceProvider> devDBProviderMap = devDBProviders.stream().collect(Collectors.toMap(DevServicesDatasourceProviderBuildItem::getDatabase, DevServicesDatasourceProviderBuildItem::getDevServicesProvider));
RunningDevService defaultDevService = startDevDb(null, curateOutcomeBuildItem, installedDrivers, !dataSourceBuildTimeConfig.namedDataSources.isEmpty(), devDBProviderMap, dataSourceBuildTimeConfig.defaultDataSource, configHandlersByDbType, propertiesMap, dockerStatusBuildItem, launchMode.getLaunchMode(), consoleInstalledBuildItem, loggingSetupBuildItem, globalDevServicesConfig);
if (defaultDevService != null) {
runningDevServices.add(defaultDevService);
}
defaultResult = toDbResult(defaultDevService);
for (Map.Entry<String, DataSourceBuildTimeConfig> entry : dataSourceBuildTimeConfig.namedDataSources.entrySet()) {
RunningDevService namedDevService = startDevDb(entry.getKey(), curateOutcomeBuildItem, installedDrivers, true, devDBProviderMap, entry.getValue(), configHandlersByDbType, propertiesMap, dockerStatusBuildItem, launchMode.getLaunchMode(), consoleInstalledBuildItem, loggingSetupBuildItem, globalDevServicesConfig);
if (namedDevService != null) {
runningDevServices.add(namedDevService);
namedResults.put(entry.getKey(), toDbResult(namedDevService));
}
}
if (first) {
first = false;
Runnable closeTask = new Runnable() {
@Override
public void run() {
if (databases != null) {
for (Closeable i : databases) {
try {
i.close();
} catch (Throwable t) {
log.error("Failed to stop database", t);
}
}
}
first = true;
databases = null;
cachedProperties = null;
}
};
closeBuildItem.addCloseTask(closeTask, true);
}
databases = runningDevServices;
cachedProperties = propertiesMap;
for (RunningDevService database : databases) {
devServicesResultBuildItemBuildProducer.produce(database.toBuildItem());
}
return new DevServicesDatasourceResultBuildItem(defaultResult, namedResults);
}
Aggregations