24 changed files with 1242 additions and 91 deletions
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.autoconfigure; |
||||
|
||||
import java.lang.annotation.Documented; |
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
|
||||
import org.springframework.context.annotation.Conditional; |
||||
|
||||
/** |
||||
* {@link Conditional} that checks whether or not a default info contributor is enabled. |
||||
* Matches if the value of the {@code management.info.<name>.enabled} property is |
||||
* {@code true}. Otherwise, matches if the value of the |
||||
* {@code management.info.defaults.enabled} property is {@code true} or if it is not |
||||
* configured. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Target({ElementType.TYPE, ElementType.METHOD}) |
||||
@Documented |
||||
@Conditional(OnEnabledInfoContributorCondition.class) |
||||
public @interface ConditionalOnEnabledInfoContributor { |
||||
|
||||
/** |
||||
* The name of the info contributor. |
||||
* @return the name of the info contributor |
||||
*/ |
||||
String value(); |
||||
|
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* Copyright 2012-2015 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.boot.actuate.autoconfigure; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import org.springframework.boot.actuate.info.EnvironmentInfoContributor; |
||||
import org.springframework.boot.actuate.info.InfoContributor; |
||||
import org.springframework.boot.actuate.info.SimpleInfoContributor; |
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter; |
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore; |
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; |
||||
import org.springframework.boot.autoconfigure.info.GitInfo; |
||||
import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
|
||||
/** |
||||
* {@link EnableAutoConfiguration Auto-configuration} for standard {@link InfoContributor}s. |
||||
* |
||||
* @author Meang Akira Tanaka |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
@Configuration |
||||
@AutoConfigureAfter(ProjectInfoAutoConfiguration.class) |
||||
@AutoConfigureBefore(EndpointAutoConfiguration.class) |
||||
public class InfoContributorAutoConfiguration { |
||||
|
||||
/** |
||||
* The default order for the core {@link InfoContributor} beans. |
||||
*/ |
||||
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10; |
||||
|
||||
@Bean |
||||
@ConditionalOnEnabledInfoContributor("env") |
||||
@Order(DEFAULT_ORDER) |
||||
public EnvironmentInfoContributor envInfoContributor(ConfigurableEnvironment environment) { |
||||
return new EnvironmentInfoContributor(environment); |
||||
} |
||||
|
||||
@Bean |
||||
@ConditionalOnEnabledInfoContributor("git") |
||||
@ConditionalOnSingleCandidate(GitInfo.class) |
||||
@Order(DEFAULT_ORDER) |
||||
public InfoContributor gitInfoContributor(GitInfo gitInfo) throws IOException { |
||||
return new SimpleInfoContributor("git", gitInfo); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.autoconfigure; |
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome; |
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition; |
||||
import org.springframework.boot.bind.RelaxedPropertyResolver; |
||||
import org.springframework.context.annotation.ConditionContext; |
||||
import org.springframework.core.annotation.AnnotationAttributes; |
||||
import org.springframework.core.type.AnnotatedTypeMetadata; |
||||
|
||||
/** |
||||
* Base endpoint element condition. An element can be disabled globally via the |
||||
* `defaults` name or individually via the name of the element. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
abstract class OnEnabledEndpointElementCondition extends SpringBootCondition { |
||||
|
||||
private final String prefix; |
||||
|
||||
private final Class<?> annotationType; |
||||
|
||||
OnEnabledEndpointElementCondition(String prefix, Class<?> annotationType) { |
||||
this.prefix = prefix; |
||||
this.annotationType = annotationType; |
||||
} |
||||
|
||||
protected String getEndpointElementOutcomeMessage(String name, boolean match) { |
||||
return "The endpoint element " + name + " is " + (match ? "enabled" : "disabled"); |
||||
} |
||||
|
||||
protected String getDefaultEndpointElementOutcomeMessage(boolean match) { |
||||
return "All default endpoint elements are " + (match ? "enabled" : "disabled") |
||||
+ " by default"; |
||||
} |
||||
|
||||
@Override |
||||
public ConditionOutcome getMatchOutcome(ConditionContext context, |
||||
AnnotatedTypeMetadata metadata) { |
||||
AnnotationAttributes annotationAttributes = AnnotationAttributes |
||||
.fromMap(metadata.getAnnotationAttributes(this.annotationType.getName())); |
||||
String endpointName = annotationAttributes.getString("value"); |
||||
ConditionOutcome outcome = getEndpointOutcome(context, endpointName); |
||||
if (outcome != null) { |
||||
return outcome; |
||||
} |
||||
return getDefaultEndpointsOutcome(context); |
||||
} |
||||
|
||||
protected ConditionOutcome getEndpointOutcome(ConditionContext context, |
||||
String endpointName) { |
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( |
||||
context.getEnvironment(), this.prefix + endpointName + "."); |
||||
if (resolver.containsProperty("enabled")) { |
||||
boolean match = resolver.getProperty("enabled", Boolean.class, true); |
||||
return new ConditionOutcome(match, |
||||
getEndpointElementOutcomeMessage(endpointName, match)); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
protected ConditionOutcome getDefaultEndpointsOutcome(ConditionContext context) { |
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( |
||||
context.getEnvironment(), this.prefix + "defaults."); |
||||
boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); |
||||
return new ConditionOutcome(match, getDefaultEndpointElementOutcomeMessage(match)); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.autoconfigure; |
||||
|
||||
import org.springframework.context.annotation.Condition; |
||||
|
||||
/** |
||||
* {@link Condition} that checks if a info indicator is enabled. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
class OnEnabledInfoContributorCondition extends OnEnabledEndpointElementCondition { |
||||
|
||||
OnEnabledInfoContributorCondition() { |
||||
super("management.info.", ConditionalOnEnabledInfoContributor.class); |
||||
} |
||||
|
||||
@Override |
||||
protected String getEndpointElementOutcomeMessage(String name, boolean match) { |
||||
return "The info contributor " + name + " is " + (match ? "enabled" : "disabled"); |
||||
} |
||||
|
||||
@Override |
||||
protected String getDefaultEndpointElementOutcomeMessage(boolean match) { |
||||
return "All default info contributors are " + (match ? "enabled" : "disabled") |
||||
+ " by default"; |
||||
} |
||||
} |
||||
@ -0,0 +1,78 @@
@@ -0,0 +1,78 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.info; |
||||
|
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.boot.bind.PropertiesConfigurationFactory; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.validation.BindException; |
||||
|
||||
/** |
||||
* A base {@link InfoContributor} implementation working on the {@link Environment}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
public abstract class AbstractEnvironmentInfoContributor implements InfoContributor { |
||||
|
||||
private final ConfigurableEnvironment environment; |
||||
|
||||
protected AbstractEnvironmentInfoContributor(ConfigurableEnvironment environment) { |
||||
this.environment = environment; |
||||
} |
||||
|
||||
public final ConfigurableEnvironment getEnvironment() { |
||||
return this.environment; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Extract the keys from the environment using the specified {@code prefix}. The |
||||
* prefix won't be included. |
||||
* <p>Any key that starts with the {@code prefix} will be included |
||||
* @param prefix the prefix to use |
||||
* @return the keys from the environment matching the prefix |
||||
*/ |
||||
protected Map<String, Object> extract(String prefix) { |
||||
Map<String, Object> content = new LinkedHashMap<String, Object>(); |
||||
bindEnvironmentTo(prefix, content); |
||||
return content; |
||||
} |
||||
|
||||
/** |
||||
* Bind the specified {@code target} from the environment using the {@code prefix}. |
||||
* <p>Any key that starts with the {@code prefix} will be bound to the {@code target}. |
||||
* @param prefix the prefix to use |
||||
* @param target the object to bind to |
||||
*/ |
||||
protected void bindEnvironmentTo(String prefix, Object target) { |
||||
PropertiesConfigurationFactory<Object> factory = |
||||
new PropertiesConfigurationFactory<Object>(target); |
||||
factory.setTargetName(prefix); |
||||
factory.setPropertySources(this.environment.getPropertySources()); |
||||
try { |
||||
factory.bindPropertiesToTarget(); |
||||
} |
||||
catch (BindException ex) { |
||||
throw new IllegalStateException("Cannot bind to " + target, ex); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
/* |
||||
* Copyright 2012-2015 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.boot.actuate.info; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
|
||||
/** |
||||
* A {@link InfoContributor} that provides all environment entries prefixed with |
||||
* info. |
||||
* |
||||
* @author Meang Akira Tanaka |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
public class EnvironmentInfoContributor extends AbstractEnvironmentInfoContributor { |
||||
|
||||
private final Map<String, Object> info; |
||||
|
||||
public EnvironmentInfoContributor(ConfigurableEnvironment environment) { |
||||
super(environment); |
||||
this.info = extract("info"); |
||||
} |
||||
|
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
builder.withDetails(this.info); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,132 @@
@@ -0,0 +1,132 @@
|
||||
/* |
||||
* Copyright 2012-2015 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.boot.actuate.info; |
||||
|
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter; |
||||
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include; |
||||
|
||||
/** |
||||
* Carries information of the application. |
||||
* <p> |
||||
* Each detail element can singular or a hierarchical object such as a pojo or a nested |
||||
* Map. |
||||
* |
||||
* @author Meang Akira Tanaka |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
@JsonInclude(Include.NON_EMPTY) |
||||
public final class Info { |
||||
|
||||
private final Map<String, Object> details; |
||||
|
||||
private Info(Builder builder) { |
||||
this.details = new LinkedHashMap<String, Object>(); |
||||
this.details.putAll(builder.content); |
||||
} |
||||
|
||||
/** |
||||
* Return the content. |
||||
* @return the details of the info or an empty map. |
||||
*/ |
||||
@JsonAnyGetter |
||||
public Map<String, Object> getDetails() { |
||||
return this.details; |
||||
} |
||||
|
||||
public Object get(String id) { |
||||
return this.details.get(id); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public <T> T get(String id, Class<T> type) { |
||||
Object value = get(id); |
||||
if (value != null && type != null && !type.isInstance(value)) { |
||||
throw new IllegalStateException("Info entry is not of required type [" + type.getName() + "]: " + value); |
||||
} |
||||
return (T) value; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (obj == this) { |
||||
return true; |
||||
} |
||||
if (obj != null && obj instanceof Info) { |
||||
Info other = (Info) obj; |
||||
return this.details.equals(other.details); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return this.details.hashCode(); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return getDetails().toString(); |
||||
} |
||||
|
||||
/** |
||||
* Builder for creating immutable {@link Info} instances. |
||||
*/ |
||||
public static class Builder { |
||||
|
||||
private final Map<String, Object> content; |
||||
|
||||
public Builder() { |
||||
this.content = new LinkedHashMap<String, Object>(); |
||||
} |
||||
|
||||
/** |
||||
* Record detail using {@code key} and {@code value}. |
||||
* @param key the detail key |
||||
* @param data the detail data |
||||
* @return this {@link Builder} instance |
||||
*/ |
||||
public Builder withDetail(String key, Object data) { |
||||
this.content.put(key, data); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Record several details. |
||||
* @param details the details |
||||
* @return this {@link Builder} instance |
||||
* @see #withDetail(String, Object) |
||||
*/ |
||||
public Builder withDetails(Map<String, Object> details) { |
||||
this.content.putAll(details); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@link Info} instance base on the state of this builder. |
||||
* @return a new {@link Info} instance |
||||
*/ |
||||
public Info build() { |
||||
return new Info(this); |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.info; |
||||
|
||||
/** |
||||
* Contributes additional info details. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
public interface InfoContributor { |
||||
|
||||
/** |
||||
* Contributes additional details using the specified {@link Info.Builder Builder}. |
||||
* @param builder the builder to use |
||||
*/ |
||||
void contribute(Info.Builder builder); |
||||
|
||||
} |
||||
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.info; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* A simple {@link InfoContributor} that exposes a single detail. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 1.4.0 |
||||
*/ |
||||
public class SimpleInfoContributor implements InfoContributor { |
||||
|
||||
private final String prefix; |
||||
|
||||
private final Object detail; |
||||
|
||||
public SimpleInfoContributor(String prefix, Object detail) { |
||||
Assert.notNull(prefix, "Prefix must not be null"); |
||||
this.prefix = prefix; |
||||
this.detail = detail; |
||||
} |
||||
|
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
if (this.detail != null) { |
||||
builder.withDetail(this.prefix, this.detail); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.autoconfigure; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.boot.actuate.info.Info; |
||||
import org.springframework.boot.actuate.info.InfoContributor; |
||||
import org.springframework.boot.autoconfigure.info.GitInfo; |
||||
import org.springframework.boot.test.EnvironmentTestUtils; |
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link InfoContributorAutoConfiguration}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
public class InfoContributorAutoConfigurationTests { |
||||
|
||||
private AnnotationConfigApplicationContext context; |
||||
|
||||
@After |
||||
public void close() { |
||||
if (this.context != null) { |
||||
this.context.close(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void disableEnvContributor() { |
||||
load("management.info.env.enabled:false"); |
||||
Map<String, InfoContributor> beans = this.context |
||||
.getBeansOfType(InfoContributor.class); |
||||
assertThat(beans).hasSize(0); |
||||
} |
||||
|
||||
@Test |
||||
public void defaultInfoContributorsDisabled() { |
||||
load("management.info.defaults.enabled:false"); |
||||
Map<String, InfoContributor> beans = this.context |
||||
.getBeansOfType(InfoContributor.class); |
||||
assertThat(beans).hasSize(0); |
||||
} |
||||
|
||||
@Test |
||||
public void defaultInfoContributorsDisabledWithCustomOne() { |
||||
load(CustomInfoProviderConfiguration.class, |
||||
"management.info.defaults.enabled:false"); |
||||
Map<String, InfoContributor> beans = this.context |
||||
.getBeansOfType(InfoContributor.class); |
||||
assertThat(beans).hasSize(1); |
||||
assertThat(this.context.getBean("customInfoContributor")) |
||||
.isSameAs(beans.values().iterator().next()); |
||||
} |
||||
|
||||
@Test |
||||
public void gitInfoAvailable() { |
||||
load(GitInfoConfiguration.class); |
||||
Map<String, InfoContributor> beans = this.context |
||||
.getBeansOfType(InfoContributor.class); |
||||
assertThat(beans).containsKeys("gitInfoContributor"); |
||||
} |
||||
|
||||
private void load(String... environment) { |
||||
load(null, environment); |
||||
} |
||||
|
||||
private void load(Class<?> config, String... environment) { |
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
||||
if (config != null) { |
||||
context.register(config); |
||||
} |
||||
context.register(InfoContributorAutoConfiguration.class); |
||||
EnvironmentTestUtils.addEnvironment(context, environment); |
||||
context.refresh(); |
||||
this.context = context; |
||||
} |
||||
|
||||
@Configuration |
||||
static class GitInfoConfiguration { |
||||
|
||||
@Bean |
||||
public GitInfo gitInfo() { |
||||
GitInfo gitInfo = new GitInfo(); |
||||
gitInfo.setBranch("master"); |
||||
gitInfo.getCommit().setId("abcdefg"); |
||||
return gitInfo; |
||||
} |
||||
} |
||||
|
||||
@Configuration |
||||
static class CustomInfoProviderConfiguration { |
||||
|
||||
@Bean |
||||
public InfoContributor customInfoContributor() { |
||||
return new InfoContributor() { |
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.endpoint.mvc; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; |
||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; |
||||
import org.springframework.boot.actuate.endpoint.InfoEndpoint; |
||||
import org.springframework.boot.actuate.endpoint.mvc.InfoMvcEndpointTests.TestConfiguration; |
||||
import org.springframework.boot.actuate.info.Info; |
||||
import org.springframework.boot.actuate.info.InfoContributor; |
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; |
||||
import org.springframework.boot.test.SpringApplicationConfiguration; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.test.context.TestPropertySource; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
import org.springframework.test.context.web.WebAppConfiguration; |
||||
import org.springframework.test.web.servlet.MockMvc; |
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
|
||||
import static org.hamcrest.Matchers.containsString; |
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
||||
/** |
||||
* Tests for {@link InfoMvcEndpointTests} |
||||
* |
||||
* @author Meang Akira Tanaka |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@SpringApplicationConfiguration(classes = {TestConfiguration.class}) |
||||
@WebAppConfiguration |
||||
@TestPropertySource(properties = {"info.app.name=MyService"}) |
||||
public class InfoMvcEndpointTests { |
||||
@Autowired |
||||
private WebApplicationContext context; |
||||
|
||||
private MockMvc mvc; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
|
||||
this.context.getBean(InfoEndpoint.class).setEnabled(true); |
||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); |
||||
} |
||||
|
||||
@Test |
||||
public void home() throws Exception { |
||||
this.mvc.perform(get("/info")).andExpect(status().isOk()) |
||||
.andExpect(content().string( |
||||
containsString("\"beanName1\":{\"key11\":\"value11\",\"key12\":\"value12\"}") |
||||
)) |
||||
.andExpect(content().string( |
||||
containsString("\"beanName2\":{\"key21\":\"value21\",\"key22\":\"value22\"}"))); |
||||
} |
||||
|
||||
@Import({JacksonAutoConfiguration.class, |
||||
HttpMessageConvertersAutoConfiguration.class, |
||||
EndpointWebMvcAutoConfiguration.class, |
||||
WebMvcAutoConfiguration.class, |
||||
ManagementServerPropertiesAutoConfiguration.class}) |
||||
@Configuration |
||||
public static class TestConfiguration { |
||||
|
||||
@Bean |
||||
public InfoEndpoint endpoint() { |
||||
return new InfoEndpoint(Arrays.asList(beanName1(), beanName2())); |
||||
} |
||||
|
||||
@Bean |
||||
public InfoContributor beanName1() { |
||||
return new InfoContributor() { |
||||
|
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
Map<String, Object> content = new LinkedHashMap<String, Object>(); |
||||
content.put("key11", "value11"); |
||||
content.put("key12", "value12"); |
||||
builder.withDetail("beanName1", content); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Bean |
||||
public InfoContributor beanName2() { |
||||
return new InfoContributor() { |
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
Map<String, Object> content = new LinkedHashMap<String, Object>(); |
||||
content.put("key21", "value21"); |
||||
content.put("key22", "value22"); |
||||
builder.withDetail("beanName2", content); |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.endpoint.mvc; |
||||
|
||||
import java.util.Collections; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; |
||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; |
||||
import org.springframework.boot.actuate.endpoint.InfoEndpoint; |
||||
import org.springframework.boot.actuate.endpoint.mvc.InfoMvcEndpointWithoutAnyInfoProvidersTests.TestConfiguration; |
||||
import org.springframework.boot.actuate.info.InfoContributor; |
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; |
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; |
||||
import org.springframework.boot.test.SpringApplicationConfiguration; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||
import org.springframework.test.context.web.WebAppConfiguration; |
||||
import org.springframework.test.web.servlet.MockMvc; |
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders; |
||||
import org.springframework.web.context.WebApplicationContext; |
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; |
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
||||
|
||||
/** |
||||
* Tests for {@link InfoMvcEndpointWithoutAnyInfoProvidersTests} |
||||
* |
||||
* @author Meang Akira Tanaka |
||||
*/ |
||||
@RunWith(SpringJUnit4ClassRunner.class) |
||||
@SpringApplicationConfiguration(classes = {TestConfiguration.class}) |
||||
@WebAppConfiguration |
||||
public class InfoMvcEndpointWithoutAnyInfoProvidersTests { |
||||
@Autowired |
||||
private WebApplicationContext context; |
||||
|
||||
private MockMvc mvc; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
|
||||
this.context.getBean(InfoEndpoint.class).setEnabled(true); |
||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); |
||||
} |
||||
|
||||
@Test |
||||
public void home() throws Exception { |
||||
this.mvc.perform(get("/info")).andExpect(status().isOk()); |
||||
} |
||||
|
||||
@Import({JacksonAutoConfiguration.class, |
||||
HttpMessageConvertersAutoConfiguration.class, |
||||
EndpointWebMvcAutoConfiguration.class, |
||||
WebMvcAutoConfiguration.class, |
||||
ManagementServerPropertiesAutoConfiguration.class}) |
||||
@Configuration |
||||
public static class TestConfiguration { |
||||
|
||||
@Bean |
||||
public InfoEndpoint endpoint() { |
||||
return new InfoEndpoint(Collections.<InfoContributor>emptyList()); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.info; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.boot.test.EnvironmentTestUtils; |
||||
import org.springframework.core.env.ConfigurableEnvironment; |
||||
import org.springframework.core.env.StandardEnvironment; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link EnvironmentInfoContributor} |
||||
*/ |
||||
public class EnvironmentInfoContributorTests { |
||||
|
||||
private final StandardEnvironment environment = new StandardEnvironment(); |
||||
|
||||
@Test |
||||
public void extractOnlyInfoProperty() { |
||||
EnvironmentTestUtils.addEnvironment(this.environment, |
||||
"info.app=my app", "info.version=1.0.0", "foo=bar"); |
||||
|
||||
Info actual = contributeFrom(this.environment); |
||||
assertThat(actual.get("app", String.class)).isEqualTo("my app"); |
||||
assertThat(actual.get("version", String.class)).isEqualTo("1.0.0"); |
||||
assertThat(actual.getDetails().size()).isEqualTo(2); |
||||
} |
||||
|
||||
@Test |
||||
public void extractNoEntry() { |
||||
EnvironmentTestUtils.addEnvironment(this.environment, "foo=bar"); |
||||
|
||||
Info actual = contributeFrom(this.environment); |
||||
assertThat(actual.getDetails().size()).isEqualTo(0); |
||||
} |
||||
|
||||
private static Info contributeFrom(ConfigurableEnvironment environment) { |
||||
EnvironmentInfoContributor contributor = new EnvironmentInfoContributor(environment); |
||||
Info.Builder builder = new Info.Builder(); |
||||
contributor.contribute(builder); |
||||
return builder.build(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
/* |
||||
* Copyright 2012-2016 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.boot.actuate.info; |
||||
|
||||
import org.junit.Rule; |
||||
import org.junit.Test; |
||||
import org.junit.rules.ExpectedException; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link SimpleInfoContributor}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
public class SimpleInfoContributorTests { |
||||
|
||||
@Rule |
||||
public final ExpectedException thrown = ExpectedException.none(); |
||||
|
||||
@Test |
||||
public void prefixIsMandatory() { |
||||
this.thrown.expect(IllegalArgumentException.class); |
||||
new SimpleInfoContributor(null, new Object()); |
||||
} |
||||
|
||||
@Test |
||||
public void mapSimpleObject() { |
||||
Object o = new Object(); |
||||
Info info = contributeFrom("test", o); |
||||
assertThat(info.get("test")).isSameAs(o); |
||||
} |
||||
|
||||
|
||||
private static Info contributeFrom(String prefix, Object detail) { |
||||
SimpleInfoContributor contributor = new SimpleInfoContributor(prefix, detail); |
||||
Info.Builder builder = new Info.Builder(); |
||||
contributor.contribute(builder); |
||||
return builder.build(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
/* |
||||
* Copyright 2012-2016 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 sample.actuator; |
||||
|
||||
import java.util.Collections; |
||||
|
||||
import org.springframework.boot.actuate.info.Info; |
||||
import org.springframework.boot.actuate.info.InfoContributor; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class ExampleInfoContributor implements InfoContributor { |
||||
|
||||
@Override |
||||
public void contribute(Info.Builder builder) { |
||||
builder.withDetail("example", |
||||
Collections.singletonMap("someKey", "someValue")); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue