parent
1bdd42e379
commit
9e95483645
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
|
||||
/**
|
||||
* {@link EndpointFilter} for endpoints discovered by
|
||||
* {@link CloudFoundryWebAnnotationEndpointDiscoverer}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class CloudFoundryEndpointFilter implements EndpointFilter<WebOperation> {
|
||||
|
||||
@Override
|
||||
public boolean match(EndpointInfo<WebOperation> info, EndpointDiscoverer<WebOperation> discoverer) {
|
||||
return (discoverer instanceof CloudFoundryWebAnnotationEndpointDiscoverer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryReactiveHealthEndpointWebExtension;
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.ReactiveCloudFoundryActuatorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryActuatorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryHealthEndpointWebExtension;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configuration for Cloud Foundry Health endpoint extensions.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore({ ReactiveCloudFoundryActuatorAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class })
|
||||
@AutoConfigureAfter(HealthEndpointAutoConfiguration.class)
|
||||
public class CloudFoundryHealthWebEndpointManagementContextConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
static class ServletWebHealthConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
public CloudFoundryHealthEndpointWebExtension cloudFoundryHealthEndpointWebExtension(
|
||||
HealthEndpoint healthEndpoint, HealthStatusHttpMapper healthStatusHttpMapper) {
|
||||
HealthEndpoint delegate = new HealthEndpoint(healthEndpoint.getHealthIndicator(), true);
|
||||
return new CloudFoundryHealthEndpointWebExtension(delegate, healthStatusHttpMapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
static class ReactiveWebHealthConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnEnabledEndpoint
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
public CloudFoundryReactiveHealthEndpointWebExtension cloudFoundryReactiveHealthEndpointWebExtension(
|
||||
ReactiveHealthIndicator reactiveHealthIndicator,
|
||||
HealthStatusHttpMapper healthStatusHttpMapper) {
|
||||
return new CloudFoundryReactiveHealthEndpointWebExtension(reactiveHealthIndicator,
|
||||
healthStatusHttpMapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.OperationMethodInvokerAdvisor;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* {@link WebAnnotationEndpointDiscoverer} for Cloud Foundry that uses Cloud Foundry specific
|
||||
* extensions for the {@link HealthEndpoint}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class CloudFoundryWebAnnotationEndpointDiscoverer extends WebAnnotationEndpointDiscoverer {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
private final Class<?> requiredExtensionType;
|
||||
|
||||
public CloudFoundryWebAnnotationEndpointDiscoverer(ApplicationContext applicationContext, ParameterMapper parameterMapper,
|
||||
EndpointMediaTypes endpointMediaTypes, EndpointPathResolver endpointPathResolver,
|
||||
Collection<? extends OperationMethodInvokerAdvisor> invokerAdvisors, Collection<? extends EndpointFilter<WebOperation>> filters, Class<?> requiredExtensionType) {
|
||||
super(applicationContext, parameterMapper, endpointMediaTypes, endpointPathResolver, invokerAdvisors, filters);
|
||||
this.applicationContext = applicationContext;
|
||||
this.requiredExtensionType = requiredExtensionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addExtension(Map<Class<?>, DiscoveredEndpoint> endpoints, Map<Class<?>, DiscoveredExtension> extensions, String beanName) {
|
||||
Class<?> extensionType = this.applicationContext.getType(beanName);
|
||||
Class<?> endpointType = getEndpointType(extensionType);
|
||||
if (HealthEndpoint.class.equals(endpointType) && !this.requiredExtensionType.equals(extensionType)) {
|
||||
return;
|
||||
}
|
||||
super.addExtension(endpoints, extensions, beanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry.reactive;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryEndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
|
||||
|
||||
/**
|
||||
* Reactive {@link EndpointWebExtension} for the {@link HealthEndpoint}
|
||||
* that always exposes full health details.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@EndpointExtension(filter = CloudFoundryEndpointFilter.class, endpoint = HealthEndpoint.class)
|
||||
public class CloudFoundryReactiveHealthEndpointWebExtension {
|
||||
|
||||
private final ReactiveHealthIndicator delegate;
|
||||
|
||||
private final HealthStatusHttpMapper statusHttpMapper;
|
||||
|
||||
public CloudFoundryReactiveHealthEndpointWebExtension(ReactiveHealthIndicator delegate,
|
||||
HealthStatusHttpMapper statusHttpMapper) {
|
||||
this.delegate = delegate;
|
||||
this.statusHttpMapper = statusHttpMapper;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public Mono<WebEndpointResponse<Health>> health() {
|
||||
return this.delegate.health().map((health) -> {
|
||||
Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
|
||||
return new WebEndpointResponse<>(health, status);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -21,10 +21,10 @@ import java.util.Collections;
|
|||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
|
||||
|
@ -68,9 +68,9 @@ public class ReactiveCloudFoundryActuatorAutoConfiguration {
|
|||
public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHandlerMapping(
|
||||
ParameterMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
|
||||
WebClient.Builder webClientBuilder) {
|
||||
WebAnnotationEndpointDiscoverer endpointDiscoverer = new WebAnnotationEndpointDiscoverer(
|
||||
CloudFoundryWebAnnotationEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext, parameterMapper, endpointMediaTypes,
|
||||
EndpointPathResolver.useEndpointId(), null, null);
|
||||
EndpointPathResolver.useEndpointId(), null, null, CloudFoundryReactiveHealthEndpointWebExtension.class);
|
||||
ReactiveCloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(
|
||||
webClientBuilder, this.applicationContext.getEnvironment());
|
||||
return new CloudFoundryWebFluxEndpointHandlerMapping(
|
||||
|
|
|
@ -18,11 +18,11 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
@ -72,9 +72,9 @@ public class CloudFoundryActuatorAutoConfiguration {
|
|||
public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandlerMapping(
|
||||
ParameterMapper parameterMapper, EndpointMediaTypes endpointMediaTypes,
|
||||
RestTemplateBuilder restTemplateBuilder) {
|
||||
WebAnnotationEndpointDiscoverer endpointDiscoverer = new WebAnnotationEndpointDiscoverer(
|
||||
CloudFoundryWebAnnotationEndpointDiscoverer endpointDiscoverer = new CloudFoundryWebAnnotationEndpointDiscoverer(
|
||||
this.applicationContext, parameterMapper, endpointMediaTypes,
|
||||
EndpointPathResolver.useEndpointId(), null, null);
|
||||
EndpointPathResolver.useEndpointId(), null, null, CloudFoundryHealthEndpointWebExtension.class);
|
||||
CloudFoundrySecurityInterceptor securityInterceptor = getSecurityInterceptor(
|
||||
restTemplateBuilder, this.applicationContext.getEnvironment());
|
||||
return new CloudFoundryWebEndpointServletHandlerMapping(
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry.servlet;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryEndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
|
||||
|
||||
/**
|
||||
* {@link EndpointWebExtension} for the {@link HealthEndpoint}
|
||||
* that always exposes full health details.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@EndpointExtension(filter = CloudFoundryEndpointFilter.class, endpoint = HealthEndpoint.class)
|
||||
public class CloudFoundryHealthEndpointWebExtension {
|
||||
|
||||
private final HealthEndpoint delegate;
|
||||
|
||||
private final HealthStatusHttpMapper statusHttpMapper;
|
||||
|
||||
public CloudFoundryHealthEndpointWebExtension(HealthEndpoint delegate,
|
||||
HealthStatusHttpMapper statusHttpMapper) {
|
||||
this.delegate = delegate;
|
||||
this.statusHttpMapper = statusHttpMapper;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public WebEndpointResponse<Health> getHealth() {
|
||||
Health health = this.delegate.health();
|
||||
Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
|
||||
return new WebEndpointResponse<>(health, status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -64,12 +64,11 @@ public class HealthWebEndpointManagementContextConfiguration {
|
|||
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
||||
static class ReactiveWebHealthConfiguration {
|
||||
|
||||
private final ReactiveHealthIndicator reactiveHealthIndicator;
|
||||
|
||||
ReactiveWebHealthConfiguration(ObjectProvider<HealthAggregator> healthAggregator,
|
||||
@Bean
|
||||
public ReactiveHealthIndicator reactiveHealthIndicator(ObjectProvider<HealthAggregator> healthAggregator,
|
||||
ObjectProvider<Map<String, ReactiveHealthIndicator>> reactiveHealthIndicators,
|
||||
ObjectProvider<Map<String, HealthIndicator>> healthIndicators) {
|
||||
this.reactiveHealthIndicator = new CompositeReactiveHealthIndicatorFactory()
|
||||
return new CompositeReactiveHealthIndicatorFactory()
|
||||
.createReactiveHealthIndicator(
|
||||
healthAggregator.getIfAvailable(OrderedHealthAggregator::new),
|
||||
reactiveHealthIndicators
|
||||
|
@ -82,9 +81,10 @@ public class HealthWebEndpointManagementContextConfiguration {
|
|||
@ConditionalOnEnabledEndpoint
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension(
|
||||
ReactiveHealthIndicator reactiveHealthIndicator,
|
||||
HealthStatusHttpMapper healthStatusHttpMapper,
|
||||
HealthEndpointProperties properties) {
|
||||
return new ReactiveHealthEndpointWebExtension(this.reactiveHealthIndicator,
|
||||
return new ReactiveHealthEndpointWebExtension(reactiveHealthIndicator,
|
||||
healthStatusHttpMapper, properties.isShowDetails());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfigurat
|
|||
org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthIndicatorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryActuatorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.ReactiveCloudFoundryActuatorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryHealthWebEndpointManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpointAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationPropertiesReportEndpointAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration,\
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointFilter;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.OperationMethodInvokerAdvisor;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebAnnotationEndpointDiscoverer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CloudFoundryEndpointFilter}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class CloudFoundryEndpointFilterTests {
|
||||
|
||||
private CloudFoundryEndpointFilter filter;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.filter = new CloudFoundryEndpointFilter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchIfDiscovererCloudFoundryShouldReturnFalse() throws Exception {
|
||||
CloudFoundryWebAnnotationEndpointDiscoverer discoverer = Mockito.mock(CloudFoundryWebAnnotationEndpointDiscoverer.class);
|
||||
assertThat(this.filter.match(null, discoverer)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchIfDiscovererNotCloudFoundryShouldReturnFalse() throws Exception {
|
||||
WebAnnotationEndpointDiscoverer discoverer = Mockito.mock(WebAnnotationEndpointDiscoverer.class);
|
||||
assertThat(this.filter.match(null, discoverer)).isFalse();
|
||||
}
|
||||
|
||||
static class TestEndpointDiscoverer extends WebAnnotationEndpointDiscoverer {
|
||||
|
||||
TestEndpointDiscoverer(ApplicationContext applicationContext, ParameterMapper parameterMapper, EndpointMediaTypes endpointMediaTypes, EndpointPathResolver endpointPathResolver, Collection<? extends OperationMethodInvokerAdvisor> invokerAdvisors, Collection<? extends EndpointFilter<WebOperation>> filters) {
|
||||
super(applicationContext, parameterMapper, endpointMediaTypes, endpointPathResolver, invokerAdvisors, filters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* 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.autoconfigure.cloudfoundry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.cache.CachingOperationInvokerAdvisor;
|
||||
import org.springframework.boot.actuate.endpoint.convert.ConversionServiceParameterMapper;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointPathResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link CloudFoundryWebAnnotationEndpointDiscoverer}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public class CloudFoundryWebAnnotationEndpointDiscovererTests {
|
||||
|
||||
@Test
|
||||
public void discovererShouldAddSuppliedExtensionForHealthEndpoint() throws Exception {
|
||||
load(TestConfiguration.class, endpointDiscoverer -> {
|
||||
Collection<EndpointInfo<WebOperation>> endpoints = endpointDiscoverer.discoverEndpoints();
|
||||
assertThat(endpoints.size()).isEqualTo(2);
|
||||
});
|
||||
}
|
||||
|
||||
private void load(Class<?> configuration,
|
||||
Consumer<CloudFoundryWebAnnotationEndpointDiscoverer> consumer) {
|
||||
this.load((id) -> null, (id) -> id, configuration, consumer);
|
||||
}
|
||||
|
||||
private void load(Function<String, Long> timeToLive,
|
||||
EndpointPathResolver endpointPathResolver, Class<?> configuration,
|
||||
Consumer<CloudFoundryWebAnnotationEndpointDiscoverer> consumer) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
configuration);
|
||||
try {
|
||||
ConversionServiceParameterMapper parameterMapper = new ConversionServiceParameterMapper(
|
||||
DefaultConversionService.getSharedInstance());
|
||||
EndpointMediaTypes mediaTypes = new EndpointMediaTypes(
|
||||
Collections.singletonList("application/json"),
|
||||
Collections.singletonList("application/json"));
|
||||
CloudFoundryWebAnnotationEndpointDiscoverer discoverer = new CloudFoundryWebAnnotationEndpointDiscoverer(
|
||||
context, parameterMapper, mediaTypes, endpointPathResolver,
|
||||
Collections.singleton(new CachingOperationInvokerAdvisor(timeToLive)),
|
||||
null, HealthWebEndpointExtension.class);
|
||||
consumer.accept(discoverer);
|
||||
}
|
||||
finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestEndpoint testEndpoint() {
|
||||
return new TestEndpoint();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthEndpoint healthEndpoint() {
|
||||
return new HealthEndpoint(null, true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestWebEndpointExtension testEndpointExtension() {
|
||||
return new TestWebEndpointExtension();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HealthWebEndpointExtension healthEndpointExtension() {
|
||||
return new HealthWebEndpointExtension();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OtherHealthWebEndpointExtension otherHealthEndpointExtension() {
|
||||
return new OtherHealthWebEndpointExtension();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EndpointWebExtension(endpoint = TestEndpoint.class)
|
||||
static class TestWebEndpointExtension {
|
||||
|
||||
@ReadOperation
|
||||
public Object getAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Endpoint(id = "test")
|
||||
static class TestEndpoint {
|
||||
|
||||
@ReadOperation
|
||||
public Object getAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EndpointWebExtension(endpoint = HealthEndpoint.class)
|
||||
static class HealthWebEndpointExtension {
|
||||
|
||||
@ReadOperation
|
||||
public Object getAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EndpointWebExtension(endpoint = HealthEndpoint.class)
|
||||
static class OtherHealthWebEndpointExtension {
|
||||
|
||||
@ReadOperation
|
||||
public Object getAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -24,13 +25,17 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryHealthWebEndpointManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthWebEndpointManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ReflectiveOperationInvoker;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||
|
@ -221,6 +226,19 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
|
|||
assertThat(operation.getRequestPredicate().getPath()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() throws Exception {
|
||||
setupContextWithCloudEnabled();
|
||||
this.context.register(HealthEndpointAutoConfiguration.class, HealthWebEndpointManagementContextConfiguration.class,
|
||||
CloudFoundryHealthWebEndpointManagementContextConfiguration.class);
|
||||
this.context.refresh();
|
||||
Collection<EndpointInfo<WebOperation>> endpoints = getHandlerMapping().getEndpoints();
|
||||
EndpointInfo endpointInfo = (EndpointInfo) (endpoints.toArray()[0]);
|
||||
WebOperation webOperation = (WebOperation) endpointInfo.getOperations().toArray()[0];
|
||||
ReflectiveOperationInvoker invoker = (ReflectiveOperationInvoker) webOperation.getInvoker();
|
||||
assertThat(ReflectionTestUtils.getField(invoker, "target")).isInstanceOf(CloudFoundryReactiveHealthEndpointWebExtension.class);
|
||||
}
|
||||
|
||||
private void setupContextWithCloudEnabled() {
|
||||
TestPropertyValues
|
||||
.of("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
|
||||
|
|
|
@ -24,14 +24,18 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryHealthWebEndpointManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.HealthWebEndpointManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointInfo;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.reflect.ReflectiveOperationInvoker;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||
|
@ -241,6 +245,23 @@ public class CloudFoundryActuatorAutoConfigurationTests {
|
|||
.isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() throws Exception {
|
||||
TestPropertyValues
|
||||
.of("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
|
||||
"vcap.application.cf_api:http://my-cloud-controller.com")
|
||||
.applyTo(this.context);
|
||||
this.context.register(HealthEndpointAutoConfiguration.class, HealthWebEndpointManagementContextConfiguration.class,
|
||||
CloudFoundryHealthWebEndpointManagementContextConfiguration.class);
|
||||
this.context.refresh();
|
||||
Collection<EndpointInfo<WebOperation>> endpoints = this.context.getBean("cloudFoundryWebEndpointServletHandlerMapping",
|
||||
CloudFoundryWebEndpointServletHandlerMapping.class).getEndpoints();
|
||||
EndpointInfo endpointInfo = (EndpointInfo) (endpoints.toArray()[0]);
|
||||
WebOperation webOperation = (WebOperation) endpointInfo.getOperations().toArray()[0];
|
||||
ReflectiveOperationInvoker invoker = (ReflectiveOperationInvoker) webOperation.getInvoker();
|
||||
assertThat(ReflectionTestUtils.getField(invoker, "target")).isInstanceOf(CloudFoundryHealthEndpointWebExtension.class);
|
||||
}
|
||||
|
||||
private CloudFoundryWebEndpointServletHandlerMapping getHandlerMapping() {
|
||||
TestPropertyValues
|
||||
.of("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
|
||||
|
|
|
@ -173,7 +173,7 @@ public abstract class AnnotationEndpointDiscoverer<K, T extends Operation>
|
|||
return extensions;
|
||||
}
|
||||
|
||||
private void addExtension(Map<Class<?>, DiscoveredEndpoint> endpoints,
|
||||
protected void addExtension(Map<Class<?>, DiscoveredEndpoint> endpoints,
|
||||
Map<Class<?>, DiscoveredExtension> extensions, String beanName) {
|
||||
Class<?> extensionType = this.applicationContext.getType(beanName);
|
||||
Class<?> endpointType = getEndpointType(extensionType);
|
||||
|
@ -199,7 +199,7 @@ public abstract class AnnotationEndpointDiscoverer<K, T extends Operation>
|
|||
}
|
||||
}
|
||||
|
||||
private Class<?> getEndpointType(Class<?> extensionType) {
|
||||
protected Class<?> getEndpointType(Class<?> extensionType) {
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils
|
||||
.getMergedAnnotationAttributes(extensionType, EndpointExtension.class);
|
||||
Class<?> endpointType = attributes.getClass("endpoint");
|
||||
|
|
|
@ -53,4 +53,8 @@ public class HealthEndpoint {
|
|||
return Health.status(health.getStatus()).build();
|
||||
}
|
||||
|
||||
public HealthIndicator getHealthIndicator() {
|
||||
return this.healthIndicator;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue