diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfiguration.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfiguration.java index e004b529..5e61d423 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfiguration.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.client.RestTemplateBuilder; @@ -28,41 +29,38 @@ import org.springframework.cloud.fn.consumer.wavefront.service.ProxyConnectionWavefrontService; import org.springframework.cloud.fn.consumer.wavefront.service.WavefrontService; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; import org.springframework.messaging.Message; import org.springframework.util.StringUtils; /** + * The auto-configuration for Wavefront consumer. + * * @author Timo Salm + * @author Artem Bilan */ -@Configuration +@AutoConfiguration(after = RestTemplateAutoConfiguration.class) @EnableConfigurationProperties(WavefrontConsumerProperties.class) -@Import(RestTemplateAutoConfiguration.class) public class WavefrontConsumerConfiguration { private static final Log logger = LogFactory.getLog(WavefrontConsumerConfiguration.class); @Bean - public Consumer> wavefrontConsumer(final WavefrontConsumerProperties properties, - final WavefrontService service) { - - return message -> { - final WavefrontFormat wavefrontFormat = new WavefrontFormat(properties, message); - final String formattedString = wavefrontFormat.getFormattedString(); + public Consumer> wavefrontConsumer(WavefrontConsumerProperties properties, WavefrontService service) { + return (message) -> { + WavefrontFormat wavefrontFormat = new WavefrontFormat(properties, message); + String formattedString = wavefrontFormat.getFormattedString(); service.send(formattedString); - if (logger.isDebugEnabled()) { - logger.debug(formattedString); - } + logger.debug(formattedString); }; } @Bean - public WavefrontService wavefrontService(final WavefrontConsumerProperties properties, - final RestTemplateBuilder restTemplateBuilder) { + public WavefrontService wavefrontService(WavefrontConsumerProperties properties, + RestTemplateBuilder restTemplateBuilder) { - if (!StringUtils.isEmpty(properties.getProxyUri())) { - return new ProxyConnectionWavefrontService(restTemplateBuilder, properties.getProxyUri()); + String proxyUri = properties.getProxyUri(); + if (StringUtils.hasText(proxyUri)) { + return new ProxyConnectionWavefrontService(restTemplateBuilder, proxyUri); } else { return new DirectConnectionWavefrontService(restTemplateBuilder, properties.getUri(), diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerProperties.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerProperties.java index 97289d08..0a969ce8 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerProperties.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ import org.springframework.validation.annotation.Validated; /** + * The configuration properties for Wavefront consumer. + * * @author Timo Salm */ @ConfigurationProperties("wavefront") @@ -104,7 +106,7 @@ public WavefrontConsumerProperties() { @NotEmpty @Pattern(regexp = "^[a-zA-Z0-9./_,-]+") public String getMetricName() { - return metricName; + return this.metricName; } public void setMetricName(String metricName) { @@ -115,7 +117,7 @@ public void setMetricName(String metricName) { @Size(max = 128) @Pattern(regexp = "^[a-zA-Z0-9._-]+") public String getSource() { - return source; + return this.source; } public void setSource(String source) { @@ -124,7 +126,7 @@ public void setSource(String source) { @NotNull public Expression getMetricExpression() { - return metricExpression; + return this.metricExpression; } public void setMetricExpression(Expression metricExpression) { @@ -132,7 +134,7 @@ public void setMetricExpression(Expression metricExpression) { } public Expression getTimestampExpression() { - return timestampExpression; + return this.timestampExpression; } public void setTimestampExpression(Expression timestampExpression) { @@ -140,7 +142,7 @@ public void setTimestampExpression(Expression timestampExpression) { } public Map getTagExpression() { - return tagExpression; + return this.tagExpression; } public void setTagExpression(Map tagExpression) { @@ -148,7 +150,7 @@ public void setTagExpression(Map tagExpression) { } public String getUri() { - return uri; + return this.uri; } public void setUri(String uri) { @@ -156,7 +158,7 @@ public void setUri(String uri) { } public String getApiToken() { - return apiToken; + return this.apiToken; } public void setApiToken(String apiToken) { @@ -164,7 +166,7 @@ public void setApiToken(String apiToken) { } public String getProxyUri() { - return proxyUri; + return this.proxyUri; } public void setProxyUri(String proxyUri) { @@ -173,8 +175,10 @@ public void setProxyUri(String proxyUri) { @AssertTrue(message = "Exactly one of 'proxy-uri' or the pair of ('uri' and 'api-token') must be set!") public boolean isMutuallyExclusiveProxyAndDirectAccessWavefrontConfiguration() { - return StringUtils.isEmpty(getProxyUri()) - ^ (StringUtils.isEmpty(getUri()) || StringUtils.isEmpty(getApiToken())); + boolean hasProxyUri = StringUtils.hasText(getProxyUri()); + boolean hasUri = StringUtils.hasText(getUri()); + boolean hasApiToken = StringUtils.hasText(getApiToken()); + return (hasProxyUri && !hasUri && !hasApiToken) || (!hasProxyUri && hasUri && hasApiToken); } } diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormat.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormat.java index b3186b74..f4cd5142 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormat.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormat.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,11 +32,13 @@ import org.springframework.messaging.Message; /** + * The format for Wavefront messages. + * * @author Timo Salm */ public class WavefrontFormat { - private static final Log logger = LogFactory.getLog(WavefrontFormat.class); + private static final Log LOGGER = LogFactory.getLog(WavefrontFormat.class); private final WavefrontConsumerProperties properties; @@ -50,62 +52,64 @@ public WavefrontFormat(final WavefrontConsumerProperties properties, Message public String getFormattedString() { final Number metricValue = extractMetricValueFromPayload(); - final Map pointTagsMap = extractPointTagsMapFromPayload(properties.getTagExpression(), message); + final Map pointTagsMap = extractPointTagsMapFromPayload(this.properties.getTagExpression(), + this.message); validatePointTagsKeyValuePairs(pointTagsMap); final String formattedPointTagsPart = getFormattedPointTags(pointTagsMap); - if (properties.getTimestampExpression() == null) { + if (this.properties.getTimestampExpression() == null) { return String - .format("\"%s\" %s source=%s %s", properties.getMetricName(), metricValue, properties.getSource(), - formattedPointTagsPart) + .format("\"%s\" %s source=%s %s", this.properties.getMetricName(), metricValue, + this.properties.getSource(), formattedPointTagsPart) .trim(); } final Long timestamp = extractTimestampFromPayload(); return String - .format("\"%s\" %s %d source=%s %s", properties.getMetricName(), metricValue, timestamp, - properties.getSource(), formattedPointTagsPart) + .format("\"%s\" %s %d source=%s %s", this.properties.getMetricName(), metricValue, timestamp, + this.properties.getSource(), formattedPointTagsPart) .trim(); } private Long extractTimestampFromPayload() { try { - return properties.getTimestampExpression().getValue(message, Long.class); + return this.properties.getTimestampExpression().getValue(this.message, Long.class); } - catch (SpelEvaluationException e) { + catch (SpelEvaluationException ex) { throw new ValidationException( "The timestamp value has to be a number that reflects the epoch seconds of the " + "metric (e.g. 1382754475).", - e); + ex); } } private Number extractMetricValueFromPayload() { try { - return properties.getMetricExpression().getValue(message, Number.class); + return this.properties.getMetricExpression().getValue(this.message, Number.class); } - catch (SpelEvaluationException e) { + catch (SpelEvaluationException ex) { throw new ValidationException("The metric value has to be a double-precision floating point number or a " - + "long integer. It can be positive, negative, or 0.", e); + + "long integer. It can be positive, negative, or 0.", ex); } } private String getFormattedPointTags(Map pointTagsMap) { return pointTagsMap.entrySet() .stream() - .map(it -> String.format("%s=\"%s\"", it.getKey(), it.getValue())) + .map((it) -> String.format("%s=\"%s\"", it.getKey(), it.getValue())) .collect(Collectors.joining(" ")); } private Map extractPointTagsMapFromPayload(Map pointTagsExpressionsPointValue, Message message) { - return pointTagsExpressionsPointValue.entrySet().stream().map(it -> { + + return pointTagsExpressionsPointValue.entrySet().stream().map((it) -> { try { - final Object pointValue = it.getValue().getValue(message); + final Object pointValue = it.getValue().getValue(this.message); return new AbstractMap.SimpleEntry<>(it.getKey(), pointValue); } - catch (EvaluationException e) { - logger.warn("Unable to extract point tag for key " + it.getKey() + " from payload", e); + catch (EvaluationException ex) { + LOGGER.warn("Unable to extract point tag for key " + it.getKey() + " from payload", ex); return null; } }).filter(Objects::nonNull).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -120,7 +124,7 @@ private void validatePointTagsKeyValuePairs(Map pointTagsMap) { final int keyValueCombinationLength = key.length() + value.toString().length(); if (keyValueCombinationLength > 254) { - logger.warn("Maximum allowed length for a combination of a point tag key and value " + LOGGER.warn("Maximum allowed length for a combination of a point tag key and value " + "is 254 characters. The length of combination for key " + key + " is " + keyValueCombinationLength + "."); } diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/package-info.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/package-info.java new file mode 100644 index 00000000..6c260a88 --- /dev/null +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/package-info.java @@ -0,0 +1,4 @@ +/** + * The Wavefront consumer classes. + */ +package org.springframework.cloud.fn.consumer.wavefront; diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontService.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontService.java index 8a446fbc..57f31531 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontService.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,11 +26,13 @@ import org.springframework.web.client.RestTemplate; /** + * The {@link WavefrontService} implementation for direct connection. + * * @author Timo Salm */ public class DirectConnectionWavefrontService implements WavefrontService { - private static final Log logger = LogFactory.getLog(DirectConnectionWavefrontService.class); + private static final Log LOGGER = LogFactory.getLog(DirectConnectionWavefrontService.class); private final RestTemplate restTemplate; @@ -40,6 +42,7 @@ public class DirectConnectionWavefrontService implements WavefrontService { public DirectConnectionWavefrontService(final RestTemplateBuilder restTemplateBuilder, final String wavefrontServerUri, final String wavefrontApiToken) { + this.restTemplate = restTemplateBuilder.build(); this.wavefrontDomain = wavefrontServerUri; this.wavefrontToken = wavefrontApiToken; @@ -47,13 +50,11 @@ public DirectConnectionWavefrontService(final RestTemplateBuilder restTemplateBu @Override public void send(String metricInWavefrontFormat) { - if (logger.isDebugEnabled()) { - logger.debug("Send metric directly to Wavefront"); - } + LOGGER.debug("Send metric directly to Wavefront"); final HttpHeaders headers = new HttpHeaders(); - headers.setBearerAuth(wavefrontToken); + headers.setBearerAuth(this.wavefrontToken); final HttpEntity httpEntity = new HttpEntity<>(metricInWavefrontFormat, headers); - restTemplate.exchange(wavefrontDomain + "/report", HttpMethod.POST, httpEntity, Void.class); + this.restTemplate.exchange(this.wavefrontDomain + "/report", HttpMethod.POST, httpEntity, Void.class); } } diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontService.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontService.java index 6c3368af..6169e969 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontService.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,13 @@ import org.springframework.web.client.RestTemplate; /** + * The {@link WavefrontService} implementation for connection over proxy. + * * @author Timo Salm */ public class ProxyConnectionWavefrontService implements WavefrontService { - private static final Log logger = LogFactory.getLog(ProxyConnectionWavefrontService.class); + private static final Log LOGGER = LogFactory.getLog(ProxyConnectionWavefrontService.class); private final RestTemplate restTemplate; @@ -35,16 +37,15 @@ public class ProxyConnectionWavefrontService implements WavefrontService { public ProxyConnectionWavefrontService(final RestTemplateBuilder restTemplateBuilder, final String wavefrontProxyUri) { + this.restTemplate = restTemplateBuilder.build(); this.wavefrontProxyUrl = wavefrontProxyUri; } @Override public void send(String metricInWavefrontFormat) { - if (logger.isDebugEnabled()) { - logger.debug("Send metric to Wavefront proxy"); - } - restTemplate.postForEntity(wavefrontProxyUrl, metricInWavefrontFormat, Void.class); + LOGGER.debug("Send metric to Wavefront proxy"); + this.restTemplate.postForEntity(this.wavefrontProxyUrl, metricInWavefrontFormat, Void.class); } } diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontService.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontService.java index fb61b17a..c951a95e 100644 --- a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontService.java +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ package org.springframework.cloud.fn.consumer.wavefront.service; /** + * The abstraction for Wavefront communication. + * * @author Timo Salm */ public interface WavefrontService { diff --git a/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/package-info.java b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/package-info.java new file mode 100644 index 00000000..2895dfa3 --- /dev/null +++ b/consumer/spring-wavefront-consumer/src/main/java/org/springframework/cloud/fn/consumer/wavefront/service/package-info.java @@ -0,0 +1,4 @@ +/** + * The Wavefront service API. + */ +package org.springframework.cloud.fn.consumer.wavefront.service; diff --git a/consumer/spring-wavefront-consumer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/consumer/spring-wavefront-consumer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..adbe9160 --- /dev/null +++ b/consumer/spring-wavefront-consumer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.cloud.fn.consumer.wavefront.WavefrontConsumerConfiguration diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTests.java similarity index 93% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTests.java index d8544830..5ea51aa9 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ "wavefront.timestamp-expression=#jsonPath(payload,'$.receivedAt')", "wavefront.tag-expression.vin=#jsonPath(payload,'$.vin')", "wavefront.tag-expression.latitude=#jsonPath(payload,'$.location.latitude')", "wavefront.proxy-uri=testUrl" }) -public class WavefrontConsumerConfigurationTest { +public class WavefrontConsumerConfigurationTests { @Autowired private Consumer> wavefrontConsumer; @@ -59,7 +59,7 @@ void testWavefrontConsumer() { final String dataJsonString = "{ \"mileage\": 1.5, \"receivedAt\": " + timestamp + ", \"vin\": \"test-vin\", " + "\"location\": {\"latitude\": 4.53, \"longitude\": 2.89 }}"; - wavefrontConsumer.accept(new GenericMessage(dataJsonString.getBytes())); + wavefrontConsumer.accept(new GenericMessage<>(dataJsonString.getBytes())); final String formattedString = "\"vehicle-location\" 1.5 " + timestamp + " source=vehicle-api " + "latitude=\"4.53\" vin=\"test-vin\""; diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTests.java similarity index 91% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTests.java index 8d4ca901..c85698b0 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontConsumerPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +33,7 @@ /** * @author Timo Salm */ -public class WavefrontConsumerPropertiesTest { +public class WavefrontConsumerPropertiesTests { private final Expression testExpression = new SpelExpressionParser().parseExpression("#jsonPath(payload,'$')"); @@ -51,7 +51,7 @@ void testRequiredProperties() { null, null, null, "proxy"); final List emptyValues = Arrays.asList(null, ""); - emptyValues.forEach(emptyValue -> { + emptyValues.forEach((emptyValue) -> { assertThat(validator.validate(properties).isEmpty()).isTrue(); properties.setMetricName(emptyValue); assertThat(validator.validate(properties).isEmpty()).isFalse(); @@ -76,13 +76,13 @@ void testValidMetricNameValues() { "c.8W-2h_dE_,J-h/"); assertThat(validator.validate(properties).isEmpty()).isTrue(); - validMetricNameValues.forEach(validMetricNameValue -> { + validMetricNameValues.forEach((validMetricNameValue) -> { properties.setMetricName(validMetricNameValue); assertThat(validator.validate(properties).isEmpty()).isTrue(); }); final List invalidMetricNameValues = Arrays.asList(" ", ":", "a B", "#"); - invalidMetricNameValues.forEach(invalidMetricNameValue -> { + invalidMetricNameValues.forEach((invalidMetricNameValue) -> { properties.setMetricName(invalidMetricNameValue); assertThat(validator.validate(properties).isEmpty()).isFalse(); }); @@ -96,14 +96,14 @@ void testValidSourceValues() { createStringOfLength(128)); assertThat(validator.validate(properties).isEmpty()).isTrue(); - validSourceValues.forEach(validSourceValue -> { + validSourceValues.forEach((validSourceValue) -> { properties.setSource(validSourceValue); assertThat(validator.validate(properties).isEmpty()).isTrue(); }); final List invalidSourceValues = Arrays.asList(" ", ":", "a B", "#", "/", ",", createStringOfLength(129)); - invalidSourceValues.forEach(invalidSourceValue -> { + invalidSourceValues.forEach((invalidSourceValue) -> { properties.setSource(invalidSourceValue); assertThat(validator.validate(properties).isEmpty()).isFalse(); }); diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTests.java similarity index 87% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTests.java index 578b5a6c..47fd473d 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/WavefrontFormatTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; @@ -45,11 +44,13 @@ import org.springframework.messaging.support.GenericMessage; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatRuntimeException; /** * @author Timo Salm + * @author Artem Bilan */ -public class WavefrontFormatTest { +public class WavefrontFormatTests { private final SpelExpressionParser parser = new SpelExpressionParser(); @@ -110,10 +111,11 @@ void testInvalidMetricValue() { final String dataJsonString = "{ \"value\": a}"; final WavefrontConsumerProperties properties = new WavefrontConsumerProperties("testMetricName", "testSource", expression("$.value"), null, Collections.emptyMap(), null, null, null); - final Exception exception = Assertions.assertThrows(RuntimeException.class, - () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()); - assertThat(exception.getLocalizedMessage().startsWith("The metric value has to be a double-precision floating")) - .isTrue(); + + assertThatRuntimeException() + .isThrownBy( + () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()) + .withMessageContaining("The metric value has to be a double-precision floating"); } @Test @@ -121,9 +123,10 @@ void testInvalidTimestampValue() { final String dataJsonString = "{ \"value\": 1.5, \"timestamp\": 2020-06-02T13:53:18+0000}"; final WavefrontConsumerProperties properties = new WavefrontConsumerProperties("testMetricName", "testSource", expression("$.value"), expression("$.timestamp"), Collections.emptyMap(), null, null, null); - final Exception exception = Assertions.assertThrows(RuntimeException.class, - () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()); - assertThat(exception.getLocalizedMessage().startsWith("The timestamp value has to be a number")).isTrue(); + assertThatRuntimeException() + .isThrownBy( + () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()) + .withMessageContaining("The timestamp value has to be a number"); } @Test @@ -145,7 +148,7 @@ void testInvalidPointTagsLengthWarning() { + createStringOfLength(254 - testPointTagKey.length()) + "\" }"; new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString(); assertThat(listAppender.list.stream() - .filter(event -> event.getMessage().startsWith("Maximum allowed length for a combination")) + .filter((event) -> event.getMessage().startsWith("Maximum allowed length for a combination")) .count()).isEqualTo(0); final String dataJsonStringWithTooLongValue = "{ \"value\": 1.5, \"testPoint1\": \"" @@ -153,7 +156,7 @@ void testInvalidPointTagsLengthWarning() { new WavefrontFormat(properties, new GenericMessage<>(dataJsonStringWithTooLongValue)).getFormattedString(); assertThat(listAppender.list.stream() - .filter(event -> event.getMessage().startsWith("Maximum allowed length for a combination") + .filter((event) -> event.getMessage().startsWith("Maximum allowed length for a combination") && event.getLevel().equals(Level.WARN)) .count()).isEqualTo(1); } @@ -174,17 +177,16 @@ void testInvalidPointTagKeys() { final List invalidPointTagKeys = Arrays.asList(" ", ":", "a B", "#", "/", ","); - invalidPointTagKeys.forEach(invalidPointTagKey -> { + invalidPointTagKeys.forEach((invalidPointTagKey) -> { final Map pointTagsExpressionsPointValueMap = Stream .of(new AbstractMap.SimpleEntry<>(invalidPointTagKey, expression("$.testPoint1"))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); final WavefrontConsumerProperties properties = new WavefrontConsumerProperties("testMetricName", "testSource", expression("$.value"), null, pointTagsExpressionsPointValueMap, null, null, null); - final Exception exception = Assertions.assertThrows(RuntimeException.class, - () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()); - assertThat(exception.getLocalizedMessage() - .startsWith("Point tag key \"" + invalidPointTagKey + "\" contains invalid characters")).isTrue(); + assertThatRuntimeException().isThrownBy( + () -> new WavefrontFormat(properties, new GenericMessage<>(dataJsonString)).getFormattedString()) + .withMessageContaining("Point tag key \"" + invalidPointTagKey + "\" contains invalid characters"); }); } diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTests.java similarity index 87% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTests.java index 3a48bc00..56081f71 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/DirectConnectionWavefrontServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,20 +29,21 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; /** * @author Timo Salm + * @author Artem Bilan */ -public class DirectConnectionWavefrontServiceTest { +public class DirectConnectionWavefrontServiceTests { @Test void testSendMetricInWavefrontFormat() { final RestTemplateBuilder restTemplateBuilderMock = mock(RestTemplateBuilder.class); final RestTemplate restTemplateMock = mock(RestTemplate.class); - when(restTemplateBuilderMock.build()).thenReturn(restTemplateMock); + given(restTemplateBuilderMock.build()).willReturn(restTemplateMock); final String metricInWavefrontFormat = "testMetric"; final String wavefrontServerUri = "testWavefrontDomain"; @@ -52,7 +53,7 @@ void testSendMetricInWavefrontFormat() { wavefrontServerUri, wavefrontApiToken); service.send(metricInWavefrontFormat); - final ArgumentCaptor argument = ArgumentCaptor.forClass(HttpEntity.class); + ArgumentCaptor> argument = ArgumentCaptor.captor(); verify(restTemplateMock, Mockito.times(1)).exchange(eq(wavefrontServerUri + "/report"), eq(HttpMethod.POST), argument.capture(), eq(Void.class)); assertThat(Objects.requireNonNull(argument.getValue().getHeaders().get("Authorization")).get(0)) diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTests.java similarity index 87% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTests.java index 8f8183e3..979cbcb0 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/ProxyConnectionWavefrontServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,20 +23,20 @@ import org.springframework.web.client.RestTemplate; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; /** * @author Timo Salm */ -public class ProxyConnectionWavefrontServiceTest { +public class ProxyConnectionWavefrontServiceTests { @Test void testSendMetricInWavefrontFormat() { final RestTemplateBuilder restTemplateBuilderMock = mock(RestTemplateBuilder.class); final RestTemplate restTemplateMock = mock(RestTemplate.class); - when(restTemplateBuilderMock.build()).thenReturn(restTemplateMock); + given(restTemplateBuilderMock.build()).willReturn(restTemplateMock); final String metricInWavefrontFormat = "testMetric"; final String wavefrontProxyUrl = "testWavefrontProxyUrl"; diff --git a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTest.java b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTests.java similarity index 83% rename from consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTest.java rename to consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTests.java index 7ce1ff82..a63195a6 100644 --- a/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTest.java +++ b/consumer/spring-wavefront-consumer/src/test/java/org/springframework/cloud/fn/consumer/wavefront/service/WavefrontServiceConditionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,9 @@ import org.junit.jupiter.api.Test; -import org.springframework.boot.context.annotation.UserConfigurations; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.fn.common.config.SpelExpressionConverterConfiguration; import org.springframework.cloud.fn.consumer.wavefront.WavefrontConsumerConfiguration; @@ -32,17 +34,18 @@ /** * @author Timo Salm */ -public class WavefrontServiceConditionTest { +public class WavefrontServiceConditionTests { private final ApplicationContextRunner runner = new ApplicationContextRunner().withConfiguration( - UserConfigurations.of(WavefrontConsumerConfiguration.class, SpelExpressionConverterConfiguration.class)); + AutoConfigurations.of(IntegrationAutoConfiguration.class, RestTemplateAutoConfiguration.class, + SpelExpressionConverterConfiguration.class, WavefrontConsumerConfiguration.class)); @Test public void proxyConnectionShouldBeUsedIfWavefrontProxyAddressSet() { runner.withPropertyValues("wavefront.metric-name=vehicle-location", "wavefront.source=vehicle-api", "wavefront.metric-expression=#jsonPath(payload,'$.mileage')", "wavefront.proxy-uri=http://wavefront-proxy.internal:2878", "wavefront.uri=", "wavefront.api-token=") - .run(context -> { + .run((context) -> { assertThat(context).hasSingleBean(ProxyConnectionWavefrontService.class); assertThat(context).doesNotHaveBean(DirectConnectionWavefrontService.class); }); @@ -55,9 +58,9 @@ public void proxyConnectionShouldBeUsedIfWavefrontProxyAddressAndDomainAndTokenS "wavefront.metric-expression=#jsonPath(payload,'$.mileage')", "wavefront.proxy-uri=http://wavefront-proxy.internal:2878", "wavefront.uri=https://my.wavefront.com", "wavefront.api-token=" + UUID.randomUUID()) - .run(context -> { + .run((context) -> { assertThat(context).hasFailed(); - final Throwable rootCause = NestedExceptionUtils.getRootCause(context.getStartupFailure()); + Throwable rootCause = NestedExceptionUtils.getRootCause(context.getStartupFailure()); assertThat(Objects.requireNonNull(rootCause).getLocalizedMessage()) .contains("Exactly one of 'proxy-uri' or the pair of ('uri' and 'api-token') must be set!"); }); @@ -69,7 +72,7 @@ public void directConnectionShouldBeUsedIfWavefrontDomainAndTokenSet() { .withPropertyValues("wavefront.metric-name=vehicle-location", "wavefront.source=vehicle-api", "wavefront.metric-expression=#jsonPath(payload,'$.mileage')", "wavefront.proxy-uri=", "wavefront.uri=https://my.wavefront.com", "wavefront.api-token=" + UUID.randomUUID()) - .run(context -> { + .run((context) -> { assertThat(context).hasSingleBean(DirectConnectionWavefrontService.class); assertThat(context).doesNotHaveBean(ProxyConnectionWavefrontService.class); }); @@ -81,7 +84,7 @@ public void applicationStartupShouldFailWithMeaningfulErrorMessageIfWavefrontPro .withPropertyValues("wavefront.metric-name=vehicle-location", "wavefront.source=vehicle-api", "wavefront.metric-expression=#jsonPath(payload,'$.mileage')", "wavefront.proxy-uri=", "wavefront.uri=", "wavefront.api-token=") - .run(context -> { + .run((context) -> { assertThat(context).hasFailed(); final Throwable rootCause = NestedExceptionUtils.getRootCause(context.getStartupFailure()); assertThat(Objects.requireNonNull(rootCause).getLocalizedMessage())