Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void reallyStart(DevServicesResultBuildItem request, List<DevServicesCus
startable.start();

RunningService service = new RunningService(request.getName(), request.getDescription(),
request.getConfig(startable), startable.getContainerId(), startable);
request.getConfig(startable), request.getOverrideConfig(startable), startable.getContainerId(), startable);
this.addRunningService(request.getName(), request.getServiceName(), request.getServiceConfig(), service);

compressor.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
Expand Down Expand Up @@ -77,6 +78,7 @@ public final class DevServicesResultBuildItem extends MultiBuildItem {
* A map of application config that is dependent on the started service
*/
private final Map<String, Function<Startable, String>> applicationConfigProvider;
private final Set<String> highPriorityConfig;

public static DiscoveredServiceBuilder discovered() {
return new DiscoveredServiceBuilder();
Expand Down Expand Up @@ -106,6 +108,7 @@ public DevServicesResultBuildItem(String name, String description, String contai
this.serviceName = null;
this.serviceConfig = null;
this.applicationConfigProvider = null;
this.highPriorityConfig = null;
this.startableSupplier = null;
this.postStartAction = null;
}
Expand All @@ -121,7 +124,7 @@ public DevServicesResultBuildItem(String name,
Map<String, String> config,
Supplier<Startable> startableSupplier,
Consumer<Startable> postStartAction,
Map<String, Function<Startable, String>> applicationConfigProvider) {
Map<String, Function<Startable, String>> applicationConfigProvider, Set<String> highPriorityConfig) {
this.name = name;
this.description = description;
this.containerId = null;
Expand All @@ -131,6 +134,7 @@ public DevServicesResultBuildItem(String name,
this.startableSupplier = startableSupplier;
this.postStartAction = postStartAction;
this.applicationConfigProvider = applicationConfigProvider;
this.highPriorityConfig = highPriorityConfig;
}

public String getName() {
Expand Down Expand Up @@ -175,6 +179,7 @@ public Map<String, Function<Startable, String>> getApplicationConfigProvider() {

public Map<String, String> getConfig(Startable startable) {
SupplierMap<String, String> map = new SupplierMap<>();
// To make sure static config does make it into a config source, include it here
if (config != null && !config.isEmpty()) {
map.putAll(config);
}
Expand All @@ -186,6 +191,22 @@ public Map<String, String> getConfig(Startable startable) {
return map;
}

/**
* @deprecated Subject to changes due to <a href="https://github.com/quarkusio/quarkus/pull/51209">#51209</a>
*/
@Deprecated(forRemoval = true)
public Map<String, String> getOverrideConfig(Startable startable) {

SupplierMap<String, String> map = new SupplierMap<>();

if (highPriorityConfig != null) {
for (String key : highPriorityConfig) {
map.put(key, () -> applicationConfigProvider.get(key).apply(startable));
}
}
return map;
}

public static class DiscoveredServiceBuilder {
private String name;
private String containerId;
Expand Down Expand Up @@ -226,10 +247,8 @@ public DevServicesResultBuildItem build() {
}

public static class OwnedServiceBuilder<T extends Startable> {

private static final String IO_QUARKUS_DEVSERVICES_CONFIG_BUILDER_CLASS = "io.quarkus.devservice.runtime.config.DevServicesConfigBuilder";
private static final boolean CONFIG_BUILDER_AVAILABLE = isClassAvailable(
IO_QUARKUS_DEVSERVICES_CONFIG_BUILDER_CLASS);
private static final boolean CONFIG_BUILDER_AVAILABLE = isClassAvailable(IO_QUARKUS_DEVSERVICES_CONFIG_BUILDER_CLASS);

private String name;
private String description;
Expand All @@ -239,6 +258,7 @@ public static class OwnedServiceBuilder<T extends Startable> {
private Supplier<? extends Startable> startableSupplier;
private Consumer<? extends Startable> postStartAction;
private Map<String, Function<Startable, String>> applicationConfigProvider;
private Set<String> highPriorityConfig;

public OwnedServiceBuilder<T> name(String name) {
this.name = name;
Expand Down Expand Up @@ -286,6 +306,15 @@ public OwnedServiceBuilder<T> postStartHook(Consumer<T> postStartAction) {
return this;
}

/**
* @deprecated Subject to changes due to <a href="https://github.com/quarkusio/quarkus/pull/51209">#51209</a>
*/
@Deprecated(forRemoval = true)
public OwnedServiceBuilder<T> highPriorityConfig(Set<String> highPriorityConfig) {
this.highPriorityConfig = highPriorityConfig;
return this;
}

/**
* Provides config to inject into the config system. If you've got values that don't change, use config(), and if you've
* got values that you'll only know after starting the container, use configProvider() and provide a map of
Expand All @@ -306,7 +335,7 @@ public DevServicesResultBuildItem build() {
return new DevServicesResultBuildItem(name, description, serviceName, serviceConfig, config,
(Supplier<Startable>) startableSupplier,
(Consumer<Startable>) postStartAction,
applicationConfigProvider);
applicationConfigProvider, highPriorityConfig);
}

private static boolean isClassAvailable(String className) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ public final class RunningService implements Closeable {
private final String feature;
private final String description;
private final Map<String, String> configs;
private final Map<String, String> overrideConfigs;
private final String containerId;
private final Closeable closeable;

public RunningService(String feature, String description, Map<String, String> configs, String containerId,
public RunningService(String feature, String description, Map<String, String> configs, Map<String, String> overrideConfig,
String containerId,
Closeable closeable) {
this.feature = feature;
this.description = description;
this.configs = configs;
this.overrideConfigs = overrideConfig;
this.containerId = containerId;
this.closeable = closeable;
}
Expand All @@ -45,8 +48,15 @@ public Map<String, String> configs() {
return configs;
}

/**
* @deprecated Subject to changes due to <a href="https://github.com/quarkusio/quarkus/pull/51209">#51209</a>
*/
@Deprecated(forRemoval = true)
public Map<String, String> overrideConfigs() {
return overrideConfigs;
}

public String containerId() {
return containerId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;

import io.quarkus.amazon.lambda.runtime.AmazonLambdaApi;
import io.quarkus.amazon.lambda.runtime.LambdaHotReplacementRecorder;
import io.quarkus.amazon.lambda.runtime.MockEventServer;
import io.quarkus.amazon.lambda.runtime.MockEventServerConfig;
import io.quarkus.deployment.Feature;
import io.quarkus.deployment.IsLiveReloadSupportedByLaunchMode;
import io.quarkus.deployment.IsProduction;
Expand Down Expand Up @@ -51,7 +54,7 @@ private boolean legacyTestingEnabled() {
@Produce(ServiceStartBuildItem.class)
@BuildStep(onlyIfNot = IsProduction.class) // This is required for testing so run it even if devservices.enabled=false
public void startEventServer(LaunchModeBuildItem launchModeBuildItem,
LambdaConfig config,
LambdaBuildConfig config,
Optional<EventServerOverrideBuildItem> override,
BuildProducer<DevServicesResultBuildItem> devServicePropertiesProducer) {
LaunchMode launchMode = launchModeBuildItem.getLaunchMode();
Expand All @@ -70,18 +73,17 @@ public void startEventServer(LaunchModeBuildItem launchModeBuildItem,
server = new MockEventServer();
}

int configuredPort = launchMode == LaunchMode.TEST ? config.mockEventServer().testPort()
: config.mockEventServer().devPort();
String portPropertySuffix = launchMode == LaunchMode.TEST ? "test-port" : "dev-port";
boolean isTest = launchMode == LaunchMode.TEST;
String portPropertySuffix = isTest ? "test-port" : "dev-port";
String propName = "quarkus.lambda.mock-event-server." + portPropertySuffix;

// No compose support, and no using of external services, so no need to discover existing services

DevServicesResultBuildItem buildItem = DevServicesResultBuildItem.owned().feature(Feature.AMAZON_LAMBDA)
.serviceName(Feature.AMAZON_LAMBDA.getName())
.serviceConfig(config)
.startable(() -> new StartableEventServer(
server, configuredPort))
.startable(() -> new StartableEventServer(server, propName, isTest))
.highPriorityConfig(Set.of(propName)) // Pass through the external config for the port, so that it can be overridden if it's an ephemeral port
.configProvider(
Map.of(propName, s -> String.valueOf(s.getExposedPort()),
AmazonLambdaApi.QUARKUS_INTERNAL_AWS_LAMBDA_TEST_API,
Expand All @@ -93,17 +95,26 @@ public void startEventServer(LaunchModeBuildItem launchModeBuildItem,
}

private static class StartableEventServer implements Startable {

private final MockEventServer server;
private final int configuredPort;
private final String propName;
private final boolean isTest;

public StartableEventServer(MockEventServer server, int configuredPort) {
public StartableEventServer(MockEventServer server, String propName, boolean isTest) {
this.server = server;
this.configuredPort = configuredPort;
this.propName = propName;
this.isTest = isTest;
}

@Override
public void start() {
// Technically, we shouldn't peek at the runtime config, but every dev service does it
// However, we won't get defaults, so we need to fill our own in
int port = isTest ? Integer.parseInt(MockEventServerConfig.TEST_PORT)
: Integer.parseInt(MockEventServerConfig.DEV_PORT);
int configuredPort = ConfigProvider.getConfig().getOptionalValue(propName, Integer.class)
.or(() -> Optional.of(port))
.get();

server.start(configuredPort);
log.debugf("Starting event server on port %d", configuredPort);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.amazon.lambda.deployment;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;

@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
@ConfigMapping(prefix = "quarkus.lambda")
public interface LambdaBuildConfig {

/**
* Configuration for the mock event server that is run
* in dev mode and test mode
*/
MockEventServerBuildConfig mockEventServer();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,11 @@
* Configuration for the mock event server that is run
* in dev mode and test mode
*/
public interface MockEventServerConfig {
public interface MockEventServerBuildConfig {
/**
* Setting to true will start event server even if quarkus.devservices.enabled=false
*/
@WithDefault("true")
boolean enabled();

/**
* Port to access mock event server in dev mode
*/
@WithDefault("8080")
int devPort();

/**
* Port to access mock event server in dev mode
*/
@WithDefault("8081")
int testPort();
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package io.quarkus.amazon.lambda.deployment;
package io.quarkus.amazon.lambda.runtime;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;

@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
@ConfigMapping(prefix = "quarkus.lambda")
public interface LambdaConfig {

Expand All @@ -13,4 +13,5 @@ public interface LambdaConfig {
* in dev mode and test mode
*/
MockEventServerConfig mockEventServer();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.quarkus.amazon.lambda.runtime;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

/**
* Configuration for the mock event server that is run
* in dev mode and test mode
*/
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
@ConfigMapping(prefix = "quarkus.lambda")
public interface MockEventServerConfig {
static final String DEV_PORT = "8080";
static final String TEST_PORT = "8081";

/**
* Port to access mock event server in dev mode
*/
@WithDefault(DEV_PORT)
int devPort();

/**
* Port to access mock event server in dev mode
*/
@WithDefault(TEST_PORT)
int testPort();
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,18 @@ DevServicesRegistryBuildItem devServicesRegistry(LaunchModeBuildItem launchMode,

// Because the devservices runtime module is new and the ecosystem needs time to catch up, don't die if the runtime module isn't available
@BuildStep(onlyIf = { IsRuntimeModuleAvailable.class })
public RunTimeConfigBuilderBuildItem registerDevResourcesConfigSource(
List<DevServicesResultBuildItem> devServicesRequestBuildItems) {
public void registerDevResourcesConfigSource(BuildProducer<RunTimeConfigBuilderBuildItem> runtimeConfigBuilders) {
// Once all the dev services are registered, we can share config
try {
// Use reflection, since we don't have an explicit dependency on the runtime module (because dependent extensions may not have that dependency)
Class<?> builderClass = Class
.forName(IO_QUARKUS_DEVSERVICES_CONFIG_BUILDER_CLASS);
return new RunTimeConfigBuilderBuildItem(builderClass);
runtimeConfigBuilders
.produce(new RunTimeConfigBuilderBuildItem(Class.forName(IO_QUARKUS_DEVSERVICES_CONFIG_BUILDER_CLASS)));
runtimeConfigBuilders.produce(new RunTimeConfigBuilderBuildItem(
Class.forName("io.quarkus.devservice.runtime.config.DevServicesOverrideConfigBuilder")));
} catch (ClassNotFoundException e) {
// Should never happen, because of the guard, as long as the runtime module is not a direct dependency of this module
throw new RuntimeException(e);
}

}

@BuildStep(onlyIf = { IsDevelopment.class, DevServicesConfig.Enabled.class })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ public SmallRyeConfigBuilder configBuilder(SmallRyeConfigBuilder builder) {

@Override
public int priority() {
// What's the right priority? This is a cheeky dynamic override, so a high priority seems correct, but dev services are supposed to fill in gaps in existing information.
// Dev services should be looking at those sources and not doing anything if there's existing config,
// so a very low priority is also arguably correct.
// In principle the priority actually shouldn't matter much, but in practice it needs to not be higher than Arquillian config overrides or some tests fail

return 10;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public DevServicesConfigSource(LaunchMode launchMode) {

@Override
public Set<String> getPropertyNames() {
// We could make this more efficient by not invoking the supplier on the other end, but it would need a more complex interface
Set<String> names = new HashSet<>();

Set<RunningService> allConfig = RunningDevServicesRegistry.INSTANCE.getAllRunningServices(launchMode.name());
Expand Down Expand Up @@ -55,7 +54,6 @@ public String getName() {

@Override
public int getOrdinal() {
// See discussion on DevServicesConfigBuilder about what the right value here is
return 10;
return 240; // a bit less than application properties, because this config should only take effect if nothing is set
}
}
Loading
Loading