Skip to content

Commit

Permalink
New Relic Micrometer Spring Legacy Updates (#1635)
Browse files Browse the repository at this point in the history
Updates for New Relic properties added in Micrometer v1.3.0 related to
#1588
  • Loading branch information
neiljpowell authored and shakuzen committed Oct 30, 2019
1 parent c1c6110 commit cfe898e
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,26 @@
* {@link ConfigurationProperties} for configuring New Relic metrics export.
*
* @author Jon Schneider
* @author Neil Powell
* @since 1.0.0
*/
@ConfigurationProperties(prefix = "management.metrics.export.newrelic")
public class NewRelicProperties extends StepRegistryProperties {

/**
* Whether to send the meter name as the event type instead of using the 'event-type'
* configuration property value. Can be set to 'true' if New Relic guidelines are not
* being followed or event types consistent with previous Spring Boot releases are
* required.
*/
private boolean meterNameEventTypeEnabled;

/**
* The event type that should be published. This property will be ignored if
* 'meter-name-event-type-enabled' is set to 'true'.
*/
private String eventType = "SpringBootSample";

/**
* New Relic API key.
*/
Expand All @@ -42,6 +57,22 @@ public class NewRelicProperties extends StepRegistryProperties {
*/
private String uri = "https://insights-collector.newrelic.com";

public boolean isMeterNameEventTypeEnabled() {
return this.meterNameEventTypeEnabled;
}

public void setMeterNameEventTypeEnabled(boolean meterNameEventTypeEnabled) {
this.meterNameEventTypeEnabled = meterNameEventTypeEnabled;
}

public String getEventType() {
return this.eventType;
}

public void setEventType(String eventType) {
this.eventType = eventType;
}

public String getApiKey() {
return this.apiKey;
}
Expand All @@ -65,5 +96,4 @@ public String getUri() {
public void setUri(String uri) {
this.uri = uri;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Adapter to convert {@link NewRelicProperties} to a {@link NewRelicConfig}.
*
* @author Jon Schneider
* @author Neil Powell
*/
class NewRelicPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapter<NewRelicProperties>
implements NewRelicConfig {
Expand All @@ -30,6 +31,16 @@ class NewRelicPropertiesConfigAdapter extends StepRegistryPropertiesConfigAdapte
super(properties);
}

@Override
public boolean meterNameEventTypeEnabled() {
return get(NewRelicProperties::isMeterNameEventTypeEnabled, NewRelicConfig.super::meterNameEventTypeEnabled);
}

@Override
public String eventType() {
return get(NewRelicProperties::getEventType, NewRelicConfig.super::eventType);
}

@Override
public String apiKey() {
return get(NewRelicProperties::getApiKey, NewRelicConfig.super::apiKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright 2012-2019 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
*
* https://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 io.micrometer.spring.autoconfigure.export.newrelic;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.config.MissingRequiredConfigurationException;
import io.micrometer.newrelic.NewRelicConfig;
import io.micrometer.newrelic.NewRelicMeterRegistry;

/**
*
* Tests for {@link NewRelicMetricsExportAutoConfiguration}.
*
* @author Neil Powell
*/
class NewRelicMetricsExportAutoConfigurationTests {

private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

@AfterEach
void cleanUp() {
if (context != null) {
context.close();
}
}

@Test
void backsOffWithoutAClock() {
registerAndRefresh();
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(() -> context.getBean(NewRelicMeterRegistry.class));
}

@Test
void failsWithoutAnApiKey() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.account-id=12345");
Exception exception = assertThrows(BeanCreationException.class, () -> {
registerAndRefresh(BaseConfiguration.class);
});
assertThat(exception.getCause().getCause()).isInstanceOf(MissingRequiredConfigurationException.class);
assertThat(exception.getMessage()).contains("apiKey");
}

@Test
void failsWithoutAnAccountId() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde");
Exception exception = assertThrows(BeanCreationException.class, () -> {
registerAndRefresh(BaseConfiguration.class);
});
assertThat(exception.getCause().getCause()).isInstanceOf(MissingRequiredConfigurationException.class);
assertThat(exception.getMessage()).contains("accountId");
}

@Test
void failsToAutoConfigureWithoutEventType() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345",
"management.metrics.export.newrelic.event-type=");
Exception exception = assertThrows(BeanCreationException.class, () -> {
registerAndRefresh(BaseConfiguration.class);
});
assertThat(exception.getCause().getCause()).isInstanceOf(MissingRequiredConfigurationException.class);
assertThat(exception.getMessage()).contains("eventType");
}

@Test
void autoConfiguresWithEventTypeOverriden() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345",
"management.metrics.export.newrelic.event-type=wxyz");
registerAndRefresh(BaseConfiguration.class);
assertThat(context.getBean(NewRelicMeterRegistry.class)).isNotNull();
assertThat(context.getBean(Clock.class)).isNotNull();
assertThat(context.getBean(NewRelicConfig.class)).isNotNull();
}

@Test
void autoConfiguresWithMeterNameEventTypeEnabledAndWithoutEventType() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345",
"management.metrics.export.newrelic.event-type=",
"management.metrics.export.newrelic.meter-name-event-type-enabled=true");
registerAndRefresh(BaseConfiguration.class);
assertThat(context.getBean(NewRelicMeterRegistry.class)).isNotNull();
assertThat(context.getBean(Clock.class)).isNotNull();
assertThat(context.getBean(NewRelicConfig.class)).isNotNull();
}

@Test
void autoConfiguresWithAccountIdAndApiKey() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345");
registerAndRefresh(BaseConfiguration.class);
assertThat(context.getBean(NewRelicMeterRegistry.class)).isNotNull();
assertThat(context.getBean(Clock.class)).isNotNull();
assertThat(context.getBean(NewRelicConfig.class)).isNotNull();
}

@Test
void autoConfigurationCanBeDisabled() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.enabled=false");
registerAndRefresh(BaseConfiguration.class);
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(() -> context.getBean(NewRelicMeterRegistry.class));
}

@Test
void allowsConfigToBeCustomized() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345");
registerAndRefresh(CustomConfigConfiguration.class);
assertThat(context.getBean(NewRelicMeterRegistry.class)).isNotNull();
assertThat(context.getBean(NewRelicConfig.class)).isEqualTo(context.getBean("customConfig"));
}

@Test
void allowsRegistryToBeCustomized() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=12345");
registerAndRefresh(CustomRegistryConfiguration.class);
assertThat(context.getBean(NewRelicMeterRegistry.class)).isEqualTo(context.getBean("customRegistry"));
assertThat(context.getBean(NewRelicConfig.class)).isNotNull();
}

@Test
void stopsMeterRegistryWhenContextIsClosed() {
EnvironmentTestUtils.addEnvironment(context,
"management.metrics.export.newrelic.api-key=abcde",
"management.metrics.export.newrelic.account-id=abcde");
registerAndRefresh(BaseConfiguration.class);
NewRelicMeterRegistry registry = context.getBean(NewRelicMeterRegistry.class);
assertThat(registry.isClosed()).isFalse();
context.close();
assertThat(registry.isClosed()).isTrue();
}

private void registerAndRefresh(Class<?>... configurationClasses) {
if (configurationClasses.length > 0) {
context.register(configurationClasses);
}
context.register(NewRelicMetricsExportAutoConfiguration.class);
context.refresh();
}

@Configuration
static class BaseConfiguration {
@Bean
public Clock clock() {
return Clock.SYSTEM;
}
}

@Configuration
@Import(BaseConfiguration.class)
static class CustomConfigConfiguration {
@Bean
NewRelicConfig customConfig() {
return (key) -> {
if ("newrelic.accountId".equals(key)) {
return "abcde";
}
if ("newrelic.apiKey".equals(key)) {
return "12345";
}
return null;
};
}
}

@Configuration
@Import(BaseConfiguration.class)
static class CustomRegistryConfiguration {
@Bean
NewRelicMeterRegistry customRegistry(NewRelicConfig config, Clock clock) {
return new NewRelicMeterRegistry(config, clock);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2012-2019 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
*
* https://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 io.micrometer.spring.autoconfigure.export.newrelic;

import io.micrometer.newrelic.NewRelicConfig;
import org.junit.jupiter.api.Test;

import io.micrometer.spring.autoconfigure.export.properties.StepRegistryPropertiesTest;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link NewRelicProperties}.
*
* @author Neil Powell
*/
public class NewRelicPropertiesTests extends StepRegistryPropertiesTest {

@Test
public void defaultValuesAreConsistent() {
NewRelicProperties properties = new NewRelicProperties();
NewRelicConfig config = (key) -> null;
assertStepRegistryDefaultValues(properties, config);
// apiKey and account are mandatory
assertThat(properties.getUri()).isEqualTo(config.uri());
assertThat(properties.isMeterNameEventTypeEnabled()).isEqualTo(config.meterNameEventTypeEnabled());
}

@Test
void eventTypeDefaultValueIsOverriden() {
NewRelicProperties properties = new NewRelicProperties();
NewRelicConfig config = (key) -> null;
assertThat(properties.getEventType()).isNotEqualTo(config.eventType());
assertThat(properties.getEventType()).isEqualTo("SpringBootSample");
assertThat(config.eventType()).isEqualTo("MicrometerSample");
}

}

0 comments on commit cfe898e

Please sign in to comment.