/* * Copyright 2012-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.boot.actuate.endpoint.mvc; import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.EnvironmentAware; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySources; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; /** * Adapter to expose {@link EnvironmentEndpoint} as an {@link MvcEndpoint}. * * @author Dave Syer * @author Christian Dupuis * @author Andy Wilkinson */ @ConfigurationProperties(prefix = "endpoints.env") public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements EnvironmentAware { private Environment environment; public EnvironmentMvcEndpoint(EnvironmentEndpoint delegate) { super(delegate); } @ActuatorGetMapping("/{name:.*}") @ResponseBody @HypermediaDisabled public Object value(@PathVariable String name) { if (!getDelegate().isEnabled()) { // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's // disabled return getDisabledResponse(); } return new NamePatternEnvironmentFilter(this.environment).getResults(name); } @Override public void setEnvironment(Environment environment) { this.environment = environment; } /** * {@link NamePatternFilter} for the Environment source. */ private class NamePatternEnvironmentFilter extends NamePatternFilter<Environment> { NamePatternEnvironmentFilter(Environment source) { super(source); } @Override protected void getNames(Environment source, NameCallback callback) { if (source instanceof ConfigurableEnvironment) { getNames(((ConfigurableEnvironment) source).getPropertySources(), callback); } } private void getNames(PropertySources propertySources, NameCallback callback) { for (PropertySource<?> propertySource : propertySources) { if (propertySource instanceof EnumerablePropertySource) { EnumerablePropertySource<?> source = (EnumerablePropertySource<?>) propertySource; for (String name : source.getPropertyNames()) { callback.addName(name); } } } } @Override protected Object getOptionalValue(Environment source, String name) { Object result = ((EnvironmentEndpoint) getDelegate()).getResolver() .getProperty(name, Object.class); if (result != null) { result = ((EnvironmentEndpoint) getDelegate()).sanitize(name, result); } return result; } @Override protected Object getValue(Environment source, String name) { Object result = source.getProperty(name, Object.class); if (result == null) { throw new NoSuchPropertyException("No such property: " + name); } return ((EnvironmentEndpoint) getDelegate()).sanitize(name, result); } } /** * Exception thrown when the specified property cannot be found. */ @SuppressWarnings("serial") @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No such property") public static class NoSuchPropertyException extends RuntimeException { public NoSuchPropertyException(String string) { super(string); } } }