From f999b08bbb57a90ef60424bf74d9837bfebb5c1f Mon Sep 17 00:00:00 2001 From: Bennet Schulz Date: Thu, 21 Nov 2024 12:39:35 +0100 Subject: [PATCH] Update to latest Quarkus version and fix breaking changes in config mapping --- pom.xml | 2 +- .../cloudwatch/LoggingCloudWatchConfig.java | 86 +++++++------- .../LoggingCloudWatchHandlerValueFactory.java | 32 ++--- .../auth/CloudWatchCredentials.java | 4 +- .../auth/CloudWatchCredentialsProvider.java | 2 +- .../LoggingCloudWatchConfigTest.java | 109 ------------------ ...gingCloudWatchHandlerValueFactoryTest.java | 34 ------ 7 files changed, 66 insertions(+), 203 deletions(-) delete mode 100644 runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfigTest.java delete mode 100644 runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactoryTest.java diff --git a/pom.xml b/pom.xml index c33dc19b..397be781 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ 17 UTF-8 UTF-8 - 3.13.2 + 3.17.0 2.29.18 3.1.1 diff --git a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfig.java b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfig.java index 7f733717..88dc845f 100644 --- a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfig.java +++ b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfig.java @@ -22,127 +22,133 @@ import java.util.Optional; import java.util.logging.Level; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; +import io.smallrye.config.WithName; /** * Configuration for CloudWatch logging. */ -@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "log.cloudwatch") -public class LoggingCloudWatchConfig { +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +@ConfigMapping(prefix = "quarkus.log.cloudwatch") +public interface LoggingCloudWatchConfig { /** * Determine whether to enable the Cloudwatch logging extension. */ - @ConfigItem(defaultValue = "true") - boolean enabled; + @WithName("enabled") + @WithDefault("true") + boolean enabled(); /** - * CW access key ID + * The AWS CloudWatch access key id */ - @ConfigItem - public Optional accessKeyId; + @WithName("access-key-id") + Optional accessKeyId(); /** - * CW access key secret + * The AWS CloudWatch access key secret */ - @ConfigItem - public Optional accessKeySecret; + @WithName("access-key-secret") + Optional accessKeySecret(); /** * Region of deployment */ - @ConfigItem - public Optional region; + @WithName("region") + Optional region(); /** * CW log group */ - @ConfigItem - public Optional logGroup; + @WithName("log-group") + Optional logGroup(); /** * CW log stream */ - @ConfigItem - public Optional logStreamName; + @WithName("log-stream-name") + Optional logStreamName(); /** * The CW log level. */ - @ConfigItem(defaultValue = "WARN") - public Level level; + @WithName("level") + @WithDefault("WARN") + Level level(); /** * Number of log events sent to CloudWatch per batch. * Defaults to 10,000 which is the maximum number of log events per batch allowed by CloudWatch. */ - @ConfigItem(defaultValue = "10000") - public int batchSize; + @WithDefault("10000") + int batchSize(); /** * Period between two batch executions. * Defaults to 5 seconds. */ - @ConfigItem(defaultValue = "5s") - public Duration batchPeriod; + @WithDefault("5s") + Duration batchPeriod(); /** * Maximum size of the log events queue. * If this is not set, the queue will have a capacity of {@link Integer#MAX_VALUE}. */ - @ConfigItem - public Optional maxQueueSize; + @WithName("max-queue-size") + Optional maxQueueSize(); /** * Service environment added as a {@code service.environment} field to each log record when available. */ - @ConfigItem - public Optional serviceEnvironment; + @WithName("service-environment") + Optional serviceEnvironment(); /** * Amount of time to allow the CloudWatch client to complete the execution of an API call. This timeout covers the * entire client execution except for marshalling. This includes request handler execution, all HTTP requests * including retries, unmarshalling, etc. This value should always be positive, if present. */ - @ConfigItem - public Optional apiCallTimeout; + @WithName("api-call-timeout") + Optional apiCallTimeout(); /** * Default credentials provider enabled added as a {@code quarkus.log.cloudwatch.default-credentials-provider.enabled} */ - @ConfigItem(name = "default-credentials-provider.enabled", defaultValue = "false") - public boolean defaultCredentialsProviderEnabled; + @WithName("default-credentials-provider.enabled") + @WithDefault("false") + boolean defaultCredentialsProviderEnabled(); /** * Endpoint override added as {@code endpoint-override} */ - @ConfigItem(name = "endpoint-override") - public Optional endpointOverride; + @WithName("endpoint-override") + Optional endpointOverride(); /* * We need to validate that the values are present, even if marked as optional. * We need to mark them as optional, as otherwise the config would mark them * as bad even before the extension can check if the values are needed at all. */ - public List validate() { + default List validate() { List errors = new ArrayList<>(); - if (!defaultCredentialsProviderEnabled) { - if (accessKeyId.isEmpty()) { + if (!defaultCredentialsProviderEnabled()) { + if (accessKeyId().isEmpty()) { errors.add("quarkus.log.cloudwatch.access-key-id"); } - if (accessKeySecret.isEmpty()) { + if (accessKeySecret().isEmpty()) { errors.add("quarkus.log.cloudwatch.access-key-secret"); } } - if (region.isEmpty()) { + if (region().isEmpty()) { errors.add("quarkus.log.cloudwatch.region"); } - if (logGroup.isEmpty()) { + if (logGroup().isEmpty()) { errors.add("quarkus.log.cloudwatch.log-group"); } - if (logStreamName.isEmpty()) { + if (logStreamName().isEmpty()) { errors.add("quarkus.log.cloudwatch.log-stream-name"); } return errors; diff --git a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactory.java b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactory.java index e27ebe6b..4336e4a5 100644 --- a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactory.java +++ b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactory.java @@ -43,7 +43,7 @@ public class LoggingCloudWatchHandlerValueFactory { private static final Logger LOGGER = Logger.getLogger(LoggingCloudWatchHandlerValueFactory.class); public RuntimeValue> create(final LoggingCloudWatchConfig config) { - if (!config.enabled) { + if (!config.enabled()) { LOGGER.info("Quarkus Logging Cloudwatch Extension is not enabled"); return new RuntimeValue<>(Optional.empty()); } @@ -62,27 +62,27 @@ public RuntimeValue> create(final LoggingCloudWatchConfig conf } } - LOGGER.infof("Logging to log-group: %s and log-stream: %s", config.logGroup.get(), config.logStreamName.get()); + LOGGER.infof("Logging to log-group: %s and log-stream: %s", config.logGroup().get(), config.logStreamName().get()); CloudWatchLogsClientBuilder cloudWatchLogsClientBuilder = CloudWatchLogsClient.builder() .credentialsProvider(new CloudWatchCredentialsProvider(config)) - .region(Region.of(config.region.get())); - if (config.apiCallTimeout.isPresent()) { + .region(Region.of(config.region().get())); + if (config.apiCallTimeout().isPresent()) { cloudWatchLogsClientBuilder = cloudWatchLogsClientBuilder.overrideConfiguration( - ClientOverrideConfiguration.builder().apiCallTimeout(config.apiCallTimeout.get()).build()); + ClientOverrideConfiguration.builder().apiCallTimeout(config.apiCallTimeout().get()).build()); } - if (config.endpointOverride.isPresent()) { - cloudWatchLogsClientBuilder.endpointOverride(URI.create(config.endpointOverride.get())); + if (config.endpointOverride().isPresent()) { + cloudWatchLogsClientBuilder.endpointOverride(URI.create(config.endpointOverride().get())); } CloudWatchLogsClient cloudWatchLogsClient = cloudWatchLogsClientBuilder.build(); String token = createLogStreamIfNeeded(cloudWatchLogsClient, config); - LoggingCloudWatchHandler handler = new LoggingCloudWatchHandler(cloudWatchLogsClient, config.logGroup.get(), - config.logStreamName.get(), token, config.maxQueueSize, config.batchSize, config.batchPeriod, - config.serviceEnvironment); - handler.setLevel(config.level); + LoggingCloudWatchHandler handler = new LoggingCloudWatchHandler(cloudWatchLogsClient, config.logGroup().get(), + config.logStreamName().get(), token, config.maxQueueSize(), config.batchSize(), config.batchPeriod(), + config.serviceEnvironment()); + handler.setLevel(config.level()); return new RuntimeValue<>(Optional.of(handler)); } @@ -91,15 +91,15 @@ private String createLogStreamIfNeeded(CloudWatchLogsClient cloudWatchLogsClient String token = null; DescribeLogStreamsRequest describeLogStreamsRequest = DescribeLogStreamsRequest.builder() - .logGroupName(config.logGroup.get()) + .logGroupName(config.logGroup().get()) // We need to filter down, as CW returns by default only 50 streams and ours may not be in it. - .logStreamNamePrefix(config.logStreamName.get()) + .logStreamNamePrefix(config.logStreamName().get()) .build(); List logStreams = cloudWatchLogsClient.describeLogStreams(describeLogStreamsRequest).logStreams(); boolean found = false; for (LogStream ls : logStreams) { - if (ls.logStreamName().equals(config.logStreamName.get())) { + if (ls.logStreamName().equals(config.logStreamName().get())) { found = true; token = ls.uploadSequenceToken(); } @@ -107,8 +107,8 @@ private String createLogStreamIfNeeded(CloudWatchLogsClient cloudWatchLogsClient if (!found) { CreateLogStreamRequest createLogStreamRequest = CreateLogStreamRequest.builder() - .logGroupName(config.logGroup.get()) - .logStreamName(config.logStreamName.get()) + .logGroupName(config.logGroup().get()) + .logStreamName(config.logStreamName().get()) .build(); cloudWatchLogsClient.createLogStream(createLogStreamRequest); } diff --git a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentials.java b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentials.java index f330bf8f..ef94d78b 100644 --- a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentials.java +++ b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentials.java @@ -29,11 +29,11 @@ class CloudWatchCredentials implements AwsCredentials { @Override public String accessKeyId() { - return config.accessKeyId.get(); + return config.accessKeyId().get(); } @Override public String secretAccessKey() { - return config.accessKeySecret.get(); + return config.accessKeySecret().get(); } } diff --git a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentialsProvider.java b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentialsProvider.java index 2d181dc9..8c1f261c 100644 --- a/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentialsProvider.java +++ b/runtime/src/main/java/io/quarkiverse/logging/cloudwatch/auth/CloudWatchCredentialsProvider.java @@ -31,7 +31,7 @@ public CloudWatchCredentialsProvider(LoggingCloudWatchConfig config) { @Override public AwsCredentials resolveCredentials() { - return config.defaultCredentialsProviderEnabled ? DefaultCredentialsProvider.create().resolveCredentials() + return config.defaultCredentialsProviderEnabled() ? DefaultCredentialsProvider.create().resolveCredentials() : new CloudWatchCredentials(config); } } diff --git a/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfigTest.java b/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfigTest.java deleted file mode 100644 index a06c30d1..00000000 --- a/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchConfigTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package io.quarkiverse.logging.cloudwatch; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -class LoggingCloudWatchConfigTest { - - private final LoggingCloudWatchConfig testee = createPreFilledTestConfig(false); - - @Test - void shouldNotThrowIllegalStateExceptionWhenEveryAttributeIsPresent() { - testee.accessKeyId = Optional.of("someAccessKeyId"); - testee.accessKeySecret = Optional.of("someAccessKeySecret"); - testee.region = Optional.of("someRegion"); - testee.logGroup = Optional.of("someLogGroup"); - testee.logStreamName = Optional.of("someLogStreamName"); - - testee.validate(); - } - - @Test - void shouldThrowIllegalStateExceptionWhenAccessKeyIdIsNotPresent() { - testee.accessKeyId = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(1, errors.size()); - assertEquals("quarkus.log.cloudwatch.access-key-id", errors.get(0), "Access key id not provided"); - } - - @Test - void shouldThrowIllegalStateExceptionWhenAccessKeySecretIsNotPresent() { - testee.accessKeySecret = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(1, errors.size()); - assertEquals("quarkus.log.cloudwatch.access-key-secret", errors.get(0), "Access key secret not provided"); - } - - @Test - void shouldThrowIllegalStateExceptionWhenRegionIsNotPresent() { - testee.region = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(1, errors.size()); - assertEquals("quarkus.log.cloudwatch.region", errors.get(0), "Region not provided"); - - } - - @Test - void shouldThrowIllegalStateExceptionWhenLogGroupIsNotPresent() { - testee.logGroup = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(1, errors.size()); - assertEquals("quarkus.log.cloudwatch.log-group", errors.get(0), "Log group not provided"); - } - - @Test - void shouldThrowIllegalStateExceptionWhenLogStreamNameIsNotPresent() { - testee.logStreamName = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(1, errors.size()); - assertEquals("quarkus.log.cloudwatch.log-stream-name", errors.get(0), "Log stream not provided"); - } - - @Test - void shouldCollctErrorsWhenMultiplePropertiesAreNotProvided() { - testee.logStreamName = Optional.empty(); - testee.region = Optional.empty(); - - List errors = testee.validate(); - - assertEquals(2, errors.size()); - assertEquals("quarkus.log.cloudwatch.region", errors.get(0), "Region not provided"); - assertEquals("quarkus.log.cloudwatch.log-stream-name", errors.get(1), "Log stream not provided"); - } - - private LoggingCloudWatchConfig createPreFilledTestConfig(boolean defaultCredentialsProviderEnabled) { - LoggingCloudWatchConfig config = new LoggingCloudWatchConfig(); - if (!defaultCredentialsProviderEnabled) { - config.accessKeyId = Optional.of("some-access-key-id"); - config.accessKeySecret = Optional.of("some-access-key-secret"); - } else { - config.defaultCredentialsProviderEnabled = true; - } - config.region = Optional.of("some-region"); - config.logGroup = Optional.of("some-log-group"); - config.logStreamName = Optional.of("some-log-stream-name"); - return config; - } - - @Test - void shouldAskForAwsAccessKeyAndSecretKeyWhenDefaultCredProviderIsEnabled() { - LoggingCloudWatchConfig preFilledTestConfig = createPreFilledTestConfig(false); - - List errors = preFilledTestConfig.validate(); - assertEquals(0, errors.size()); - } -} diff --git a/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactoryTest.java b/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactoryTest.java deleted file mode 100644 index 8ddc28a1..00000000 --- a/runtime/src/test/java/io/quarkiverse/logging/cloudwatch/LoggingCloudWatchHandlerValueFactoryTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.quarkiverse.logging.cloudwatch; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.Optional; -import java.util.logging.Handler; - -import org.junit.jupiter.api.Test; - -import io.quarkus.runtime.RuntimeValue; - -class LoggingCloudWatchHandlerValueFactoryTest { - - private final LoggingCloudWatchHandlerValueFactory testee = new LoggingCloudWatchHandlerValueFactory(); - - @Test - void shouldReturnEmptyRuntimeValueWhenConfigIsEmptyAndHasEnabledFalseByDefault() { - LoggingCloudWatchConfig config = new LoggingCloudWatchConfig(); - - final RuntimeValue> actualRuntimeValue = testee.create(config); - - assertFalse(actualRuntimeValue.getValue().isPresent()); - } - - @Test - void shouldReturnEmptyRuneTimeValueWhenConfigIsNotEnabled() { - LoggingCloudWatchConfig config = new LoggingCloudWatchConfig(); - config.enabled = false; - - final RuntimeValue> actualRuntimeValue = testee.create(config); - - assertFalse(actualRuntimeValue.getValue().isPresent()); - } -} \ No newline at end of file