diff --git a/spring-cloud-stream-metrics/src/main/java/org/springframework/cloud/stream/metrics/ApplicationMetricsProperties.java b/spring-cloud-stream-metrics/src/main/java/org/springframework/cloud/stream/metrics/ApplicationMetricsProperties.java index 04c9fe086..21e038657 100644 --- a/spring-cloud-stream-metrics/src/main/java/org/springframework/cloud/stream/metrics/ApplicationMetricsProperties.java +++ b/spring-cloud-stream-metrics/src/main/java/org/springframework/cloud/stream/metrics/ApplicationMetricsProperties.java @@ -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; } } } diff --git a/spring-cloud-stream-metrics/src/test/java/org/springframework/cloud/stream/metrics/ApplicationMetricsExporterTests.java b/spring-cloud-stream-metrics/src/test/java/org/springframework/cloud/stream/metrics/ApplicationMetricsExporterTests.java index 7be45120a..a5caa1585 100644 --- a/spring-cloud-stream-metrics/src/test/java/org/springframework/cloud/stream/metrics/ApplicationMetricsExporterTests.java +++ b/spring-cloud-stream-metrics/src/test/java/org/springframework/cloud/stream/metrics/ApplicationMetricsExporterTests.java @@ -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(