Make spring-wavefront-consumer as auto-config
* Fix all the Checkstyle violations
This commit is contained in:
@@ -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 java.util.function.Consumer;
|
||||
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.DirectConnectionW
|
||||
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<Message<?>> wavefrontConsumer(final WavefrontConsumerProperties properties,
|
||||
final WavefrontService service) {
|
||||
|
||||
return message -> {
|
||||
final WavefrontFormat wavefrontFormat = new WavefrontFormat(properties, message);
|
||||
final String formattedString = wavefrontFormat.getFormattedString();
|
||||
public Consumer<Message<?>> 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(),
|
||||
|
||||
@@ -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.util.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* The configuration properties for Wavefront consumer.
|
||||
*
|
||||
* @author Timo Salm
|
||||
*/
|
||||
@ConfigurationProperties("wavefront")
|
||||
@@ -104,7 +106,7 @@ public class 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 class WavefrontConsumerProperties {
|
||||
@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 class WavefrontConsumerProperties {
|
||||
|
||||
@NotNull
|
||||
public Expression getMetricExpression() {
|
||||
return metricExpression;
|
||||
return this.metricExpression;
|
||||
}
|
||||
|
||||
public void setMetricExpression(Expression metricExpression) {
|
||||
@@ -132,7 +134,7 @@ public class WavefrontConsumerProperties {
|
||||
}
|
||||
|
||||
public Expression getTimestampExpression() {
|
||||
return timestampExpression;
|
||||
return this.timestampExpression;
|
||||
}
|
||||
|
||||
public void setTimestampExpression(Expression timestampExpression) {
|
||||
@@ -140,7 +142,7 @@ public class WavefrontConsumerProperties {
|
||||
}
|
||||
|
||||
public Map<String, Expression> getTagExpression() {
|
||||
return tagExpression;
|
||||
return this.tagExpression;
|
||||
}
|
||||
|
||||
public void setTagExpression(Map<String, Expression> tagExpression) {
|
||||
@@ -148,7 +150,7 @@ public class WavefrontConsumerProperties {
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
@@ -156,7 +158,7 @@ public class WavefrontConsumerProperties {
|
||||
}
|
||||
|
||||
public String getApiToken() {
|
||||
return apiToken;
|
||||
return this.apiToken;
|
||||
}
|
||||
|
||||
public void setApiToken(String apiToken) {
|
||||
@@ -164,7 +166,7 @@ public class WavefrontConsumerProperties {
|
||||
}
|
||||
|
||||
public String getProxyUri() {
|
||||
return proxyUri;
|
||||
return this.proxyUri;
|
||||
}
|
||||
|
||||
public void setProxyUri(String proxyUri) {
|
||||
@@ -173,8 +175,10 @@ public class WavefrontConsumerProperties {
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.expression.spel.SpelEvaluationException;
|
||||
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 class WavefrontFormat {
|
||||
public String getFormattedString() {
|
||||
final Number metricValue = extractMetricValueFromPayload();
|
||||
|
||||
final Map<String, Object> pointTagsMap = extractPointTagsMapFromPayload(properties.getTagExpression(), message);
|
||||
final Map<String, Object> 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<String, Object> 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<String, Object> extractPointTagsMapFromPayload(Map<String, Expression> 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 @@ public class WavefrontFormat {
|
||||
|
||||
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 + ".");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* The Wavefront consumer classes.
|
||||
*/
|
||||
package org.springframework.cloud.fn.consumer.wavefront;
|
||||
@@ -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.http.HttpMethod;
|
||||
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 class DirectConnectionWavefrontService implements WavefrontService {
|
||||
|
||||
@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<String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.boot.web.client.RestTemplateBuilder;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* The Wavefront service API.
|
||||
*/
|
||||
package org.springframework.cloud.fn.consumer.wavefront.service;
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.cloud.fn.consumer.wavefront.WavefrontConsumerConfiguration
|
||||
@@ -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 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
"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<Message<?>> wavefrontConsumer;
|
||||
@@ -59,7 +59,7 @@ public class WavefrontConsumerConfigurationTest {
|
||||
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\"";
|
||||
@@ -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 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Timo Salm
|
||||
*/
|
||||
public class WavefrontConsumerPropertiesTest {
|
||||
public class WavefrontConsumerPropertiesTests {
|
||||
|
||||
private final Expression testExpression = new SpelExpressionParser().parseExpression("#jsonPath(payload,'$')");
|
||||
|
||||
@@ -51,7 +51,7 @@ public class WavefrontConsumerPropertiesTest {
|
||||
null, null, null, "proxy");
|
||||
final List<String> 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 @@ public class WavefrontConsumerPropertiesTest {
|
||||
"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<String> invalidMetricNameValues = Arrays.asList(" ", ":", "a B", "#");
|
||||
invalidMetricNameValues.forEach(invalidMetricNameValue -> {
|
||||
invalidMetricNameValues.forEach((invalidMetricNameValue) -> {
|
||||
properties.setMetricName(invalidMetricNameValue);
|
||||
assertThat(validator.validate(properties).isEmpty()).isFalse();
|
||||
});
|
||||
@@ -96,14 +96,14 @@ public class WavefrontConsumerPropertiesTest {
|
||||
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<String> invalidSourceValues = Arrays.asList(" ", ":", "a B", "#", "/", ",",
|
||||
createStringOfLength(129));
|
||||
invalidSourceValues.forEach(invalidSourceValue -> {
|
||||
invalidSourceValues.forEach((invalidSourceValue) -> {
|
||||
properties.setSource(invalidSourceValue);
|
||||
assertThat(validator.validate(properties).isEmpty()).isFalse();
|
||||
});
|
||||
@@ -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.Level;
|
||||
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.integration.json.JsonPathUtils;
|
||||
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 @@ public class WavefrontFormatTest {
|
||||
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 @@ public class WavefrontFormatTest {
|
||||
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 @@ public class WavefrontFormatTest {
|
||||
+ 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 @@ public class WavefrontFormatTest {
|
||||
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 @@ public class WavefrontFormatTest {
|
||||
|
||||
final List<String> invalidPointTagKeys = Arrays.asList(" ", ":", "a B", "#", "/", ",");
|
||||
|
||||
invalidPointTagKeys.forEach(invalidPointTagKey -> {
|
||||
invalidPointTagKeys.forEach((invalidPointTagKey) -> {
|
||||
final Map<String, Expression> 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");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 org.springframework.web.client.RestTemplate;
|
||||
|
||||
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 @@ public class DirectConnectionWavefrontServiceTest {
|
||||
wavefrontServerUri, wavefrontApiToken);
|
||||
service.send(metricInWavefrontFormat);
|
||||
|
||||
final ArgumentCaptor<HttpEntity> argument = ArgumentCaptor.forClass(HttpEntity.class);
|
||||
ArgumentCaptor<HttpEntity<?>> 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))
|
||||
@@ -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.boot.web.client.RestTemplateBuilder;
|
||||
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";
|
||||
@@ -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 java.util.UUID;
|
||||
|
||||
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 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @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 class WavefrontServiceConditionTest {
|
||||
"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 class WavefrontServiceConditionTest {
|
||||
.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 class WavefrontServiceConditionTest {
|
||||
.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())
|
||||
Reference in New Issue
Block a user