Skip to content

Commit

Permalink
Dev console commands and UI for listing dev services
Browse files Browse the repository at this point in the history
Exclude junit from keycloak test server dependency
  • Loading branch information
ozangunalp committed Jan 28, 2022
1 parent c5db541 commit f7f54b8
Show file tree
Hide file tree
Showing 68 changed files with 1,478 additions and 634 deletions.
10 changes: 10 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,16 @@
<artifactId>quarkus-devservices-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client-common</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
* Used to start and configure dev services, any processor starting dev services should produce these items.
*
* Quarkus will make sure the relevant settings are present in both JVM and native modes.
*
* @deprecated use {@link DevServicesResultBuildItem}
*/
@Deprecated
public final class DevServicesConfigResultBuildItem extends MultiBuildItem {

final String key;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.deployment.builditem;

import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import io.quarkus.builder.item.MultiBuildItem;

/**
* BuildItem for running dev services
* Combines injected configs to the application with container id (if it exists).
*
* Processors are expected to return this build item not only when the dev service first starts,
* but also if a running dev service already exists.
*
* {@link RunningDevService} helps to manage the lifecycle of the running dev service
*/
public final class DevServicesResultBuildItem extends MultiBuildItem {

private final String name;
private final String containerId;
private final Map<String, String> config;

public DevServicesResultBuildItem(String name, String containerId, Map<String, String> config) {
this.name = name;
this.containerId = containerId;
this.config = config;
}

public String getName() {
return name;
}

public String getContainerId() {
return containerId;
}

public Map<String, String> getConfig() {
return config;
}

public static class RunningDevService implements Closeable {

private final String name;
private final String containerId;
private final Map<String, String> config;
private final Closeable closeable;

private static Map<String, String> mapOf(String key, String value) {
Map<String, String> map = new HashMap<>();
map.put(key, value);
return map;
}

public RunningDevService(String name, String containerId, Closeable closeable, String key, String value) {
this(name, containerId, closeable, mapOf(key, value));
}

public RunningDevService(String name, String containerId, Closeable closeable, Map<String, String> config) {
this.name = name;
this.containerId = containerId;
this.closeable = closeable;
this.config = Collections.unmodifiableMap(config);
}

public String getName() {
return name;
}

public String getContainerId() {
return containerId;
}

public Map<String, String> getConfig() {
return config;
}

public Closeable getCloseable() {
return closeable;
}

public boolean isOwner() {
return closeable != null;
}

@Override
public void close() throws IOException {
this.closeable.close();
}

public DevServicesResultBuildItem toBuildItem() {
return new DevServicesResultBuildItem(name, containerId, config);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.quarkus.deployment.builditem.DevServicesConfigResultBuildItem;
import io.quarkus.deployment.builditem.DevServicesLauncherConfigResultBuildItem;
import io.quarkus.deployment.builditem.DevServicesNativeConfigResultBuildItem;
import io.quarkus.deployment.builditem.DevServicesResultBuildItem;
import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem;
import io.quarkus.deployment.builditem.ServiceStartBuildItem;

Expand All @@ -32,9 +33,13 @@ List<DevServicesConfigResultBuildItem> deprecated(List<DevServicesNativeConfigRe
@Produce(ServiceStartBuildItem.class)
DevServicesLauncherConfigResultBuildItem setup(BuildProducer<RunTimeConfigurationDefaultBuildItem> runtimeConfig,
List<DevServicesConfigResultBuildItem> devServicesConfigResultBuildItems,
List<DevServicesResultBuildItem> devServicesResultBuildItems,
CuratedApplicationShutdownBuildItem shutdownBuildItem) {
Map<String, String> newProperties = new HashMap<>(devServicesConfigResultBuildItems.stream().collect(
Collectors.toMap(DevServicesConfigResultBuildItem::getKey, DevServicesConfigResultBuildItem::getValue)));
for (DevServicesResultBuildItem resultBuildItem : devServicesResultBuildItems) {
newProperties.putAll(resultBuildItem.getConfig());
}
Config config = ConfigProvider.getConfig();
//check if there are existing already started dev services
//if there were no changes to the processors they don't produce config
Expand Down
13 changes: 13 additions & 0 deletions devtools/bom-descriptor-json/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client-deployment</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion extensions/apicurio-registry-avro/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-common</artifactId>
<artifactId>quarkus-devservices-deployment</artifactId>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;

import io.quarkus.deployment.Feature;
import io.quarkus.deployment.IsDockerWorking;
import io.quarkus.deployment.IsNormal;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CuratedApplicationShutdownBuildItem;
import io.quarkus.deployment.builditem.DevServicesConfigResultBuildItem;
import io.quarkus.deployment.builditem.DevServicesResultBuildItem;
import io.quarkus.deployment.builditem.DevServicesResultBuildItem.RunningDevService;
import io.quarkus.deployment.builditem.DevServicesSharedNetworkBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.console.ConsoleInstalledBuildItem;
Expand Down Expand Up @@ -50,56 +51,50 @@ public class DevServicesApicurioRegistryProcessor {
private static final ContainerLocator apicurioRegistryContainerLocator = new ContainerLocator(DEV_SERVICE_LABEL,
APICURIO_REGISTRY_PORT);

static volatile AutoCloseable closeable;
static volatile RunningDevService devService;
static volatile ApicurioRegistryDevServiceCfg cfg;
static volatile boolean first = true;

private final IsDockerWorking isDockerWorking = new IsDockerWorking(true);

@BuildStep(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class)
public void startApicurioRegistryDevService(LaunchModeBuildItem launchMode,
public DevServicesResultBuildItem startApicurioRegistryDevService(LaunchModeBuildItem launchMode,
ApicurioRegistryDevServicesBuildTimeConfig apicurioRegistryDevServices,
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem,
BuildProducer<DevServicesConfigResultBuildItem> devServicesConfiguration,
Optional<ConsoleInstalledBuildItem> consoleInstalledBuildItem,
CuratedApplicationShutdownBuildItem closeBuildItem,
LoggingSetupBuildItem loggingSetupBuildItem, GlobalDevServicesConfig devServicesConfig) {

ApicurioRegistryDevServiceCfg configuration = getConfiguration(apicurioRegistryDevServices);

if (closeable != null) {
if (devService != null) {
boolean restartRequired = !configuration.equals(cfg);
if (!restartRequired) {
return;
return devService.toBuildItem();
}
shutdownApicurioRegistry();
cfg = null;
}
ApicurioRegistry apicurioRegistry;
StartupLogCompressor compressor = new StartupLogCompressor(
(launchMode.isTest() ? "(test) " : "") + "Apicurio Registry Dev Services Starting:",
consoleInstalledBuildItem, loggingSetupBuildItem);
try {
apicurioRegistry = startApicurioRegistry(configuration, launchMode,
devService = startApicurioRegistry(configuration, launchMode,
!devServicesSharedNetworkBuildItem.isEmpty(), devServicesConfig.timeout);
if (apicurioRegistry == null) {
compressor.close();
return;
}
compressor.close();
} catch (Throwable t) {
compressor.closeAndDumpCaptured();
throw new RuntimeException(t);
}

cfg = configuration;
closeable = apicurioRegistry.getCloseable();
if (devService == null) {
return null;
}

devServicesConfiguration.produce(new DevServicesConfigResultBuildItem(
REGISTRY_URL_CONFIG, apicurioRegistry.getUrl() + "/apis/registry/v2"));
cfg = configuration;

if (apicurioRegistry.isOwner()) {
log.infof("Dev Services for Apicurio Registry started. The registry is available at %s", apicurioRegistry.getUrl());
if (devService.isOwner()) {
log.infof("Dev Services for Apicurio Registry started. The registry is available at %s", getRegistryUrlConfig());
}

// Configure the watch dog
Expand All @@ -108,31 +103,36 @@ public void startApicurioRegistryDevService(LaunchModeBuildItem launchMode,
Runnable closeTask = new Runnable() {
@Override
public void run() {
if (closeable != null) {
if (devService != null) {
shutdownApicurioRegistry();
}
first = true;
closeable = null;
devService = null;
cfg = null;
}
};
closeBuildItem.addCloseTask(closeTask, true);
}
return devService.toBuildItem();
}

private String getRegistryUrlConfig() {
return devService.getConfig().get(REGISTRY_URL_CONFIG) + "/apis/registry/v2";
}

private void shutdownApicurioRegistry() {
if (closeable != null) {
if (devService != null) {
try {
closeable.close();
devService.close();
} catch (Throwable e) {
log.error("Failed to stop Apicurio Registry", e);
} finally {
closeable = null;
devService = null;
}
}
}

private ApicurioRegistry startApicurioRegistry(ApicurioRegistryDevServiceCfg config, LaunchModeBuildItem launchMode,
private RunningDevService startApicurioRegistry(ApicurioRegistryDevServiceCfg config, LaunchModeBuildItem launchMode,
boolean useSharedNetwork, Optional<Duration> timeout) {
if (!config.devServicesEnabled) {
// explicitly disabled
Expand All @@ -157,7 +157,8 @@ private ApicurioRegistry startApicurioRegistry(ApicurioRegistryDevServiceCfg con

// Starting the broker
return apicurioRegistryContainerLocator.locateContainer(config.serviceName, config.shared, launchMode.getLaunchMode())
.map(containerAddress -> new ApicurioRegistry(containerAddress.getUrl(), null))
.map(containerAddress -> new RunningDevService(Feature.APICURIO_REGISTRY_AVRO.getName(),
containerAddress.getId(), null, REGISTRY_URL_CONFIG, containerAddress.getUrl()))
.orElseGet(() -> {
ApicurioRegistryContainer container = new ApicurioRegistryContainer(
DockerImageName.parse(config.imageName), config.fixedExposedPort,
Expand All @@ -166,7 +167,8 @@ private ApicurioRegistry startApicurioRegistry(ApicurioRegistryDevServiceCfg con
timeout.ifPresent(container::withStartupTimeout);
container.start();

return new ApicurioRegistry(container.getUrl(), container);
return new RunningDevService(Feature.APICURIO_REGISTRY_AVRO.getName(), container.getContainerId(),
container::close, REGISTRY_URL_CONFIG, container.getUrl());
});
}

Expand All @@ -193,28 +195,6 @@ private ApicurioRegistryDevServiceCfg getConfiguration(ApicurioRegistryDevServic
return new ApicurioRegistryDevServiceCfg(cfg);
}

private static class ApicurioRegistry {
private final String url;
private final AutoCloseable closeable;

public ApicurioRegistry(String url, AutoCloseable closeable) {
this.url = url;
this.closeable = closeable;
}

public String getUrl() {
return url;
}

public AutoCloseable getCloseable() {
return closeable;
}

public boolean isOwner() {
return closeable != null;
}
}

private static final class ApicurioRegistryDevServiceCfg {
private final boolean devServicesEnabled;
private final String imageName;
Expand Down
4 changes: 4 additions & 0 deletions extensions/apicurio-registry-avro/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Loading

0 comments on commit f7f54b8

Please sign in to comment.