Observe priority when populating the exported properties

Fix #909

- If a property is already present in the exported list
  it means that it's been put there by a higher priority
  source - so we can skip it
This commit is contained in:
Marius Bogoevici
2017-04-10 19:19:55 -04:00
committed by Vinicius Carvalho
parent ab76178b82
commit 523a3cfdab
2 changed files with 49 additions and 15 deletions

View File

@@ -129,22 +129,26 @@ public class ApplicationMetricsProperties
EnumerablePropertySource<?> e = (EnumerablePropertySource<?>) source;
for (String propertyName : e.getPropertyNames()) {
RelaxedNames relaxedNames = new RelaxedNames(propertyName);
relaxedLoop: for (String relaxedPropertyName : relaxedNames) {
if (isMatch(relaxedPropertyName, this.properties, null)) {
Object value = source.getProperty(propertyName);
String stringValue = ObjectUtils.nullSafeToString(value);
Object exportedValue = null;
if (value != null) {
exportedValue = stringValue.startsWith("#{")
? beanExpressionResolver.evaluate(
environment.resolvePlaceholders(stringValue), expressionContext)
: environment.resolvePlaceholders(stringValue);
String canonicalFormat = RelaxedPropertiesUtils.findCanonicalFormat(relaxedNames);
// omit this property if already populated from a
// higher priority source
if (!this.exportProperties.containsKey(canonicalFormat)) {
relaxedLoop: for (String relaxedPropertyName : relaxedNames) {
if (isMatch(relaxedPropertyName, this.properties, null)) {
Object value = source.getProperty(propertyName);
String stringValue = ObjectUtils.nullSafeToString(value);
Object exportedValue = null;
if (value != null) {
exportedValue = stringValue.startsWith("#{")
? beanExpressionResolver.evaluate(
environment.resolvePlaceholders(stringValue), expressionContext)
: environment.resolvePlaceholders(stringValue);
}
this.exportProperties.put(
canonicalFormat,
exportedValue);
break relaxedLoop;
}
this.exportProperties.put(
RelaxedPropertiesUtils
.findCanonicalFormat(relaxedNames),
exportedValue);
break relaxedLoop;
}
}
}

View File

@@ -242,6 +242,36 @@ public class ApplicationMetricsExporterTests {
applicationContext.close();
}
@Test
public void propertiesFromLowerPrioritySourcesOverridden() throws Exception {
System.setProperty("spring.cloud.application.guid.test.metrics", "lowPriority");
try {
ConfigurableApplicationContext applicationContext = SpringApplication.run(
BinderExporterApplication.class,
"--server.port=0",
"--spring.jmx.enabled=false",
"--spring.cloud.application.guid.test.metrics=highPriority",
"--spring.metrics.export.delay-millis=500",
"--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo",
"--spring.metrics.export.includes=integration**",
"--spring.cloud.stream.metrics.properties=spring**");
Emitter emitterSource = applicationContext.getBean(Emitter.class);
MessageCollector collector = applicationContext.getBean(MessageCollector.class);
Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(1000,
TimeUnit.MILLISECONDS);
Assert.assertNotNull(message);
ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(), ApplicationMetrics.class);
Assert.assertTrue(contains("integration.channel.errorChannel.errorRate.mean",
applicationMetrics.getMetrics()));
Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid.test.metrics"))
.isEqualTo("highPriority");
applicationContext.close();
} finally {
System.clearProperty("spring.cloud.application.guid.test.metrics");
}
}
@Test
public void overrideAppName() throws Exception {
ConfigurableApplicationContext applicationContext = SpringApplication.run(