use of io.quarkus.deployment.builditem.DockerStatusBuildItem in project quarkus by quarkusio.
the class DevServicesKafkaProcessor method startKafka.
private RunningDevService startKafka(DockerStatusBuildItem dockerStatusBuildItem, KafkaDevServiceCfg config, LaunchModeBuildItem launchMode, boolean useSharedNetwork, Optional<Duration> timeout) {
if (!config.devServicesEnabled) {
// explicitly disabled
log.debug("Not starting dev services for Kafka, as it has been disabled in the config.");
return null;
}
// Check if kafka.bootstrap.servers is set
if (ConfigUtils.isPropertyPresent(KAFKA_BOOTSTRAP_SERVERS)) {
log.debug("Not starting dev services for Kafka, the kafka.bootstrap.servers is configured.");
return null;
}
// Verify that we have kafka channels without bootstrap.servers
if (!hasKafkaChannelWithoutBootstrapServers()) {
log.debug("Not starting dev services for Kafka, all the channels are configured.");
return null;
}
if (!dockerStatusBuildItem.isDockerAvailable()) {
log.warn("Docker isn't working, please configure the Kafka bootstrap servers property (kafka.bootstrap.servers).");
return null;
}
final Optional<ContainerAddress> maybeContainerAddress = kafkaContainerLocator.locateContainer(config.serviceName, config.shared, launchMode.getLaunchMode());
// Starting the broker
final Supplier<RunningDevService> defaultKafkaBrokerSupplier = () -> {
if (config.imageName.contains("strimzi")) {
StrimziKafkaContainer container = new StrimziKafkaContainer(config.imageName).withBrokerId(1).withKraft().waitForRunning();
ConfigureUtil.configureSharedNetwork(container, "kafka");
if (config.serviceName != null) {
container.withLabel(DevServicesKafkaProcessor.DEV_SERVICE_LABEL, config.serviceName);
}
if (config.fixedExposedPort != 0) {
container.withPort(config.fixedExposedPort);
}
timeout.ifPresent(container::withStartupTimeout);
container.start();
return new RunningDevService(Feature.KAFKA_CLIENT.getName(), container.getContainerId(), container::close, KAFKA_BOOTSTRAP_SERVERS, container.getBootstrapServers());
} else {
RedPandaKafkaContainer container = new RedPandaKafkaContainer(DockerImageName.parse(config.imageName), config.fixedExposedPort, launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT ? config.serviceName : null, useSharedNetwork, config.redpanda);
timeout.ifPresent(container::withStartupTimeout);
container.start();
return new RunningDevService(Feature.KAFKA_CLIENT.getName(), container.getContainerId(), container::close, KAFKA_BOOTSTRAP_SERVERS, container.getBootstrapServers());
}
};
return maybeContainerAddress.map(containerAddress -> new RunningDevService(Feature.KAFKA_CLIENT.getName(), containerAddress.getId(), null, KAFKA_BOOTSTRAP_SERVERS, containerAddress.getUrl())).orElseGet(defaultKafkaBrokerSupplier);
}
use of io.quarkus.deployment.builditem.DockerStatusBuildItem in project quarkus by quarkusio.
the class KeycloakDevServicesProcessor method startContainer.
private RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, BuildProducer<KeycloakDevServicesConfigBuildItem> keycloakBuildItemBuildProducer, boolean useSharedNetwork, Optional<Duration> timeout) {
if (!capturedDevServicesConfiguration.enabled) {
// explicitly disabled
LOG.debug("Not starting Dev Services for Keycloak as it has been disabled in the config");
return null;
}
if (!isOidcTenantEnabled()) {
LOG.debug("Not starting Dev Services for Keycloak as 'quarkus.oidc.tenant.enabled' is false");
return null;
}
if (ConfigUtils.isPropertyPresent(AUTH_SERVER_URL_CONFIG_KEY)) {
LOG.debug("Not starting Dev Services for Keycloak as 'quarkus.oidc.auth-server-url' has been provided");
return null;
}
if (ConfigUtils.isPropertyPresent(PROVIDER_CONFIG_KEY)) {
LOG.debug("Not starting Dev Services for Keycloak as 'quarkus.oidc.provider' has been provided");
return null;
}
if (!dockerStatusBuildItem.isDockerAvailable()) {
LOG.warn("Please configure 'quarkus.oidc.auth-server-url' or get a working docker instance");
return null;
}
final Optional<ContainerAddress> maybeContainerAddress = keycloakDevModeContainerLocator.locateContainer(capturedDevServicesConfiguration.serviceName, capturedDevServicesConfiguration.shared, LaunchMode.current());
String imageName = capturedDevServicesConfiguration.imageName;
DockerImageName dockerImageName = DockerImageName.parse(imageName).asCompatibleSubstituteFor(imageName);
final Supplier<RunningDevService> defaultKeycloakContainerSupplier = () -> {
QuarkusOidcContainer oidcContainer = new QuarkusOidcContainer(dockerImageName, capturedDevServicesConfiguration.port, useSharedNetwork, capturedDevServicesConfiguration.realmPath, capturedDevServicesConfiguration.serviceName, capturedDevServicesConfiguration.shared, capturedDevServicesConfiguration.javaOpts);
timeout.ifPresent(oidcContainer::withStartupTimeout);
oidcContainer.start();
String internalUrl = startURL(oidcContainer.getHost(), oidcContainer.getPort(), oidcContainer.keycloakX);
String hostUrl = oidcContainer.useSharedNetwork ? startURL("localhost", oidcContainer.fixedExposedPort.getAsInt(), oidcContainer.keycloakX) : null;
Map<String, String> configs = prepareConfiguration(keycloakBuildItemBuildProducer, internalUrl, hostUrl, oidcContainer.realmRep, oidcContainer.keycloakX);
return new RunningDevService(KEYCLOAK_CONTAINER_NAME, oidcContainer.getContainerId(), oidcContainer::close, configs);
};
return maybeContainerAddress.map(containerAddress -> {
// TODO: this probably needs to be addressed
Map<String, String> configs = prepareConfiguration(keycloakBuildItemBuildProducer, getSharedContainerUrl(containerAddress), getSharedContainerUrl(containerAddress), null, false);
return new RunningDevService(KEYCLOAK_CONTAINER_NAME, containerAddress.getId(), null, configs);
}).orElseGet(defaultKeycloakContainerSupplier);
}
use of io.quarkus.deployment.builditem.DockerStatusBuildItem in project quarkus by quarkusio.
the class DevServicesElasticsearchProcessor method startElasticsearch.
private DevServicesResultBuildItem.RunningDevService startElasticsearch(DockerStatusBuildItem dockerStatusBuildItem, ElasticsearchDevServicesBuildTimeConfig config, DevservicesElasticsearchBuildItemsConfiguration buildItemConfig, LaunchModeBuildItem launchMode, boolean useSharedNetwork, Optional<Duration> timeout) throws BuildException {
if (!config.enabled.orElse(true)) {
// explicitly disabled
log.debug("Not starting dev services for Elasticsearch, as it has been disabled in the config.");
return null;
}
for (String hostsConfigProperty : buildItemConfig.hostsConfigProperties) {
// Check if elasticsearch hosts property is set
if (ConfigUtils.isPropertyPresent(hostsConfigProperty)) {
log.debugf("Not starting dev services for Elasticsearch, the %s property is configured.", hostsConfigProperty);
return null;
}
}
if (!dockerStatusBuildItem.isDockerAvailable()) {
log.warnf("Docker isn't working, please configure the Elasticsearch hosts property (%s).", displayProperties(buildItemConfig.hostsConfigProperties));
return null;
}
// We only support ELASTIC container for now
if (buildItemConfig.distribution == DevservicesElasticsearchBuildItem.Distribution.OPENSEARCH) {
throw new BuildException("Dev services for Elasticsearch didn't support Opensearch", Collections.emptyList());
}
// with the image we are about to launch
if (buildItemConfig.version != null) {
String containerTag = config.imageName.substring(config.imageName.indexOf(':') + 1);
if (!containerTag.startsWith(buildItemConfig.version)) {
throw new BuildException("Dev services for Elasticsearch detected a version mismatch, container image is " + config.imageName + " but the configured version is " + buildItemConfig.version + ". Either configure a different image or disable dev services for Elasticsearch.", Collections.emptyList());
}
}
final Optional<ContainerAddress> maybeContainerAddress = elasticsearchContainerLocator.locateContainer(config.serviceName, config.shared, launchMode.getLaunchMode());
// Starting the server
final Supplier<DevServicesResultBuildItem.RunningDevService> defaultElasticsearchSupplier = () -> {
ElasticsearchContainer container = new ElasticsearchContainer(DockerImageName.parse(config.imageName));
ConfigureUtil.configureSharedNetwork(container, "elasticsearch");
if (config.serviceName != null) {
container.withLabel(DEV_SERVICE_LABEL, config.serviceName);
}
if (config.port.isPresent()) {
container.setPortBindings(List.of(config.port.get() + ":" + config.port.get()));
}
timeout.ifPresent(container::withStartupTimeout);
container.addEnv("ES_JAVA_OPTS", config.javaOpts);
// Disable security as else we would need to configure it correctly to avoid tons of WARNING in the log
container.addEnv("xpack.security.enabled", "false");
container.start();
return new DevServicesResultBuildItem.RunningDevService(Feature.ELASTICSEARCH_REST_CLIENT_COMMON.getName(), container.getContainerId(), container::close, buildPropertiesMap(buildItemConfig, container.getHttpHostAddress()));
};
return maybeContainerAddress.map(containerAddress -> new DevServicesResultBuildItem.RunningDevService(Feature.ELASTICSEARCH_REST_CLIENT_COMMON.getName(), containerAddress.getId(), null, buildPropertiesMap(buildItemConfig, containerAddress.getUrl()))).orElseGet(defaultElasticsearchSupplier);
}
use of io.quarkus.deployment.builditem.DockerStatusBuildItem 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);
}
use of io.quarkus.deployment.builditem.DockerStatusBuildItem in project quarkus by quarkusio.
the class DevServicesRedisProcessor method startContainer.
private RunningDevService startContainer(DockerStatusBuildItem dockerStatusBuildItem, String connectionName, DevServicesConfig devServicesConfig, LaunchMode launchMode, boolean useSharedNetwork, Optional<Duration> timeout) {
if (!devServicesConfig.enabled) {
// explicitly disabled
log.debug("Not starting devservices for " + (isDefault(connectionName) ? "default redis client" : connectionName) + " as it has been disabled in the config");
return null;
}
String configPrefix = getConfigPrefix(connectionName);
boolean needToStart = !ConfigUtils.isPropertyPresent(configPrefix + RedisConfig.HOSTS_CONFIG_NAME);
if (!needToStart) {
log.debug("Not starting devservices for " + (isDefault(connectionName) ? "default redis client" : connectionName) + " as hosts have been provided");
return null;
}
if (!dockerStatusBuildItem.isDockerAvailable()) {
log.warn("Please configure quarkus.redis.hosts for " + (isDefault(connectionName) ? "default redis client" : connectionName) + " or get a working docker instance");
return null;
}
DockerImageName dockerImageName = DockerImageName.parse(devServicesConfig.imageName.orElse(REDIS_6_ALPINE)).asCompatibleSubstituteFor(REDIS_6_ALPINE);
Supplier<RunningDevService> defaultRedisServerSupplier = () -> {
QuarkusPortRedisContainer redisContainer = new QuarkusPortRedisContainer(dockerImageName, devServicesConfig.port, launchMode == DEVELOPMENT ? devServicesConfig.serviceName : null, useSharedNetwork);
timeout.ifPresent(redisContainer::withStartupTimeout);
redisContainer.start();
String redisHost = REDIS_SCHEME + redisContainer.getHost() + ":" + redisContainer.getPort();
return new RunningDevService(Feature.REDIS_CLIENT.getName(), redisContainer.getContainerId(), redisContainer::close, configPrefix + RedisConfig.HOSTS_CONFIG_NAME, redisHost);
};
return redisContainerLocator.locateContainer(devServicesConfig.serviceName, devServicesConfig.shared, launchMode).map(containerAddress -> {
String redisUrl = REDIS_SCHEME + containerAddress.getUrl();
return new RunningDevService(Feature.REDIS_CLIENT.getName(), containerAddress.getId(), null, configPrefix + RedisConfig.HOSTS_CONFIG_NAME, redisUrl);
}).orElseGet(defaultRedisServerSupplier);
}
Aggregations