Skip to content

Commit 8d6bfba

Browse files
author
Auri Munoz
committed
wip - infer type when possible and fail if missing in case of impossible inference
1 parent bf9c835 commit 8d6bfba

File tree

6 files changed

+152
-77
lines changed

6 files changed

+152
-77
lines changed

extensions/smallrye-stork/deployment/src/main/java/io/quarkus/stork/deployment/SmallRyeStorkProcessor.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
import io.quarkus.deployment.annotations.ExecutionTime;
1818
import io.quarkus.deployment.annotations.Produce;
1919
import io.quarkus.deployment.annotations.Record;
20+
import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem;
2021
import io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem;
2122
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
2223
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
2324
import io.quarkus.stork.SmallRyeStorkRecorder;
2425
import io.quarkus.stork.SmallRyeStorkRegistrationRecorder;
2526
import io.quarkus.stork.StorkConfigProvider;
2627
import io.quarkus.stork.StorkConfiguration;
28+
import io.quarkus.stork.StorkRegistrarConfigRecorder;
2729
import io.quarkus.vertx.deployment.VertxBuildItem;
2830
import io.smallrye.stork.spi.LoadBalancerProvider;
2931
import io.smallrye.stork.spi.ServiceDiscoveryProvider;
@@ -98,16 +100,20 @@ void checkThatTheKubernetesExtensionIsUsedWhenKubernetesServiceDiscoveryInOnTheC
98100
void initializeStork(SmallRyeStorkRecorder storkRecorder, ShutdownContextBuildItem shutdown, VertxBuildItem vertx,
99101
StorkConfiguration configuration) {
100102
storkRecorder.initialize(shutdown, vertx.getVertx(), configuration);
103+
if (QuarkusClassLoader.isClassPresentAtRuntime(SERVICE_REGISTRAR_PROVIDER)) {
104+
storkRecorder.deregisterServiceInstance(shutdown, configuration);
105+
}
101106
}
102107

103108
@BuildStep
104109
@Record(ExecutionTime.RUNTIME_INIT)
105110
void checkStorkConsulRegistrar(BuildProducer<StorkRegistrationBuildItem> registration,
106-
SmallRyeStorkRegistrationRecorder registrationRecorder, StorkConfiguration configuration) {
111+
BuildProducer<RunTimeConfigurationDefaultBuildItem> config,
112+
StorkRegistrarConfigRecorder initializerRecorder, StorkConfiguration configuration) {
107113
if (QuarkusClassLoader.isClassPresentAtRuntime(CONSUL_SERVICE_REGISTRAR_PROVIDER)) {
108-
registrationRecorder.prepareConfiguration(configuration, CONSUL_SERVICE_REGISTRAR_TYPE);
114+
initializerRecorder.setupServiceRegistrarConfig(configuration, CONSUL_SERVICE_REGISTRAR_TYPE);
109115
} else if (QuarkusClassLoader.isClassPresentAtRuntime(EUREKA_SERVICE_REGISTRAR_PROVIDER)) {
110-
registrationRecorder.prepareConfiguration(configuration, EUREKA_SERVICE_REGISTRAR_TYPE);
116+
initializerRecorder.setupServiceRegistrarConfig(configuration, EUREKA_SERVICE_REGISTRAR_TYPE);
111117
}
112118
registration.produce(new StorkRegistrationBuildItem());
113119

extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRecorder.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package io.quarkus.stork;
22

3+
import java.net.InetAddress;
34
import java.util.List;
5+
import java.util.Map;
46

57
import jakarta.enterprise.inject.Instance;
68
import jakarta.enterprise.inject.spi.CDI;
79

10+
import org.eclipse.microprofile.config.Config;
11+
import org.eclipse.microprofile.config.ConfigProvider;
12+
813
import io.quarkus.runtime.RuntimeValue;
914
import io.quarkus.runtime.ShutdownContext;
1015
import io.quarkus.runtime.annotations.Recorder;
@@ -34,4 +39,36 @@ public void run() {
3439
}
3540
});
3641
}
42+
43+
public void deregisterServiceInstance(ShutdownContext shutdown, StorkConfiguration configuration) {
44+
shutdown.addLastShutdownTask(new Runnable() {
45+
@Override
46+
public void run() {
47+
Stork.shutdown();
48+
}
49+
});
50+
}
51+
52+
private void deregisterServiceInstance(StorkConfiguration configuration) {
53+
List<ServiceConfig> serviceConfigs = StorkConfigUtil.toStorkServiceConfig(configuration);
54+
List<ServiceConfig> registrationConfigs = serviceConfigs.stream()
55+
.filter(serviceConfig -> serviceConfig.serviceRegistrar() != null).toList();
56+
57+
registrationConfigs.get(0).serviceName();
58+
Config quarkusConfig = ConfigProvider.getConfig();
59+
for (ServiceConfig serviceConfig : serviceConfigs) {
60+
String serviceName = serviceConfig.serviceName();
61+
Map<String, String> parameters = serviceConfig.serviceRegistrar().parameters();
62+
String host = parameters.containsKey("ip-address") ? parameters.get("ip-address")
63+
: quarkusConfig.getValue("quarkus.http.host", String.class);
64+
int port = parameters.containsKey("port") ? Integer.parseInt(parameters.get("port"))
65+
: Integer.parseInt(quarkusConfig.getValue("quarkus.http.port", String.class));
66+
if (host == null || host.isEmpty()) {
67+
InetAddress inetAddress = StorkConfigUtil.detectAddress();
68+
host = inetAddress != null ? inetAddress.getHostAddress() : host;
69+
}
70+
Stork.getInstance().getService(serviceName).getServiceRegistrar().registerServiceInstance(serviceName, host,
71+
port).await().indefinitely();
72+
}
73+
}
3774
}

extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRegistrationRecorder.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
@Recorder
1515
public class SmallRyeStorkRegistrationRecorder {
1616

17-
public StorkConfiguration prepareConfiguration(StorkConfiguration configuration, String serviceRegistrarType) {
18-
return StorkConfigUtil.buildDefaultRegistrationConfig(configuration, serviceRegistrarType);
19-
20-
}
21-
2217
public void registerServiceInstance(StorkConfiguration configuration) {
2318
List<ServiceConfig> serviceConfigs = StorkConfigUtil.toStorkServiceConfig(configuration);
2419
Config quarkusConfig = ConfigProvider.getConfig();

extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/StorkConfigUtil.java

Lines changed: 54 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
import java.util.Map;
1111
import java.util.Optional;
1212
import java.util.Set;
13-
import java.util.stream.Collectors;
1413

15-
import org.eclipse.microprofile.config.Config;
16-
import org.eclipse.microprofile.config.ConfigProvider;
14+
import org.jboss.logging.Logger;
1715

1816
import io.smallrye.stork.api.config.ServiceConfig;
1917
import io.smallrye.stork.spi.config.SimpleServiceConfig;
2018

2119
public class StorkConfigUtil {
2220

21+
private static final Logger LOGGER = Logger.getLogger(StorkConfigUtil.class.getName());
22+
2323
public static List<ServiceConfig> toStorkServiceConfig(StorkConfiguration storkConfiguration) {
2424
List<ServiceConfig> storkServicesConfigs = new ArrayList<>();
2525
Set<String> servicesConfigs = storkConfiguration.serviceConfiguration().keySet();
@@ -38,7 +38,7 @@ public static List<ServiceConfig> toStorkServiceConfig(StorkConfiguration storkC
3838
}
3939
if (serviceConfiguration.serviceRegistrar().isPresent()) {
4040
SimpleServiceConfig.SimpleServiceRegistrarConfig serviceRegistrarConfig = new SimpleServiceConfig.SimpleServiceRegistrarConfig(
41-
serviceConfiguration.serviceRegistrar().get().type(),
41+
serviceConfiguration.serviceRegistrar().get().type().orElse(""),
4242
serviceConfiguration.serviceRegistrar().get().parameters());
4343
builder.setServiceRegistrar(serviceRegistrarConfig);
4444
}
@@ -47,89 +47,75 @@ public static List<ServiceConfig> toStorkServiceConfig(StorkConfiguration storkC
4747
return storkServicesConfigs;
4848
}
4949

50-
public static StorkConfiguration buildDefaultRegistrationConfig(StorkConfiguration configuration, String serviceRegistrarType) {
51-
Config quarkusConfig = ConfigProvider.getConfig();
52-
List<ServiceConfig> serviceConfigs = StorkConfigUtil.toStorkServiceConfig(configuration);
53-
List<ServiceConfig> registrationConfigs = serviceConfigs.stream()
54-
.filter(serviceConfig -> serviceConfig.serviceRegistrar() != null).toList();
55-
if (registrationConfigs.isEmpty()) {
56-
String serviceName = quarkusConfig.getOptionalValue("quarkus.application.name", String.class)
57-
.orElse("auri-application");
58-
configuration.serviceConfiguration().put(serviceName, new ServiceConfiguration() {
59-
@Override
60-
public Optional<StorkServiceDiscoveryConfiguration> serviceDiscovery() {
61-
return Optional.empty();
62-
}
50+
public static ServiceConfiguration buildDefaultRegistrarConfiguration(String serviceRegistrarType) {
51+
return buildServiceConfigurationWithRegistrar(serviceRegistrarType, Map.of());
52+
}
6353

64-
@Override
65-
public StorkLoadBalancerConfiguration loadBalancer() {
66-
return null;
67-
}
54+
public static ServiceConfiguration addRegistrarTypeIfAbsent(String serviceRegistrarType,
55+
ServiceConfiguration serviceConfiguration) {
56+
Map<String, String> parameters = serviceConfiguration.serviceRegistrar()
57+
.map(StorkServiceRegistrarConfiguration::parameters)
58+
.orElse(Map.of());
59+
return buildServiceConfigurationWithRegistrar(serviceRegistrarType, parameters);
60+
}
6861

69-
@Override
70-
public Optional<StorkServiceRegistrarConfiguration> serviceRegistrar() {
71-
return Optional.of(new StorkServiceRegistrarConfiguration() {
72-
@Override
73-
public String type() {
74-
return serviceRegistrarType;
75-
}
76-
77-
@Override
78-
public Map<String, String> parameters() {
79-
return Map.of();
80-
}
81-
});
82-
}
83-
});
84-
}
85-
return configuration;
62+
private static ServiceConfiguration buildServiceConfigurationWithRegistrar(String type, Map<String, String> parameters) {
63+
return new ServiceConfiguration() {
64+
@Override
65+
public Optional<StorkServiceDiscoveryConfiguration> serviceDiscovery() {
66+
return Optional.empty();
67+
}
68+
69+
@Override
70+
public StorkLoadBalancerConfiguration loadBalancer() {
71+
return null;
72+
}
8673

74+
@Override
75+
public Optional<StorkServiceRegistrarConfiguration> serviceRegistrar() {
76+
return Optional.of(buildServiceRegistrarConfiguration(type, parameters));
77+
}
78+
};
79+
}
80+
81+
private static StorkServiceRegistrarConfiguration buildServiceRegistrarConfiguration(String type,
82+
Map<String, String> parameters) {
83+
return new StorkServiceRegistrarConfiguration() {
84+
@Override
85+
public Optional<String> type() {
86+
return Optional.of(type);
87+
}
88+
89+
@Override
90+
public Map<String, String> parameters() {
91+
return parameters;
92+
}
93+
};
8794
}
8895

8996
public static InetAddress detectAddress() {
9097
InetAddress result = null;
9198
try {
9299
int lowest = Integer.MAX_VALUE;
93-
for (Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces(); nics
94-
.hasMoreElements();) {
95-
NetworkInterface ifc = nics.nextElement();
96-
if (ifc.isUp()) {
97-
// this.log.trace("Testing interface: " + ifc.getDisplayName());
98-
if (ifc.getIndex() < lowest || result == null) {
99-
lowest = ifc.getIndex();
100+
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
101+
while (networkInterfaces.hasMoreElements()) {
102+
NetworkInterface networkInterface = networkInterfaces.nextElement();
103+
if (networkInterface.isUp()) {
104+
LOGGER.debug("Testing interface: {}" + networkInterface.getDisplayName());
105+
if (networkInterface.getIndex() < lowest || result == null) {
106+
lowest = networkInterface.getIndex();
100107
} else if (result != null) {
101108
continue;
102109
}
103-
104-
// @formatter:off
105-
// if (!ignoreInterface(ifc.getDisplayName())) {
106-
// for (Enumeration<InetAddress> addrs = ifc
107-
// .getInetAddresses(); addrs.hasMoreElements();) {
108-
// InetAddress address = addrs.nextElement();
109-
// if (address instanceof Inet4Address
110-
// && !address.isLoopbackAddress()
111-
// && isPreferredAddress(address)) {
112-
//// this.log.trace("Found non-loopback interface: "
113-
//// + ifc.getDisplayName());
114-
// result = address;
115-
// }
116-
// }
117-
// }
118-
// @formatter:on
119110
}
120111
}
121112
} catch (IOException ex) {
122-
// this.log.error("Cannot get first non-loopback address", ex);
113+
LOGGER.error("Unable to get first non-loopback address", ex);
123114
}
124-
125-
if (result != null) {
126-
return result;
127-
}
128-
129115
try {
130116
return InetAddress.getLocalHost();
131117
} catch (UnknownHostException e) {
132-
// this.log.warn("Unable to retrieve localhost");
118+
LOGGER.error("Unable to detect address", e);
133119
}
134120

135121
return null;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.quarkus.stork;
2+
3+
import java.util.*;
4+
import java.util.logging.Logger;
5+
6+
import org.eclipse.microprofile.config.Config;
7+
import org.eclipse.microprofile.config.ConfigProvider;
8+
9+
import io.quarkus.runtime.annotations.Recorder;
10+
import io.smallrye.stork.api.config.ServiceConfig;
11+
12+
@Recorder
13+
public class StorkRegistrarConfigRecorder {
14+
15+
private static final Logger LOGGER = Logger.getLogger(StorkRegistrarConfigRecorder.class.getName());
16+
17+
public void setupServiceRegistrarConfig(StorkConfiguration config, String serviceRegistrarType) {
18+
Config quarkusConfig = ConfigProvider.getConfig();
19+
List<ServiceConfig> serviceConfigs = StorkConfigUtil.toStorkServiceConfig(config);
20+
List<ServiceConfig> registrationConfigs = serviceConfigs.stream()
21+
.filter(serviceConfig -> serviceConfig.serviceRegistrar() != null).toList();
22+
String serviceName = quarkusConfig.getOptionalValue("quarkus.application.name", String.class)
23+
.orElse("auri-application");
24+
if (registrationConfigs.isEmpty()) {
25+
config.serviceConfiguration().put(serviceName,
26+
StorkConfigUtil.buildDefaultRegistrarConfiguration(serviceRegistrarType));
27+
} else if (registrationConfigs.size() == 1) {
28+
config.serviceConfiguration().computeIfPresent(serviceName,
29+
(k, v) -> StorkConfigUtil.addRegistrarTypeIfAbsent(serviceRegistrarType, v));
30+
} else {
31+
failOnMissingRegistrarTypes(registrationConfigs, serviceName);
32+
}
33+
}
34+
35+
private static void failOnMissingRegistrarTypes(List<ServiceConfig> registrationConfigs, String serviceName) {
36+
List<String> servicesWithMissingType = new ArrayList<>();
37+
for (ServiceConfig registrationConfig : registrationConfigs) {
38+
if (registrationConfig.serviceRegistrar().type().isBlank()) {
39+
servicesWithMissingType.add(registrationConfig.serviceName());
40+
LOGGER.info("Missing 'type' for service '" + serviceName + "'. This may lead to a runtime error.");
41+
}
42+
43+
}
44+
if (!servicesWithMissingType.isEmpty()) {
45+
throw new IllegalArgumentException("Missing required 'type' for the following services: " +
46+
String.join(", ", servicesWithMissingType));
47+
}
48+
}
49+
50+
}

extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/StorkServiceRegistrarConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.quarkus.stork;
22

33
import java.util.Map;
4+
import java.util.Optional;
45

56
import io.quarkus.runtime.annotations.ConfigGroup;
67
import io.smallrye.config.WithParentName;
@@ -13,7 +14,7 @@ public interface StorkServiceRegistrarConfiguration {
1314
* A ServiceRegistrarProvider for the type has to be available
1415
*
1516
*/
16-
String type();
17+
Optional<String> type();
1718

1819
/**
1920
* Service Registrar parameters.

0 commit comments

Comments
 (0)