org.springframework.cloud.stream.metrics.ApplicationMetricsExporterTests.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.cloud.stream.metrics.ApplicationMetricsExporterTests.java

Source

/*
 * Copyright 2017 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.stream.metrics;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.assertj.core.api.Assertions;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.stream.metrics.config.Emitter;
import org.springframework.cloud.stream.test.binder.MessageCollector;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.messaging.Message;
import org.springframework.util.CollectionUtils;

/**
 * @author Vinicius Carvalho
 */
public class ApplicationMetricsExporterTests {

    @BeforeClass
    public static void setSystemProps() {
        System.setProperty("SPRING_TEST_ENV_SYNTAX", "testing");
    }

    @AfterClass
    public static void unsetSystemProps() {
        System.clearProperty("SPRING_TEST_ENV_SYNTAX");
    }

    @Test(expected = NoSuchBeanDefinitionException.class)
    public void checkDisabledConfiguration() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false");
        try {
            applicationContext.getBean(Emitter.class);
        } catch (Exception e) {
            throw e;
        } finally {
            applicationContext.close();
        }

    }

    @Test
    public void defaultIncludes() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--spring.metrics.export.delay-millis=500",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        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()));
        Assert.assertEquals("application", applicationMetrics.getName());
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    @Test
    public void customAppNameAndIndex() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--spring.metrics.export.delay-millis=500",
                "--spring.application.name=foo",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        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()));
        Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertEquals("foo", applicationMetrics.getName());
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    @Test
    public void usingPrefix() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--spring.metrics.export.delay-millis=500",
                "--spring.cloud.stream.metrics.prefix=foo",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        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()));
        Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertEquals("foo.application", applicationMetrics.getName());
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    @Test
    public void includesExcludesDefaultConfig() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--spring.metrics.export.delay-millis=500",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo",
                "--spring.metrics.export.includes=mem**", "--spring.metrics.export.excludes=integration**");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        Assert.assertNotNull(message);
        ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
        ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
                ApplicationMetrics.class);
        Assert.assertFalse(
                contains("integration.channel.errorChannel.errorRate.mean", applicationMetrics.getMetrics()));
        Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    @Test
    public void includesExcludesWithApplicationMetricsConfiguration() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false",
                "--spring.metrics.export.triggers.application.delay-millis=500",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo",
                "--spring.metrics.export.triggers.application.includes=mem**",
                "--spring.metrics.export.triggers.application.excludes=integration**");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        Assert.assertNotNull(message);
        ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
        ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
                ApplicationMetrics.class);
        Assert.assertFalse(
                contains("integration.channel.errorChannel.errorRate.mean", applicationMetrics.getMetrics()));
        Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    @Test
    public void includesExcludesWithProperties() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--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=java**,spring.test.env**");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        Assert.assertNotNull(message);
        ObjectMapper mapper = applicationContext.getBean(ObjectMapper.class);
        ApplicationMetrics applicationMetrics = mapper.readValue((String) message.getPayload(),
                ApplicationMetrics.class);
        Assert.assertFalse(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertTrue(
                contains("integration.channel.errorChannel.errorRate.mean", applicationMetrics.getMetrics()));
        Assert.assertFalse(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        Assert.assertTrue(applicationMetrics.getProperties().get("spring.test.env.syntax").equals("testing"));
        applicationContext.close();
    }

    @Test
    public void propertiesWithPlaceholdersAndExpressions() throws Exception {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--PLATFORM_APP_NAME=123-name-foo",
                "--PLATFORM_APP_ID=123-id-bar",
                "--spring.cloud.application.guid=${PLATFORM_APP_NAME}.${PLATFORM_APP_ID}",
                "--spring.cloud.application.guid.expression=#{'${PLATFORM_APP_NAME}' + '..' + '${PLATFORM_APP_ID}'}",
                "--spring.cloud.application.guid.default.prop=${app.name.not.found:time-source}",
                "--spring.cloud.application.guid.default.env=${APP_NAME_NOT_FOUND:time-source}",
                "--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(10, TimeUnit.SECONDS);
        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"))
                .isEqualTo("123-name-foo.123-id-bar");
        Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid.expression"))
                .isEqualTo("123-name-foo..123-id-bar");
        Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid.default.prop"))
                .isEqualTo("time-source");
        Assertions.assertThat(applicationMetrics.getProperties().get("spring.cloud.application.guid.default.env"))
                .isEqualTo("time-source");
        Assert.assertFalse(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        Assert.assertTrue(applicationMetrics.getProperties().get("spring.test.env.syntax").equals("testing"));
        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(10,
                    TimeUnit.SECONDS);
            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(BinderExporterApplication.class,
                "--server.port=0", "--spring.jmx.enabled=false", "--spring.metrics.export.delay-millis=500",
                "--spring.application.name=foo",
                "--spring.cloud.stream.bindings." + Emitter.APPLICATION_METRICS + ".destination=foo",
                "--spring.cloud.stream.metrics.key=foobarfoo");
        Emitter emitterSource = applicationContext.getBean(Emitter.class);
        MessageCollector collector = applicationContext.getBean(MessageCollector.class);
        Message<?> message = collector.forChannel(emitterSource.applicationMetrics()).poll(10, TimeUnit.SECONDS);
        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()));
        Assert.assertTrue(contains("mem", applicationMetrics.getMetrics()));
        Assert.assertEquals("foobarfoo", applicationMetrics.getName());
        Assert.assertTrue(CollectionUtils.isEmpty(applicationMetrics.getProperties()));
        applicationContext.close();
    }

    private boolean contains(String metric, Collection<Metric<?>> metrics) {
        boolean contains = false;
        for (Metric<?> entry : metrics) {
            contains = entry.getName().equals(metric);
            if (contains) {
                break;
            }
        }
        return contains;
    }

    @EnableAutoConfiguration
    public static class BinderExporterApplication {

    }

}