mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Drop support for Jersey until jersey-spring6 is available
Closes gh-28808
This commit is contained in:
parent
29a21d4621
commit
8bf2ffd93c
@ -177,7 +177,6 @@ public class DocumentConfigurationProperties extends DefaultTask {
|
||||
prefix.accept("spring.hateoas");
|
||||
prefix.accept("spring.http");
|
||||
prefix.accept("spring.servlet");
|
||||
prefix.accept("spring.jersey");
|
||||
prefix.accept("spring.mvc");
|
||||
prefix.accept("spring.netty");
|
||||
prefix.accept("spring.resources");
|
||||
|
@ -101,8 +101,6 @@ dependencies {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
optional("org.flywaydb:flyway-core")
|
||||
optional("org.glassfish.jersey.core:jersey-server")
|
||||
optional("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
optional("org.hibernate:hibernate-core") {
|
||||
exclude group: "javax.activation", module: "javax.activation-api"
|
||||
exclude group: "javax.persistence", module: "javax.persistence-api"
|
||||
@ -178,8 +176,6 @@ dependencies {
|
||||
testImplementation("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
testImplementation("org.glassfish.jersey.ext:jersey-spring5")
|
||||
testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
testImplementation("org.hamcrest:hamcrest")
|
||||
testImplementation("org.hsqldb:hsqldb")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -16,19 +16,15 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
@ -67,18 +63,4 @@ public class ServletEndpointManagementContextConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
public static class JerseyServletEndpointManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletEndpointRegistrar servletEndpointRegistrar(WebEndpointProperties properties,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, JerseyApplicationPath jerseyApplicationPath) {
|
||||
return new ServletEndpointRegistrar(jerseyApplicationPath.getRelativePath(properties.getBasePath()),
|
||||
servletEndpointsSupplier.getEndpoints());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.jersey.ManagementContextResourceConfigCustomizer;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
|
||||
import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.actuate.endpoint.web.jersey.JerseyHealthEndpointAdditionalPathResourceFactory;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jersey
|
||||
* {@link Endpoint @Endpoint} concerns.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @author Michael Simons
|
||||
* @author Madhura Bhave
|
||||
* @author HaiTao Zhang
|
||||
*/
|
||||
@ManagementContextConfiguration(proxyBeanMethods = false)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnBean(WebEndpointsSupplier.class)
|
||||
@ConditionalOnMissingBean(type = "org.springframework.web.servlet.DispatcherServlet")
|
||||
class JerseyWebEndpointManagementContextConfiguration {
|
||||
|
||||
private static final EndpointId HEALTH_ENDPOINT_ID = EndpointId.of("health");
|
||||
|
||||
@Bean
|
||||
JerseyWebEndpointsResourcesRegistrar jerseyWebEndpointsResourcesRegistrar(Environment environment,
|
||||
WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier,
|
||||
EndpointMediaTypes endpointMediaTypes, WebEndpointProperties webEndpointProperties) {
|
||||
String basePath = webEndpointProperties.getBasePath();
|
||||
boolean shouldRegisterLinks = shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
|
||||
return new JerseyWebEndpointsResourcesRegistrar(webEndpointsSupplier, servletEndpointsSupplier,
|
||||
endpointMediaTypes, basePath, shouldRegisterLinks);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
|
||||
@ConditionalOnBean(HealthEndpoint.class)
|
||||
@ConditionalOnAvailableEndpoint(endpoint = HealthEndpoint.class, exposure = EndpointExposure.WEB)
|
||||
JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar jerseyDifferentPortAdditionalHealthEndpointPathsResourcesRegistrar(
|
||||
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) {
|
||||
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
|
||||
ExposableWebEndpoint health = webEndpoints.stream()
|
||||
.filter((endpoint) -> endpoint.getEndpointId().equals(HEALTH_ENDPOINT_ID)).findFirst().get();
|
||||
return new JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(health, healthEndpointGroups);
|
||||
}
|
||||
|
||||
private boolean shouldRegisterLinksMapping(WebEndpointProperties properties, Environment environment,
|
||||
String basePath) {
|
||||
return properties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath)
|
||||
|| ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register endpoints with the {@link ResourceConfig} for the management context.
|
||||
*/
|
||||
static class JerseyWebEndpointsResourcesRegistrar implements ManagementContextResourceConfigCustomizer {
|
||||
|
||||
private final WebEndpointsSupplier webEndpointsSupplier;
|
||||
|
||||
private final ServletEndpointsSupplier servletEndpointsSupplier;
|
||||
|
||||
private final EndpointMediaTypes mediaTypes;
|
||||
|
||||
private final String basePath;
|
||||
|
||||
private final boolean shouldRegisterLinks;
|
||||
|
||||
JerseyWebEndpointsResourcesRegistrar(WebEndpointsSupplier webEndpointsSupplier,
|
||||
ServletEndpointsSupplier servletEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
|
||||
String basePath, boolean shouldRegisterLinks) {
|
||||
this.webEndpointsSupplier = webEndpointsSupplier;
|
||||
this.servletEndpointsSupplier = servletEndpointsSupplier;
|
||||
this.mediaTypes = endpointMediaTypes;
|
||||
this.basePath = basePath;
|
||||
this.shouldRegisterLinks = shouldRegisterLinks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(ResourceConfig config) {
|
||||
register(config);
|
||||
}
|
||||
|
||||
private void register(ResourceConfig config) {
|
||||
Collection<ExposableWebEndpoint> webEndpoints = this.webEndpointsSupplier.getEndpoints();
|
||||
Collection<ExposableServletEndpoint> servletEndpoints = this.servletEndpointsSupplier.getEndpoints();
|
||||
EndpointLinksResolver linksResolver = getLinksResolver(webEndpoints, servletEndpoints);
|
||||
EndpointMapping mapping = new EndpointMapping(this.basePath);
|
||||
Collection<Resource> endpointResources = new JerseyEndpointResourceFactory().createEndpointResources(
|
||||
mapping, webEndpoints, this.mediaTypes, linksResolver, this.shouldRegisterLinks);
|
||||
register(endpointResources, config);
|
||||
}
|
||||
|
||||
private EndpointLinksResolver getLinksResolver(Collection<ExposableWebEndpoint> webEndpoints,
|
||||
Collection<ExposableServletEndpoint> servletEndpoints) {
|
||||
List<ExposableEndpoint<?>> endpoints = new ArrayList<>(webEndpoints.size() + servletEndpoints.size());
|
||||
endpoints.addAll(webEndpoints);
|
||||
endpoints.addAll(servletEndpoints);
|
||||
return new EndpointLinksResolver(endpoints, this.basePath);
|
||||
}
|
||||
|
||||
private void register(Collection<Resource> resources, ResourceConfig config) {
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar
|
||||
implements ManagementContextResourceConfigCustomizer {
|
||||
|
||||
private final ExposableWebEndpoint endpoint;
|
||||
|
||||
private final HealthEndpointGroups groups;
|
||||
|
||||
JerseyAdditionalHealthEndpointPathsManagementResourcesRegistrar(ExposableWebEndpoint endpoint,
|
||||
HealthEndpointGroups groups) {
|
||||
this.endpoint = endpoint;
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(ResourceConfig config) {
|
||||
register(config);
|
||||
}
|
||||
|
||||
private void register(ResourceConfig config) {
|
||||
EndpointMapping mapping = new EndpointMapping("");
|
||||
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
|
||||
WebServerNamespace.MANAGEMENT, this.groups);
|
||||
Collection<Resource> endpointResources = resourceFactory
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
|
||||
.stream().filter(Objects::nonNull).collect(Collectors.toList());
|
||||
register(endpointResources, config);
|
||||
}
|
||||
|
||||
private void register(Collection<Resource> resources, ResourceConfig config) {
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for exposing actuator web endpoints using Jersey.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey;
|
@ -17,40 +17,21 @@
|
||||
package org.springframework.boot.actuate.autoconfigure.health;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
import org.springframework.boot.actuate.endpoint.web.jersey.JerseyHealthEndpointAdditionalPathResourceFactory;
|
||||
import org.springframework.boot.actuate.endpoint.web.servlet.AdditionalHealthEndpointPathsWebMvcHandlerMapping;
|
||||
import org.springframework.boot.actuate.health.HealthContributorRegistry;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointWebExtension;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyProperties;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
@ -94,78 +75,4 @@ class HealthEndpointWebExtensionConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
static class JerseyAdditionalHealthEndpointPathsConfiguration {
|
||||
|
||||
@Bean
|
||||
JerseyAdditionalHealthEndpointPathsResourcesRegistrar jerseyAdditionalHealthEndpointPathsResourcesRegistrar(
|
||||
WebEndpointsSupplier webEndpointsSupplier, HealthEndpointGroups healthEndpointGroups) {
|
||||
ExposableWebEndpoint health = getHealthEndpoint(webEndpointsSupplier);
|
||||
return new JerseyAdditionalHealthEndpointPathsResourcesRegistrar(health, healthEndpointGroups);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ResourceConfig.class)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
static class JerseyInfrastructureConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(JerseyApplicationPath.class)
|
||||
JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, ResourceConfig config) {
|
||||
return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig(ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers) {
|
||||
ResourceConfig resourceConfig = new ResourceConfig();
|
||||
resourceConfigCustomizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig));
|
||||
return resourceConfig;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean<ServletContainer> jerseyServletRegistration(
|
||||
JerseyApplicationPath jerseyApplicationPath, ResourceConfig resourceConfig) {
|
||||
return new ServletRegistrationBean<>(new ServletContainer(resourceConfig),
|
||||
jerseyApplicationPath.getUrlMapping());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class JerseyAdditionalHealthEndpointPathsResourcesRegistrar implements ResourceConfigCustomizer {
|
||||
|
||||
private final ExposableWebEndpoint endpoint;
|
||||
|
||||
private final HealthEndpointGroups groups;
|
||||
|
||||
JerseyAdditionalHealthEndpointPathsResourcesRegistrar(ExposableWebEndpoint endpoint,
|
||||
HealthEndpointGroups groups) {
|
||||
this.endpoint = endpoint;
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(ResourceConfig config) {
|
||||
register(config);
|
||||
}
|
||||
|
||||
private void register(ResourceConfig config) {
|
||||
EndpointMapping mapping = new EndpointMapping("");
|
||||
JerseyHealthEndpointAdditionalPathResourceFactory resourceFactory = new JerseyHealthEndpointAdditionalPathResourceFactory(
|
||||
WebServerNamespace.SERVER, this.groups);
|
||||
Collection<Resource> endpointResources = resourceFactory
|
||||
.createEndpointResources(mapping, Collections.singletonList(this.endpoint), null, null, false)
|
||||
.stream().filter(Objects::nonNull).collect(Collectors.toList());
|
||||
register(endpointResources, config);
|
||||
}
|
||||
|
||||
private void register(Collection<Resource> resources, ResourceConfig config) {
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.metrics.jersey;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.AnnotationFinder;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.DefaultJerseyTagsProvider;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.MetricsApplicationEventListener;
|
||||
import io.micrometer.core.instrument.config.MeterFilter;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Jersey server instrumentation.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Michael Simons
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureAfter({ MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnClass({ ResourceConfig.class, MetricsApplicationEventListener.class })
|
||||
@ConditionalOnBean({ MeterRegistry.class, ResourceConfig.class })
|
||||
@EnableConfigurationProperties(MetricsProperties.class)
|
||||
public class JerseyServerMetricsAutoConfiguration {
|
||||
|
||||
private final MetricsProperties properties;
|
||||
|
||||
public JerseyServerMetricsAutoConfiguration(MetricsProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(JerseyTagsProvider.class)
|
||||
public DefaultJerseyTagsProvider jerseyTagsProvider() {
|
||||
return new DefaultJerseyTagsProvider();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceConfigCustomizer jerseyServerMetricsResourceConfigCustomizer(MeterRegistry meterRegistry,
|
||||
JerseyTagsProvider tagsProvider) {
|
||||
Server server = this.properties.getWeb().getServer();
|
||||
return (config) -> config.register(
|
||||
new MetricsApplicationEventListener(meterRegistry, tagsProvider, server.getRequest().getMetricName(),
|
||||
server.getRequest().getAutotime().isEnabled(), new AnnotationUtilsAnnotationFinder()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(0)
|
||||
public MeterFilter jerseyMetricsUriTagFilter() {
|
||||
String metricName = this.properties.getWeb().getServer().getRequest().getMetricName();
|
||||
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(
|
||||
() -> String.format("Reached the maximum number of URI tags for '%s'.", metricName));
|
||||
return MeterFilter.maximumAllowableTags(metricName, "uri", this.properties.getWeb().getServer().getMaxUriTags(),
|
||||
filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@link AnnotationFinder} that uses {@link AnnotationUtils}.
|
||||
*/
|
||||
private static class AnnotationUtilsAnnotationFinder implements AnnotationFinder {
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A findAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
|
||||
return AnnotationUtils.findAnnotation(annotatedElement, annotationType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Jersey actuator metrics.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.jersey;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -16,18 +16,14 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.security.servlet;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.AntPathRequestMatcherProvider;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
@ -59,17 +55,4 @@ public class SecurityRequestMatchersManagementContextConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
@ConditionalOnBean(JerseyApplicationPath.class)
|
||||
public static class JerseyRequestMatcherConfiguration {
|
||||
|
||||
@Bean
|
||||
public RequestMatcherProvider requestMatcherProvider(JerseyApplicationPath applicationPath) {
|
||||
return new AntPathRequestMatcherProvider(applicationPath::getRelativePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jersey
|
||||
* infrastructure when a separate management context with a web server running on a
|
||||
* different port is required.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@ManagementContextConfiguration(value = ManagementContextType.CHILD, proxyBeanMethods = false)
|
||||
@Import(JerseyManagementContextConfiguration.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
public class JerseyChildManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public JerseyApplicationPath jerseyApplicationPath() {
|
||||
return () -> "/";
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig(ObjectProvider<ManagementContextResourceConfigCustomizer> customizers) {
|
||||
ResourceConfig resourceConfig = new ResourceConfig();
|
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig));
|
||||
return resourceConfig;
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Shared configuration for Jersey-based actuators regardless of management context type.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class JerseyManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean<ServletContainer> jerseyServletRegistration(JerseyApplicationPath jerseyApplicationPath,
|
||||
ResourceConfig resourceConfig) {
|
||||
return new ServletRegistrationBean<>(new ServletContainer(resourceConfig),
|
||||
jerseyApplicationPath.getUrlMapping());
|
||||
}
|
||||
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyProperties;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link ManagementContextConfiguration @ManagementContextConfiguration} for Jersey
|
||||
* infrastructure when the management context is the same as the main application context.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@ManagementContextConfiguration(value = ManagementContextType.SAME, proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnClass(ResourceConfig.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
|
||||
public class JerseySameManagementContextConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer managementResourceConfigCustomizerAdapter(
|
||||
ObjectProvider<ManagementContextResourceConfigCustomizer> customizers) {
|
||||
return (config) -> customizers.orderedStream().forEach((customizer) -> customizer.customize(config));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(JerseyManagementContextConfiguration.class)
|
||||
@ConditionalOnMissingBean(ResourceConfig.class)
|
||||
static class JerseyInfrastructureConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(JerseyApplicationPath.class)
|
||||
JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, ResourceConfig config) {
|
||||
return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig(ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers) {
|
||||
ResourceConfig resourceConfig = new ResourceConfig();
|
||||
resourceConfigCustomizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig));
|
||||
return resourceConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize Jersey's
|
||||
* {@link ResourceConfig} in the management context before it is used.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.3.10
|
||||
*/
|
||||
public interface ManagementContextResourceConfigCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the resource config.
|
||||
* @param config the {@link ResourceConfig} to customize
|
||||
*/
|
||||
void customize(ResourceConfig config);
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration for a Jersey-based management context.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.web.jersey;
|
@ -70,7 +70,6 @@ org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetri
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.metrics.r2dbc.ConnectionPoolMetricsAutoConfiguration,\
|
||||
@ -106,10 +105,7 @@ org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguratio
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.security.servlet.SecurityRequestMatchersManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyChildManagementContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -18,21 +18,17 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -49,24 +45,13 @@ class ServletEndpointManagementContextConfigurationTests {
|
||||
|
||||
@Test
|
||||
void contextShouldContainServletEndpointRegistrar() {
|
||||
FilteredClassLoader classLoader = new FilteredClassLoader(ResourceConfig.class);
|
||||
this.contextRunner.withClassLoader(classLoader).run((context) -> {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ServletEndpointRegistrar.class);
|
||||
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class);
|
||||
assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/test/actuator");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextWhenJerseyShouldContainServletEndpointRegistrar() {
|
||||
FilteredClassLoader classLoader = new FilteredClassLoader(DispatcherServlet.class);
|
||||
this.contextRunner.withClassLoader(classLoader).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ServletEndpointRegistrar.class);
|
||||
ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class);
|
||||
assertThat(bean).hasFieldOrPropertyWithValue("basePath", "/jersey/actuator");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextWhenNoServletBasedShouldNotContainServletEndpointRegistrar() {
|
||||
new ApplicationContextRunner().withUserConfiguration(TestConfig.class)
|
||||
@ -88,11 +73,6 @@ class ServletEndpointManagementContextConfigurationTests {
|
||||
return () -> "/test";
|
||||
}
|
||||
|
||||
@Bean
|
||||
JerseyApplicationPath jerseyApplicationPath() {
|
||||
return () -> "/jersey";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for web endpoints running on Jersey.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyWebEndpointIntegrationTests {
|
||||
|
||||
@Test
|
||||
void whenJerseyIsConfiguredToUseAFilterThenResourceRegistrationSucceeds() {
|
||||
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class,
|
||||
JerseyAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
JerseyWebEndpointManagementContextConfiguration.class))
|
||||
.withUserConfiguration(ResourceConfigConfiguration.class)
|
||||
.withClassLoader(new FilteredClassLoader(DispatcherServlet.class))
|
||||
.withPropertyValues("spring.jersey.type=filter", "server.port=0").run((context) -> {
|
||||
assertThat(context).hasNotFailed();
|
||||
Set<Resource> resources = context.getBean(ResourceConfig.class).getResources();
|
||||
assertThat(resources).hasSize(1);
|
||||
Resource resource = resources.iterator().next();
|
||||
assertThat(resource.getPath()).isEqualTo("/actuator");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration.JerseyWebEndpointsResourcesRegistrar;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyWebEndpointManagementContextConfiguration}.
|
||||
*
|
||||
* @author Michael Simons
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyWebEndpointManagementContextConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner runner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(WebEndpointAutoConfiguration.class,
|
||||
JerseyWebEndpointManagementContextConfiguration.class))
|
||||
.withBean(WebEndpointsSupplier.class, () -> Collections::emptyList);
|
||||
|
||||
@Test
|
||||
void jerseyWebEndpointsResourcesRegistrarForEndpointsIsAutoConfigured() {
|
||||
this.runner.run((context) -> assertThat(context).hasSingleBean(JerseyWebEndpointsResourcesRegistrar.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnServletWebApplication() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class));
|
||||
contextRunner
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnClassResourceConfig() {
|
||||
this.runner.withClassLoader(new FilteredClassLoader(ResourceConfig.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* Integration tests for the Jersey actuator endpoints.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyEndpointIntegrationTests {
|
||||
|
||||
@Test
|
||||
void linksAreProvidedToAllEndpointTypes() {
|
||||
testJerseyEndpoints(new Class<?>[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
void linksPageIsNotAvailableWhenDisabled() {
|
||||
getContextRunner(new Class<?>[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class })
|
||||
.withPropertyValues("management.endpoints.web.discovery.enabled:false").run((context) -> {
|
||||
int port = context
|
||||
.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
|
||||
.getWebServer().getPort();
|
||||
WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port)
|
||||
.responseTimeout(Duration.ofMinutes(5)).build();
|
||||
client.get().uri("/actuator").exchange().expectStatus().isNotFound();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorEndpointsWhenUserProvidedResourceConfigBeanNotAvailable() {
|
||||
testJerseyEndpoints(new Class<?>[] { EndpointsConfiguration.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorEndpointsWhenSecurityAvailable() {
|
||||
WebApplicationContextRunner contextRunner = getContextRunner(
|
||||
new Class<?>[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class },
|
||||
getAutoconfigurations(SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class));
|
||||
contextRunner.run((context) -> {
|
||||
int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
|
||||
.getWebServer().getPort();
|
||||
WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port)
|
||||
.responseTimeout(Duration.ofMinutes(5)).build();
|
||||
client.get().uri("/actuator").exchange().expectStatus().isUnauthorized();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void testJerseyEndpoints(Class<?>[] userConfigurations) {
|
||||
getContextRunner(userConfigurations).run((context) -> {
|
||||
int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
|
||||
.getWebServer().getPort();
|
||||
WebTestClient client = WebTestClient.bindToServer().baseUrl("http://localhost:" + port)
|
||||
.responseTimeout(Duration.ofMinutes(5)).build();
|
||||
client.get().uri("/actuator").exchange().expectStatus().isOk().expectBody().jsonPath("_links.beans")
|
||||
.isNotEmpty().jsonPath("_links.restcontroller").doesNotExist().jsonPath("_links.controller")
|
||||
.doesNotExist();
|
||||
});
|
||||
}
|
||||
|
||||
WebApplicationContextRunner getContextRunner(Class<?>[] userConfigurations,
|
||||
Class<?>... additionalAutoConfigurations) {
|
||||
FilteredClassLoader classLoader = new FilteredClassLoader(DispatcherServlet.class);
|
||||
return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withClassLoader(classLoader)
|
||||
.withConfiguration(AutoConfigurations.of(getAutoconfigurations(additionalAutoConfigurations)))
|
||||
.withUserConfiguration(userConfigurations)
|
||||
.withPropertyValues("management.endpoints.web.exposure.include:*", "server.port:0");
|
||||
}
|
||||
|
||||
private Class<?>[] getAutoconfigurations(Class<?>... additional) {
|
||||
List<Class<?>> autoconfigurations = new ArrayList<>(Arrays.asList(JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, EndpointAutoConfiguration.class,
|
||||
ServletWebServerFactoryAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class));
|
||||
autoconfigurations.addAll(Arrays.asList(additional));
|
||||
return autoconfigurations.toArray(new Class<?>[0]);
|
||||
}
|
||||
|
||||
@ControllerEndpoint(id = "controller")
|
||||
static class TestControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@RestControllerEndpoint(id = "restcontroller")
|
||||
static class TestRestControllerEndpoint {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class EndpointsConfiguration {
|
||||
|
||||
@Bean
|
||||
TestControllerEndpoint testControllerEndpoint() {
|
||||
return new TestControllerEndpoint();
|
||||
}
|
||||
|
||||
@Bean
|
||||
TestRestControllerEndpoint testRestControllerEndpoint() {
|
||||
return new TestRestControllerEndpoint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfig testResourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.integrationtest;
|
||||
|
||||
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.system.DiskSpaceHealthContributorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* Integration tests for health groups on an additional path on Jersey.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyHealthEndpointAdditionalPathIntegrationTests extends
|
||||
AbstractHealthEndpointAdditionalPathIntegrationTests<WebApplicationContextRunner, ConfigurableWebApplicationContext, AssertableWebApplicationContext> {
|
||||
|
||||
JerseyHealthEndpointAdditionalPathIntegrationTests() {
|
||||
super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
|
||||
WebEndpointAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class,
|
||||
HealthEndpointAutoConfiguration.class, DiskSpaceHealthContributorAutoConfiguration.class))
|
||||
.withInitializer(new ServerPortInfoApplicationContextInitializer())
|
||||
.withClassLoader(new FilteredClassLoader(DispatcherServlet.class)).withPropertyValues("server.port=0"));
|
||||
}
|
||||
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.metrics.jersey;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.DefaultJerseyTagsProvider;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider;
|
||||
import io.micrometer.core.instrument.binder.jersey.server.MetricsApplicationEventListener;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.monitoring.RequestEvent;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyServerMetricsAutoConfiguration}.
|
||||
*
|
||||
* @author Michael Weirauch
|
||||
* @author Michael Simons
|
||||
*/
|
||||
class JerseyServerMetricsAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple())
|
||||
.withConfiguration(AutoConfigurations.of(JerseyServerMetricsAutoConfiguration.class));
|
||||
|
||||
private final WebApplicationContextRunner webContextRunner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class,
|
||||
JerseyServerMetricsAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
|
||||
SimpleMetricsExportAutoConfiguration.class, MetricsAutoConfiguration.class))
|
||||
.withUserConfiguration(ResourceConfiguration.class).withPropertyValues("server.port:0");
|
||||
|
||||
@Test
|
||||
void shouldOnlyBeActiveInWebApplicationContext() {
|
||||
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ResourceConfigCustomizer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldProvideAllNecessaryBeans() {
|
||||
this.webContextRunner.run((context) -> assertThat(context).hasSingleBean(DefaultJerseyTagsProvider.class)
|
||||
.hasSingleBean(ResourceConfigCustomizer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHonorExistingTagProvider() {
|
||||
this.webContextRunner.withUserConfiguration(CustomJerseyTagsProviderConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(CustomJerseyTagsProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpRequestsAreTimed() {
|
||||
this.webContextRunner.run((context) -> {
|
||||
doRequest(context);
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
Timer timer = registry.get("http.server.requests").tag("uri", "/users/{id}").timer();
|
||||
assertThat(timer.count()).isEqualTo(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void noHttpRequestsTimedWhenJerseyInstrumentationMissingFromClasspath() {
|
||||
this.webContextRunner.withClassLoader(new FilteredClassLoader(MetricsApplicationEventListener.class))
|
||||
.run((context) -> {
|
||||
doRequest(context);
|
||||
|
||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||
assertThat(registry.find("http.server.requests").timer()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
private static void doRequest(AssertableWebApplicationContext context) {
|
||||
int port = context.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
|
||||
.getWebServer().getPort();
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.getForEntity(URI.create("http://localhost:" + port + "/users/3"), String.class);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig().register(new TestResource());
|
||||
}
|
||||
|
||||
@Path("/users")
|
||||
public class TestResource {
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public String getUser(@PathParam("id") String id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomJerseyTagsProviderConfiguration {
|
||||
|
||||
@Bean
|
||||
JerseyTagsProvider customJerseyTagsProvider() {
|
||||
return new CustomJerseyTagsProvider();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class CustomJerseyTagsProvider implements JerseyTagsProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> httpRequestTags(RequestEvent event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> httpLongRequestTags(RequestEvent event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.actuate.autoconfigure.security.servlet;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link EndpointRequest} with Jersey.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyEndpointRequestIntegrationTests extends AbstractEndpointRequestIntegrationTests {
|
||||
|
||||
@Test
|
||||
void toLinksWhenApplicationPathSetShouldMatch() {
|
||||
getContextRunner().withPropertyValues("spring.jersey.application-path=/admin").run((context) -> {
|
||||
WebTestClient webTestClient = getWebTestClient(context);
|
||||
webTestClient.get().uri("/admin/actuator/").exchange().expectStatus().isOk();
|
||||
webTestClient.get().uri("/admin/actuator").exchange().expectStatus().isOk();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void toEndpointWhenApplicationPathSetShouldMatch() {
|
||||
getContextRunner().withPropertyValues("spring.jersey.application-path=/admin").run((context) -> {
|
||||
WebTestClient webTestClient = getWebTestClient(context);
|
||||
webTestClient.get().uri("/admin/actuator/e1").exchange().expectStatus().isOk();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void toAnyEndpointWhenApplicationPathSetShouldMatch() {
|
||||
getContextRunner()
|
||||
.withPropertyValues("spring.jersey.application-path=/admin", "spring.security.user.password=password")
|
||||
.run((context) -> {
|
||||
WebTestClient webTestClient = getWebTestClient(context);
|
||||
webTestClient.get().uri("/admin/actuator/e2").exchange().expectStatus().isUnauthorized();
|
||||
webTestClient.get().uri("/admin/actuator/e2").header("Authorization", getBasicAuth()).exchange()
|
||||
.expectStatus().isOk();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void toAnyEndpointShouldMatchServletEndpoint() {
|
||||
getContextRunner().withPropertyValues("spring.security.user.password=password",
|
||||
"management.endpoints.web.exposure.include=se1").run((context) -> {
|
||||
WebTestClient webTestClient = getWebTestClient(context);
|
||||
webTestClient.get().uri("/actuator/se1").exchange().expectStatus().isUnauthorized();
|
||||
webTestClient.get().uri("/actuator/se1").header("Authorization", getBasicAuth()).exchange()
|
||||
.expectStatus().isOk();
|
||||
webTestClient.get().uri("/actuator/se1/list").exchange().expectStatus().isUnauthorized();
|
||||
webTestClient.get().uri("/actuator/se1/list").header("Authorization", getBasicAuth()).exchange()
|
||||
.expectStatus().isOk();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void toAnyEndpointWhenApplicationPathSetShouldMatchServletEndpoint() {
|
||||
getContextRunner().withPropertyValues("spring.jersey.application-path=/admin",
|
||||
"spring.security.user.password=password", "management.endpoints.web.exposure.include=se1")
|
||||
.run((context) -> {
|
||||
WebTestClient webTestClient = getWebTestClient(context);
|
||||
webTestClient.get().uri("/admin/actuator/se1").exchange().expectStatus().isUnauthorized();
|
||||
webTestClient.get().uri("/admin/actuator/se1").header("Authorization", getBasicAuth()).exchange()
|
||||
.expectStatus().isOk();
|
||||
webTestClient.get().uri("/admin/actuator/se1/list").exchange().expectStatus().isUnauthorized();
|
||||
webTestClient.get().uri("/admin/actuator/se1/list").header("Authorization", getBasicAuth())
|
||||
.exchange().expectStatus().isOk();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WebApplicationContextRunner createContextRunner() {
|
||||
return new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
.withUserConfiguration(JerseyEndpointConfiguration.class)
|
||||
.withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(WebEndpointProperties.class)
|
||||
static class JerseyEndpointConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcat() {
|
||||
return new TomcatServletWebServerFactory(0);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.AntPathRequestMatcherProvider;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.RequestMatcherProvider;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
@ -67,17 +66,6 @@ class SecurityRequestMatchersManagementContextConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registersRequestMatcherForJerseyProviderIfJerseyPresentAndMvcAbsent() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
.withUserConfiguration(TestJerseyConfiguration.class).run((context) -> {
|
||||
AntPathRequestMatcherProvider matcherProvider = context
|
||||
.getBean(AntPathRequestMatcherProvider.class);
|
||||
RequestMatcher requestMatcher = matcherProvider.getRequestMatcher("/example");
|
||||
assertThat(requestMatcher).extracting("pattern").isEqualTo("/admin/example");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void mvcRequestMatcherProviderConditionalOnDispatcherServletClass() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
@ -91,20 +79,6 @@ class SecurityRequestMatchersManagementContextConfigurationTests {
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AntPathRequestMatcherProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jerseyRequestMatcherProviderConditionalOnResourceConfigClass() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("org.glassfish.jersey.server.ResourceConfig"))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AntPathRequestMatcherProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jerseyRequestMatcherProviderConditionalOnJerseyApplicationPathBean() {
|
||||
new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(SecurityRequestMatchersManagementContextConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader("org.springframework.web.servlet.DispatcherServlet"))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(AntPathRequestMatcherProvider.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestMvcConfiguration {
|
||||
|
||||
@ -115,14 +89,4 @@ class SecurityRequestMatchersManagementContextConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestJerseyConfiguration {
|
||||
|
||||
@Bean
|
||||
JerseyApplicationPath jerseyApplicationPath() {
|
||||
return () -> "/admin";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyChildManagementContextConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@ClassPathExclusions("spring-webmvc-*")
|
||||
class JerseyChildManagementContextConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withUserConfiguration(JerseyChildManagementContextConfiguration.class);
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnServletWebApplication() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class));
|
||||
contextRunner
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnClassResourceConfig() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(ResourceConfig.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jerseyApplicationPathIsAutoConfigured() {
|
||||
this.contextRunner.run((context) -> {
|
||||
JerseyApplicationPath bean = context.getBean(JerseyApplicationPath.class);
|
||||
assertThat(bean.getPath()).isEqualTo("/");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void servletRegistrationBeanIsAutoConfigured() {
|
||||
this.contextRunner.run((context) -> {
|
||||
ServletRegistrationBean<ServletContainer> bean = context.getBean(ServletRegistrationBean.class);
|
||||
assertThat(bean.getUrlMappings()).containsExactly("/*");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourceConfigCustomizerBeanIsNotRequired() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ResourceConfig.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() {
|
||||
this.contextRunner.withUserConfiguration(CustomizerConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ResourceConfig.class);
|
||||
ResourceConfig config = context.getBean(ResourceConfig.class);
|
||||
ManagementContextResourceConfigCustomizer customizer = context
|
||||
.getBean(ManagementContextResourceConfigCustomizer.class);
|
||||
verify(customizer).customize(config);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
ManagementContextResourceConfigCustomizer resourceConfigCustomizer() {
|
||||
return mock(ManagementContextResourceConfigCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.autoconfigure.web.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseySameManagementContextConfiguration}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@ClassPathExclusions("spring-webmvc-*")
|
||||
class JerseySameManagementContextConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class));
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnServletWebApplication() {
|
||||
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class));
|
||||
contextRunner
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfigurationIsConditionalOnClassResourceConfig() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(ResourceConfig.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JerseySameManagementContextConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jerseyApplicationPathIsAutoConfiguredWhenNeeded() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(DefaultJerseyApplicationPath.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void jerseyApplicationPathIsConditionalOnMissingBean() {
|
||||
this.contextRunner.withUserConfiguration(ConfigWithJerseyApplicationPath.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(JerseyApplicationPath.class);
|
||||
assertThat(context).hasBean("testJerseyApplicationPath");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void existingResourceConfigBeanShouldNotAutoConfigureRelatedBeans() {
|
||||
this.contextRunner.withUserConfiguration(ConfigWithResourceConfig.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ResourceConfig.class);
|
||||
assertThat(context).doesNotHaveBean(JerseyApplicationPath.class);
|
||||
assertThat(context).doesNotHaveBean(ServletRegistrationBean.class);
|
||||
assertThat(context).hasBean("customResourceConfig");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void servletRegistrationBeanIsAutoConfiguredWhenNeeded() {
|
||||
this.contextRunner.withPropertyValues("spring.jersey.application-path=/jersey").run((context) -> {
|
||||
ServletRegistrationBean<ServletContainer> bean = context.getBean(ServletRegistrationBean.class);
|
||||
assertThat(bean.getUrlMappings()).containsExactly("/jersey/*");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() {
|
||||
this.contextRunner.withUserConfiguration(CustomizerConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ResourceConfig.class);
|
||||
ResourceConfig config = context.getBean(ResourceConfig.class);
|
||||
ManagementContextResourceConfigCustomizer customizer = context
|
||||
.getBean(ManagementContextResourceConfigCustomizer.class);
|
||||
verify(customizer).customize(config);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ConfigWithJerseyApplicationPath {
|
||||
|
||||
@Bean
|
||||
JerseyApplicationPath testJerseyApplicationPath() {
|
||||
return mock(JerseyApplicationPath.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ConfigWithResourceConfig {
|
||||
|
||||
@Bean
|
||||
ResourceConfig customResourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
ManagementContextResourceConfigCustomizer resourceConfigCustomizer() {
|
||||
return mock(ManagementContextResourceConfigCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -50,8 +50,6 @@ dependencies {
|
||||
}
|
||||
optional("org.elasticsearch:elasticsearch")
|
||||
optional("org.flywaydb:flyway-core")
|
||||
optional("org.glassfish.jersey.core:jersey-server")
|
||||
optional("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
optional("org.hibernate.validator:hibernate-validator")
|
||||
optional("org.influxdb:influxdb-java")
|
||||
optional("org.liquibase:liquibase-core") {
|
||||
@ -91,7 +89,6 @@ dependencies {
|
||||
testImplementation("io.r2dbc:r2dbc-h2")
|
||||
testImplementation("org.apache.logging.log4j:log4j-to-slf4j")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
testImplementation("org.hamcrest:hamcrest")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
testImplementation("org.mockito:mockito-core")
|
||||
@ -105,6 +102,5 @@ dependencies {
|
||||
testRuntimeOnly("io.projectreactor.netty:reactor-netty-http")
|
||||
testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api")
|
||||
testRuntimeOnly("org.apache.tomcat.embed:tomcat-embed-el")
|
||||
testRuntimeOnly("org.glassfish.jersey.ext:jersey-spring5")
|
||||
testRuntimeOnly("org.hsqldb:hsqldb")
|
||||
}
|
||||
|
@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.endpoint.web.jersey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.glassfish.jersey.process.Inflector;
|
||||
import org.glassfish.jersey.server.ContainerRequest;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.glassfish.jersey.server.model.Resource.Builder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
|
||||
import org.springframework.boot.actuate.endpoint.InvocationContext;
|
||||
import org.springframework.boot.actuate.endpoint.OperationArgumentResolver;
|
||||
import org.springframework.boot.actuate.endpoint.ProducibleOperationArgumentResolver;
|
||||
import org.springframework.boot.actuate.endpoint.SecurityContext;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.web.Link;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A factory for creating Jersey {@link Resource Resources} for {@link WebOperation web
|
||||
* endpoint operations}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JerseyEndpointResourceFactory {
|
||||
|
||||
/**
|
||||
* Creates {@link Resource Resources} for the operations of the given
|
||||
* {@code webEndpoints}.
|
||||
* @param endpointMapping the base mapping for all endpoints
|
||||
* @param endpoints the web endpoints
|
||||
* @param endpointMediaTypes media types consumed and produced by the endpoints
|
||||
* @param linksResolver resolver for determining links to available endpoints
|
||||
* @param shouldRegisterLinks should register links
|
||||
* @return the resources for the operations
|
||||
*/
|
||||
public Collection<Resource> createEndpointResources(EndpointMapping endpointMapping,
|
||||
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver, boolean shouldRegisterLinks) {
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
endpoints.stream().flatMap((endpoint) -> endpoint.getOperations().stream())
|
||||
.map((operation) -> createResource(endpointMapping, operation)).forEach(resources::add);
|
||||
if (shouldRegisterLinks) {
|
||||
Resource resource = createEndpointLinksResource(endpointMapping.getPath(), endpointMediaTypes,
|
||||
linksResolver);
|
||||
resources.add(resource);
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
protected Resource createResource(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
WebOperationRequestPredicate requestPredicate = operation.getRequestPredicate();
|
||||
String path = requestPredicate.getPath();
|
||||
String matchAllRemainingPathSegmentsVariable = requestPredicate.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
path = path.replace("{*" + matchAllRemainingPathSegmentsVariable + "}",
|
||||
"{" + matchAllRemainingPathSegmentsVariable + ": .*}");
|
||||
}
|
||||
return getResource(endpointMapping, operation, requestPredicate, path, null, null);
|
||||
}
|
||||
|
||||
protected Resource getResource(EndpointMapping endpointMapping, WebOperation operation,
|
||||
WebOperationRequestPredicate requestPredicate, String path, WebServerNamespace serverNamespace,
|
||||
JerseyRemainingPathSegmentProvider remainingPathSegmentProvider) {
|
||||
Builder resourceBuilder = Resource.builder().path(endpointMapping.getPath())
|
||||
.path(endpointMapping.createSubPath(path));
|
||||
resourceBuilder.addMethod(requestPredicate.getHttpMethod().name())
|
||||
.consumes(StringUtils.toStringArray(requestPredicate.getConsumes()))
|
||||
.produces(StringUtils.toStringArray(requestPredicate.getProduces()))
|
||||
.handledBy(new OperationInflector(operation, !requestPredicate.getConsumes().isEmpty(), serverNamespace,
|
||||
remainingPathSegmentProvider));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
|
||||
private Resource createEndpointLinksResource(String endpointPath, EndpointMediaTypes endpointMediaTypes,
|
||||
EndpointLinksResolver linksResolver) {
|
||||
Builder resourceBuilder = Resource.builder().path(endpointPath);
|
||||
resourceBuilder.addMethod("GET").produces(StringUtils.toStringArray(endpointMediaTypes.getProduced()))
|
||||
.handledBy(new EndpointLinksInflector(linksResolver));
|
||||
return resourceBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Inflector} to invoke the {@link WebOperation}.
|
||||
*/
|
||||
private static final class OperationInflector implements Inflector<ContainerRequestContext, Object> {
|
||||
|
||||
private static final String PATH_SEPARATOR = AntPathMatcher.DEFAULT_PATH_SEPARATOR;
|
||||
|
||||
private static final List<Function<Object, Object>> BODY_CONVERTERS;
|
||||
|
||||
static {
|
||||
List<Function<Object, Object>> converters = new ArrayList<>();
|
||||
converters.add(new ResourceBodyConverter());
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Mono", OperationInflector.class.getClassLoader())) {
|
||||
converters.add(new MonoBodyConverter());
|
||||
}
|
||||
BODY_CONVERTERS = Collections.unmodifiableList(converters);
|
||||
}
|
||||
|
||||
private final WebOperation operation;
|
||||
|
||||
private final boolean readBody;
|
||||
|
||||
private final WebServerNamespace serverNamespace;
|
||||
|
||||
private final JerseyRemainingPathSegmentProvider remainingPathSegmentProvider;
|
||||
|
||||
private OperationInflector(WebOperation operation, boolean readBody, WebServerNamespace serverNamespace,
|
||||
JerseyRemainingPathSegmentProvider remainingPathSegments) {
|
||||
this.operation = operation;
|
||||
this.readBody = readBody;
|
||||
this.serverNamespace = serverNamespace;
|
||||
this.remainingPathSegmentProvider = remainingPathSegments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response apply(ContainerRequestContext data) {
|
||||
Map<String, Object> arguments = new HashMap<>();
|
||||
if (this.readBody) {
|
||||
arguments.putAll(extractBodyArguments(data));
|
||||
}
|
||||
arguments.putAll(extractPathParameters(data));
|
||||
arguments.putAll(extractQueryParameters(data));
|
||||
try {
|
||||
JerseySecurityContext securityContext = new JerseySecurityContext(data.getSecurityContext());
|
||||
OperationArgumentResolver serverNamespaceArgumentResolver = OperationArgumentResolver
|
||||
.of(WebServerNamespace.class, () -> this.serverNamespace);
|
||||
InvocationContext invocationContext = new InvocationContext(securityContext, arguments,
|
||||
serverNamespaceArgumentResolver,
|
||||
new ProducibleOperationArgumentResolver(() -> data.getHeaders().get("Accept")));
|
||||
Object response = this.operation.invoke(invocationContext);
|
||||
return convertToJaxRsResponse(response, data.getRequest().getMethod());
|
||||
}
|
||||
catch (InvalidEndpointRequestException ex) {
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> extractBodyArguments(ContainerRequestContext data) {
|
||||
Map<String, Object> entity = ((ContainerRequest) data).readEntity(Map.class);
|
||||
return (entity != null) ? entity : Collections.emptyMap();
|
||||
}
|
||||
|
||||
private Map<String, Object> extractPathParameters(ContainerRequestContext requestContext) {
|
||||
Map<String, Object> pathParameters = extract(requestContext.getUriInfo().getPathParameters());
|
||||
String matchAllRemainingPathSegmentsVariable = this.operation.getRequestPredicate()
|
||||
.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
String remainingPathSegments = getRemainingPathSegments(requestContext, pathParameters,
|
||||
matchAllRemainingPathSegmentsVariable);
|
||||
pathParameters.put(matchAllRemainingPathSegmentsVariable, tokenizePathSegments(remainingPathSegments));
|
||||
}
|
||||
return pathParameters;
|
||||
}
|
||||
|
||||
private String getRemainingPathSegments(ContainerRequestContext requestContext,
|
||||
Map<String, Object> pathParameters, String matchAllRemainingPathSegmentsVariable) {
|
||||
if (this.remainingPathSegmentProvider != null) {
|
||||
return this.remainingPathSegmentProvider.get(requestContext, matchAllRemainingPathSegmentsVariable);
|
||||
}
|
||||
return (String) pathParameters.get(matchAllRemainingPathSegmentsVariable);
|
||||
}
|
||||
|
||||
private String[] tokenizePathSegments(String path) {
|
||||
String[] segments = StringUtils.tokenizeToStringArray(path, PATH_SEPARATOR, false, true);
|
||||
for (int i = 0; i < segments.length; i++) {
|
||||
if (segments[i].contains("%")) {
|
||||
segments[i] = StringUtils.uriDecode(segments[i], StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
private Map<String, Object> extractQueryParameters(ContainerRequestContext requestContext) {
|
||||
return extract(requestContext.getUriInfo().getQueryParameters());
|
||||
}
|
||||
|
||||
private Map<String, Object> extract(MultivaluedMap<String, String> multivaluedMap) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
multivaluedMap.forEach((name, values) -> {
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
result.put(name, (values.size() != 1) ? values : values.get(0));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private Response convertToJaxRsResponse(Object response, String httpMethod) {
|
||||
if (response == null) {
|
||||
boolean isGet = HttpMethod.GET.equals(httpMethod);
|
||||
Status status = isGet ? Status.NOT_FOUND : Status.NO_CONTENT;
|
||||
return Response.status(status).build();
|
||||
}
|
||||
try {
|
||||
if (!(response instanceof WebEndpointResponse)) {
|
||||
return Response.status(Status.OK).entity(convertIfNecessary(response)).build();
|
||||
}
|
||||
WebEndpointResponse<?> webEndpointResponse = (WebEndpointResponse<?>) response;
|
||||
return Response.status(webEndpointResponse.getStatus())
|
||||
.header("Content-Type", webEndpointResponse.getContentType())
|
||||
.entity(convertIfNecessary(webEndpointResponse.getBody())).build();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(Object body) throws IOException {
|
||||
for (Function<Object, Object> converter : BODY_CONVERTERS) {
|
||||
body = converter.apply(body);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Body converter from {@link org.springframework.core.io.Resource} to
|
||||
* {@link InputStream}.
|
||||
*/
|
||||
private static final class ResourceBodyConverter implements Function<Object, Object> {
|
||||
|
||||
@Override
|
||||
public Object apply(Object body) {
|
||||
if (body instanceof org.springframework.core.io.Resource) {
|
||||
try {
|
||||
return ((org.springframework.core.io.Resource) body).getInputStream();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Body converter from {@link Mono} to {@link Mono#block()}.
|
||||
*/
|
||||
private static final class MonoBodyConverter implements Function<Object, Object> {
|
||||
|
||||
@Override
|
||||
public Object apply(Object body) {
|
||||
if (body instanceof Mono) {
|
||||
return ((Mono<?>) body).block();
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Inflector} to for endpoint links.
|
||||
*/
|
||||
private static final class EndpointLinksInflector implements Inflector<ContainerRequestContext, Response> {
|
||||
|
||||
private final EndpointLinksResolver linksResolver;
|
||||
|
||||
private EndpointLinksInflector(EndpointLinksResolver linksResolver) {
|
||||
this.linksResolver = linksResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response apply(ContainerRequestContext request) {
|
||||
Map<String, Link> links = this.linksResolver
|
||||
.resolveLinks(request.getUriInfo().getAbsolutePath().toString());
|
||||
return Response.ok(Collections.singletonMap("_links", links)).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class JerseySecurityContext implements SecurityContext {
|
||||
|
||||
private final javax.ws.rs.core.SecurityContext securityContext;
|
||||
|
||||
private JerseySecurityContext(javax.ws.rs.core.SecurityContext securityContext) {
|
||||
this.securityContext = securityContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getPrincipal() {
|
||||
return this.securityContext.getUserPrincipal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
return this.securityContext.isUserInRole(role);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.endpoint.web.jersey;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperation;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate;
|
||||
import org.springframework.boot.actuate.endpoint.web.WebServerNamespace;
|
||||
import org.springframework.boot.actuate.health.AdditionalHealthEndpointPath;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroup;
|
||||
import org.springframework.boot.actuate.health.HealthEndpointGroups;
|
||||
|
||||
/**
|
||||
* A factory for creating Jersey {@link Resource Resources} for health groups with
|
||||
* additional path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public class JerseyHealthEndpointAdditionalPathResourceFactory extends JerseyEndpointResourceFactory {
|
||||
|
||||
private final Set<HealthEndpointGroup> groups;
|
||||
|
||||
private final WebServerNamespace serverNamespace;
|
||||
|
||||
public JerseyHealthEndpointAdditionalPathResourceFactory(WebServerNamespace serverNamespace,
|
||||
HealthEndpointGroups groups) {
|
||||
this.serverNamespace = serverNamespace;
|
||||
this.groups = groups.getAllWithAdditionalPath(serverNamespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Resource createResource(EndpointMapping endpointMapping, WebOperation operation) {
|
||||
WebOperationRequestPredicate requestPredicate = operation.getRequestPredicate();
|
||||
String matchAllRemainingPathSegmentsVariable = requestPredicate.getMatchAllRemainingPathSegmentsVariable();
|
||||
if (matchAllRemainingPathSegmentsVariable != null) {
|
||||
for (HealthEndpointGroup group : this.groups) {
|
||||
AdditionalHealthEndpointPath additionalPath = group.getAdditionalPath();
|
||||
if (additionalPath != null) {
|
||||
return getResource(endpointMapping, operation, requestPredicate, additionalPath.getValue(),
|
||||
this.serverNamespace, (data, pathSegmentsVariable) -> data.getUriInfo().getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.actuate.endpoint.web.jersey;
|
||||
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
|
||||
/**
|
||||
* Strategy interface used to provide the remaining path segments for a Jersey actuator
|
||||
* endpoint.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
interface JerseyRemainingPathSegmentProvider {
|
||||
|
||||
String get(ContainerRequestContext requestContext, String matchAllRemainingPathSegmentsVariable);
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Jersey support for actuator endpoints.
|
||||
*/
|
||||
package org.springframework.boot.actuate.endpoint.web.jersey;
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.actuate.endpoint.web.jersey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.ext.ContextResolver;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.AbstractWebEndpointIntegrationTests;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
/**
|
||||
* Integration tests for web endpoints exposed using Jersey.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @see JerseyEndpointResourceFactory
|
||||
*/
|
||||
public class JerseyWebEndpointIntegrationTests
|
||||
extends AbstractWebEndpointIntegrationTests<AnnotationConfigServletWebServerApplicationContext> {
|
||||
|
||||
public JerseyWebEndpointIntegrationTests() {
|
||||
super(JerseyWebEndpointIntegrationTests::createApplicationContext,
|
||||
JerseyWebEndpointIntegrationTests::applyAuthenticatedConfiguration);
|
||||
}
|
||||
|
||||
private static AnnotationConfigServletWebServerApplicationContext createApplicationContext() {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
context.register(JerseyConfiguration.class);
|
||||
return context;
|
||||
}
|
||||
|
||||
private static void applyAuthenticatedConfiguration(AnnotationConfigServletWebServerApplicationContext context) {
|
||||
context.register(AuthenticatedConfiguration.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPort(AnnotationConfigServletWebServerApplicationContext context) {
|
||||
return context.getWebServer().getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateErrorBody(WebTestClient.BodyContentSpec body, HttpStatus status, String path,
|
||||
String message) {
|
||||
// Jersey doesn't support the general error page handling
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JerseyConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcat() {
|
||||
return new TomcatServletWebServerFactory(0);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean<ServletContainer> servletContainer(ResourceConfig resourceConfig) {
|
||||
return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), "/*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig(Environment environment, WebEndpointDiscoverer endpointDiscoverer,
|
||||
EndpointMediaTypes endpointMediaTypes) {
|
||||
ResourceConfig resourceConfig = new ResourceConfig();
|
||||
String endpointPath = environment.getProperty("endpointPath");
|
||||
Collection<Resource> resources = new JerseyEndpointResourceFactory().createEndpointResources(
|
||||
new EndpointMapping(endpointPath), endpointDiscoverer.getEndpoints(), endpointMediaTypes,
|
||||
new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath));
|
||||
resourceConfig.registerResources(new HashSet<>(resources));
|
||||
resourceConfig.register(JacksonFeature.class);
|
||||
resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()), ContextResolver.class);
|
||||
return resourceConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class AuthenticatedConfiguration {
|
||||
|
||||
@Bean
|
||||
Filter securityFilter() {
|
||||
return new OncePerRequestFilter() {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
context.setAuthentication(new UsernamePasswordAuthenticationToken("Alice", "secret",
|
||||
Arrays.asList(new SimpleGrantedAuthority("ROLE_ACTUATOR"))));
|
||||
SecurityContextHolder.setContext(context);
|
||||
try {
|
||||
filterChain.doFilter(new SecurityContextHolderAwareRequestWrapper(request, "ROLE_"), response);
|
||||
}
|
||||
finally {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private ObjectMapperContextResolver(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper getContext(Class<?> type) {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -17,16 +17,12 @@
|
||||
package org.springframework.boot.actuate.endpoint.web.test;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.model.Resource;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.Extension;
|
||||
@ -41,14 +37,11 @@ import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
|
||||
import org.springframework.boot.actuate.endpoint.web.jersey.JerseyEndpointResourceFactory;
|
||||
import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping;
|
||||
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
@ -91,22 +84,12 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation
|
||||
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
|
||||
ExtensionContext extensionContext) {
|
||||
return Stream.of(
|
||||
new WebEndpointsInvocationContext("Jersey",
|
||||
WebEndpointTestInvocationContextProvider::createJerseyContext),
|
||||
new WebEndpointsInvocationContext("WebMvc",
|
||||
WebEndpointTestInvocationContextProvider::createWebMvcContext),
|
||||
new WebEndpointsInvocationContext("WebFlux",
|
||||
WebEndpointTestInvocationContextProvider::createWebFluxContext));
|
||||
}
|
||||
|
||||
private static ConfigurableApplicationContext createJerseyContext(List<Class<?>> classes) {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
classes.add(JerseyEndpointConfiguration.class);
|
||||
context.register(ClassUtils.toClassArray(classes));
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
private static ConfigurableApplicationContext createWebMvcContext(List<Class<?>> classes) {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
classes.add(WebMvcEndpointConfiguration.class);
|
||||
@ -208,44 +191,6 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class })
|
||||
static class JerseyEndpointConfiguration {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
JerseyEndpointConfiguration(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcat() {
|
||||
return new TomcatServletWebServerFactory(0);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer webEndpointRegistrar() {
|
||||
return this::customize;
|
||||
}
|
||||
|
||||
private void customize(ResourceConfig config) {
|
||||
EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT;
|
||||
WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext,
|
||||
new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
Collection<Resource> resources = new JerseyEndpointResourceFactory().createEndpointResources(
|
||||
new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes,
|
||||
new EndpointLinksResolver(discoverer.getEndpoints()), true);
|
||||
config.registerResources(new HashSet<>(resources));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, WebFluxAutoConfiguration.class })
|
||||
static class WebFluxEndpointConfiguration implements ApplicationListener<WebServerInitializedEvent> {
|
||||
|
@ -110,11 +110,6 @@ dependencies {
|
||||
}
|
||||
optional("org.flywaydb:flyway-core")
|
||||
optional("org.freemarker:freemarker")
|
||||
optional("org.glassfish.jersey.core:jersey-server")
|
||||
optional("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
optional("org.glassfish.jersey.containers:jersey-container-servlet")
|
||||
optional("org.glassfish.jersey.ext:jersey-spring5")
|
||||
optional("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
optional("org.hibernate:hibernate-core") {
|
||||
exclude group: "javax.activation", module: "javax.activation-api"
|
||||
exclude group: "javax.persistence", module: "javax.persistence-api"
|
||||
|
@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRegistration;
|
||||
import javax.ws.rs.ext.ContextResolver;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import com.fasterxml.jackson.databind.AnnotationIntrospector;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.cfg.MapperConfig;
|
||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.spring.SpringComponentProvider;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.glassfish.jersey.servlet.ServletProperties;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.DynamicRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
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.util.ClassUtils;
|
||||
import org.springframework.web.WebApplicationInitializer;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.filter.RequestContextFilter;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Jersey.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Andy Wilkinson
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ SpringComponentProvider.class, ServletRegistration.class })
|
||||
@ConditionalOnBean(type = "org.glassfish.jersey.server.ResourceConfig")
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@AutoConfigureBefore(DispatcherServletAutoConfiguration.class)
|
||||
@AutoConfigureAfter(JacksonAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(JerseyProperties.class)
|
||||
public class JerseyAutoConfiguration implements ServletContextAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JerseyAutoConfiguration.class);
|
||||
|
||||
private final JerseyProperties jersey;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
public JerseyAutoConfiguration(JerseyProperties jersey, ResourceConfig config,
|
||||
ObjectProvider<ResourceConfigCustomizer> customizers) {
|
||||
this.jersey = jersey;
|
||||
this.config = config;
|
||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(this.config));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingFilterBean(RequestContextFilter.class)
|
||||
public FilterRegistrationBean<RequestContextFilter> requestContextFilter() {
|
||||
FilterRegistrationBean<RequestContextFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new RequestContextFilter());
|
||||
registration.setOrder(this.jersey.getFilter().getOrder() - 1);
|
||||
registration.setName("requestContextFilter");
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JerseyApplicationPath jerseyApplicationPath() {
|
||||
return new DefaultJerseyApplicationPath(this.jersey.getApplicationPath(), this.config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jerseyFilterRegistration")
|
||||
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter")
|
||||
public FilterRegistrationBean<ServletContainer> jerseyFilterRegistration(JerseyApplicationPath applicationPath) {
|
||||
FilterRegistrationBean<ServletContainer> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new ServletContainer(this.config));
|
||||
registration.setUrlPatterns(Collections.singletonList(applicationPath.getUrlMapping()));
|
||||
registration.setOrder(this.jersey.getFilter().getOrder());
|
||||
registration.addInitParameter(ServletProperties.FILTER_CONTEXT_PATH, stripPattern(applicationPath.getPath()));
|
||||
addInitParameters(registration);
|
||||
registration.setName("jerseyFilter");
|
||||
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
|
||||
return registration;
|
||||
}
|
||||
|
||||
private String stripPattern(String path) {
|
||||
if (path.endsWith("/*")) {
|
||||
path = path.substring(0, path.lastIndexOf("/*"));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jerseyServletRegistration")
|
||||
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true)
|
||||
public ServletRegistrationBean<ServletContainer> jerseyServletRegistration(JerseyApplicationPath applicationPath) {
|
||||
ServletRegistrationBean<ServletContainer> registration = new ServletRegistrationBean<>(
|
||||
new ServletContainer(this.config), applicationPath.getUrlMapping());
|
||||
addInitParameters(registration);
|
||||
registration.setName(getServletRegistrationName());
|
||||
registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup());
|
||||
return registration;
|
||||
}
|
||||
|
||||
private String getServletRegistrationName() {
|
||||
return ClassUtils.getUserClass(this.config.getClass()).getName();
|
||||
}
|
||||
|
||||
private void addInitParameters(DynamicRegistrationBean<?> registration) {
|
||||
this.jersey.getInit().forEach(registration::addInitParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
String servletRegistrationName = getServletRegistrationName();
|
||||
ServletRegistration registration = servletContext.getServletRegistration(servletRegistrationName);
|
||||
if (registration != null) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Configuring existing registration for Jersey servlet '" + servletRegistrationName + "'");
|
||||
}
|
||||
registration.setInitParameters(this.jersey.getInit());
|
||||
}
|
||||
}
|
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public static final class JerseyWebApplicationInitializer implements WebApplicationInitializer {
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
// We need to switch *off* the Jersey WebApplicationInitializer because it
|
||||
// will try and register a ContextLoaderListener which we don't need
|
||||
servletContext.setInitParameter("contextConfigLocation", "<NONE>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(JacksonFeature.class)
|
||||
@ConditionalOnSingleCandidate(ObjectMapper.class)
|
||||
static class JacksonResourceConfigCustomizer {
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer resourceConfigCustomizer(final ObjectMapper objectMapper) {
|
||||
return (ResourceConfig config) -> {
|
||||
config.register(JacksonFeature.class);
|
||||
config.register(new ObjectMapperContextResolver(objectMapper), ContextResolver.class);
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ JaxbAnnotationIntrospector.class, XmlElement.class })
|
||||
static class JaxbObjectMapperCustomizer {
|
||||
|
||||
@Autowired
|
||||
void addJaxbAnnotationIntrospector(ObjectMapper objectMapper) {
|
||||
JaxbAnnotationIntrospector jaxbAnnotationIntrospector = new JaxbAnnotationIntrospector(
|
||||
objectMapper.getTypeFactory());
|
||||
objectMapper.setAnnotationIntrospectors(
|
||||
createPair(objectMapper.getSerializationConfig(), jaxbAnnotationIntrospector),
|
||||
createPair(objectMapper.getDeserializationConfig(), jaxbAnnotationIntrospector));
|
||||
}
|
||||
|
||||
private AnnotationIntrospector createPair(MapperConfig<?> config,
|
||||
JaxbAnnotationIntrospector jaxbAnnotationIntrospector) {
|
||||
return AnnotationIntrospector.pair(config.getAnnotationIntrospector(), jaxbAnnotationIntrospector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private ObjectMapperContextResolver(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper getContext(Class<?> type) {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} for Jersey.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.jersey")
|
||||
public class JerseyProperties {
|
||||
|
||||
/**
|
||||
* Jersey integration type.
|
||||
*/
|
||||
private Type type = Type.SERVLET;
|
||||
|
||||
/**
|
||||
* Init parameters to pass to Jersey through the servlet or filter.
|
||||
*/
|
||||
private Map<String, String> init = new HashMap<>();
|
||||
|
||||
private final Filter filter = new Filter();
|
||||
|
||||
private final Servlet servlet = new Servlet();
|
||||
|
||||
/**
|
||||
* Path that serves as the base URI for the application. If specified, overrides the
|
||||
* value of "@ApplicationPath".
|
||||
*/
|
||||
private String applicationPath;
|
||||
|
||||
public Filter getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
public Servlet getServlet() {
|
||||
return this.servlet;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Map<String, String> getInit() {
|
||||
return this.init;
|
||||
}
|
||||
|
||||
public void setInit(Map<String, String> init) {
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
public String getApplicationPath() {
|
||||
return this.applicationPath;
|
||||
}
|
||||
|
||||
public void setApplicationPath(String applicationPath) {
|
||||
this.applicationPath = applicationPath;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
SERVLET, FILTER
|
||||
|
||||
}
|
||||
|
||||
public static class Filter {
|
||||
|
||||
/**
|
||||
* Jersey filter chain order.
|
||||
*/
|
||||
private int order;
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Servlet {
|
||||
|
||||
/**
|
||||
* Load on startup priority of the Jersey servlet.
|
||||
*/
|
||||
private int loadOnStartup = -1;
|
||||
|
||||
public int getLoadOnStartup() {
|
||||
return this.loadOnStartup;
|
||||
}
|
||||
|
||||
public void setLoadOnStartup(int loadOnStartup) {
|
||||
this.loadOnStartup = loadOnStartup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize Jersey's
|
||||
* {@link ResourceConfig} before it is used.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ResourceConfigCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the resource config.
|
||||
* @param config the {@link ResourceConfig} to customize
|
||||
*/
|
||||
void customize(ResourceConfig config);
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Jersey.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.jersey;
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.web.servlet;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyProperties;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link JerseyApplicationPath} that derives the path from
|
||||
* {@link JerseyProperties} or the {@code @ApplicationPath} annotation.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class DefaultJerseyApplicationPath implements JerseyApplicationPath {
|
||||
|
||||
private final String applicationPath;
|
||||
|
||||
private final ResourceConfig config;
|
||||
|
||||
public DefaultJerseyApplicationPath(String applicationPath, ResourceConfig config) {
|
||||
this.applicationPath = applicationPath;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return resolveApplicationPath();
|
||||
}
|
||||
|
||||
private String resolveApplicationPath() {
|
||||
if (StringUtils.hasLength(this.applicationPath)) {
|
||||
return this.applicationPath;
|
||||
}
|
||||
// Jersey doesn't like to be the default servlet, so map to /* as a fallback
|
||||
return MergedAnnotations.from(this.config.getApplication().getClass(), SearchStrategy.TYPE_HIERARCHY)
|
||||
.get(ApplicationPath.class).getValue(MergedAnnotation.VALUE, String.class).orElse("/*");
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.web.servlet;
|
||||
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
|
||||
/**
|
||||
* Interface that can be used by auto-configurations that need path details Jersey's
|
||||
* application path that serves as the base URI for the application.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.0.7
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface JerseyApplicationPath {
|
||||
|
||||
/**
|
||||
* Returns the configured path of the application.
|
||||
* @return the configured path
|
||||
*/
|
||||
String getPath();
|
||||
|
||||
/**
|
||||
* Return a form of the given path that's relative to the Jersey application path.
|
||||
* @param path the path to make relative
|
||||
* @return the relative path
|
||||
*/
|
||||
default String getRelativePath(String path) {
|
||||
String prefix = getPrefix();
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
return prefix + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a cleaned up version of the path that can be used as a prefix for URLs. The
|
||||
* resulting path will have path will not have a trailing slash.
|
||||
* @return the prefix
|
||||
* @see #getRelativePath(String)
|
||||
*/
|
||||
default String getPrefix() {
|
||||
String result = getPath();
|
||||
int index = result.indexOf('*');
|
||||
if (index != -1) {
|
||||
result = result.substring(0, index);
|
||||
}
|
||||
if (result.endsWith("/")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a URL mapping pattern that can be used with a
|
||||
* {@link ServletRegistrationBean} to map Jersey's servlet.
|
||||
* @return the path as a servlet URL mapping
|
||||
*/
|
||||
default String getUrlMapping() {
|
||||
String path = getPath();
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
if (path.equals("/")) {
|
||||
return "/*";
|
||||
}
|
||||
if (path.contains("*")) {
|
||||
return path;
|
||||
}
|
||||
if (path.endsWith("/")) {
|
||||
return path + "*";
|
||||
}
|
||||
return path + "/*";
|
||||
}
|
||||
|
||||
}
|
@ -1060,10 +1060,6 @@
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.jersey.type",
|
||||
"defaultValue": "servlet"
|
||||
},
|
||||
{
|
||||
"name": "spring.jmx.default-domain",
|
||||
"type": "java.lang.String",
|
||||
|
@ -84,7 +84,6 @@ org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
|
||||
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.Application;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using a custom {@link Application}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/test/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApplicationPath("/test")
|
||||
static class TestApplication extends Application {
|
||||
|
||||
}
|
||||
|
||||
@Path("/hello")
|
||||
public static class TestController {
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class JerseyConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestApplication testApplication() {
|
||||
return new TestApplication();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceConfig conf(TestApplication app) {
|
||||
ResourceConfig config = ResourceConfig.forApplication(app);
|
||||
config.register(TestController.class);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.context-path=/app",
|
||||
"server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomFilterContextPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomFilterPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom load on startup.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.jersey.servlet.load-on-startup=5")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomLoadOnStartupTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
assertThat(this.context.getBean("jerseyServletRegistration")).hasFieldOrPropertyWithValue("loadOnStartup", 5);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom ObjectMapper.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jackson.default-property-inclusion=non_null")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomObjectMapperProviderTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> response = this.restTemplate.getForEntity("/rest/message", String.class);
|
||||
assertThat(HttpStatus.OK).isEqualTo(response.getStatusCode());
|
||||
assertThat("{\"subject\":\"Jersey\"}").isEqualTo(response.getBody());
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/message")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public Message message() {
|
||||
return new Message("Jersey", null);
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Message {
|
||||
|
||||
private String subject;
|
||||
|
||||
private String body;
|
||||
|
||||
Message(String subject, String body) {
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.servlet.contextPath=/app")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomServletContextPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationCustomServletPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/rest/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationDefaultFilterPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using default servlet paths.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationDefaultServletPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} with an ObjectMapper.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jackson.default-property-inclusion:non-null")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationObjectMapperProviderTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void responseIsSerializedUsingAutoConfiguredObjectMapper() {
|
||||
ResponseEntity<String> response = this.restTemplate.getForEntity("/rest/message", String.class);
|
||||
assertThat(HttpStatus.OK).isEqualTo(response.getStatusCode());
|
||||
assertThat(response.getBody()).isEqualTo("{\"subject\":\"Jersey\"}");
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@ApplicationPath("/rest")
|
||||
@Path("/message")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public Message message() {
|
||||
return new Message("Jersey", null);
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Message {
|
||||
|
||||
private String subject;
|
||||
|
||||
private String body;
|
||||
|
||||
Message() {
|
||||
}
|
||||
|
||||
Message(String subject, String body) {
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return this.subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Wrapper;
|
||||
import org.apache.tomcat.util.buf.UDecoder;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfigurationServletContainerTests.Application;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests that verify the behavior when deployed to a Servlet container where Jersey may
|
||||
* have already initialized itself.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@DirtiesContext
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class JerseyAutoConfigurationServletContainerTests {
|
||||
|
||||
@Test
|
||||
void existingJerseyServletIsAmended(CapturedOutput output) {
|
||||
assertThat(output).contains("Configuring existing registration for Jersey servlet");
|
||||
assertThat(output).contains("Servlet " + Application.class.getName() + " was not registered");
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@Import(ContainerConfiguration.class)
|
||||
@Path("/hello")
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ContainerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcat() {
|
||||
return new TomcatServletWebServerFactory() {
|
||||
|
||||
@Override
|
||||
protected void postProcessContext(Context context) {
|
||||
Wrapper jerseyServlet = context.createWrapper();
|
||||
String servletName = Application.class.getName();
|
||||
jerseyServlet.setName(servletName);
|
||||
jerseyServlet.setServletClass(ServletContainer.class.getName());
|
||||
jerseyServlet.setServlet(new ServletContainer());
|
||||
jerseyServlet.setOverridable(false);
|
||||
context.addChild(jerseyServlet);
|
||||
String pattern = UDecoder.URLDecode("/*", StandardCharsets.UTF_8);
|
||||
context.addServletMappingDecoded(pattern, servletName);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.RequestContextFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class))
|
||||
.withUserConfiguration(ResourceConfigConfiguration.class);
|
||||
|
||||
@Test
|
||||
void requestContextFilterRegistrationIsAutoConfigured() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
|
||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
||||
assertThat(registration.getFilter()).isInstanceOf(RequestContextFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUserDefinesARequestContextFilterTheAutoConfiguredRegistrationBacksOff() {
|
||||
this.contextRunner.withUserConfiguration(RequestContextFilterConfiguration.class).run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(FilterRegistrationBean.class);
|
||||
assertThat(context).hasSingleBean(RequestContextFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUserDefinesARequestContextFilterRegistrationTheAutoConfiguredRegistrationBacksOff() {
|
||||
this.contextRunner.withUserConfiguration(RequestContextFilterRegistrationConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
|
||||
assertThat(context).hasBean("customRequestContextFilterRegistration");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJaxbIsAvailableTheObjectMapperIsCustomizedWithAnAnnotationIntrospector() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors().stream()
|
||||
.filter(JaxbAnnotationIntrospector.class::isInstance)).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader("javax.xml.bind.annotation")).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors()
|
||||
.stream().filter(JaxbAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() {
|
||||
this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(JaxbAnnotationIntrospector.class)).run((context) -> {
|
||||
ObjectMapper objectMapper = context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.getSerializationConfig().getAnnotationIntrospector().allIntrospectors()
|
||||
.stream().filter(JaxbAnnotationIntrospector.class::isInstance)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfig resourceConfig() {
|
||||
return new ResourceConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class RequestContextFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
RequestContextFilter requestContextFilter() {
|
||||
return new RequestContextFilter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class RequestContextFilterRegistrationConfiguration {
|
||||
|
||||
@Bean
|
||||
FilterRegistrationBean<RequestContextFilter> customRequestContextFilterRegistration() {
|
||||
return new FilterRegistrationBean<>(new RequestContextFilter());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.jersey;
|
||||
|
||||
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 javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyAutoConfiguration} when using custom application path.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.jersey.application-path=/api")
|
||||
@DirtiesContext
|
||||
class JerseyAutoConfigurationWithoutApplicationPathTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/api/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@MinimalWebConfiguration
|
||||
@Path("/hello")
|
||||
public static class Application extends ResourceConfig {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
Application() {
|
||||
register(Application.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.msg;
|
||||
}
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 org.springframework.boot.autoconfigure.web.servlet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JerseyApplicationPath}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JerseyApplicationPathTests {
|
||||
|
||||
@Test
|
||||
void getRelativePathReturnsRelativePath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getRelativePath("boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/").getRelativePath("boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getRelativePath("/boot")).isEqualTo("spring/boot");
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/*").getRelativePath("/boot")).isEqualTo("spring/boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenHasSimplePathReturnPath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenHasPatternRemovesPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/*.do").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPrefixWhenPathEndsWithSlashRemovesSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/").getPrefix()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathIsEmptyReturnsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "").getUrlMapping()).isEqualTo("/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathIsSlashReturnsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/").getUrlMapping()).isEqualTo("/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenPathContainsStarReturnsPath() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/*.do").getUrlMapping()).isEqualTo("/spring/*.do");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathNotEndingSlashReturnsSlashStarPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/boot").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathDoesNotStartWithSlashPrependsSlash() {
|
||||
assertThat(((JerseyApplicationPath) () -> "spring/boot").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUrlMappingWhenHasPathEndingWithSlashReturnsSlashStarPattern() {
|
||||
assertThat(((JerseyApplicationPath) () -> "/spring/boot/").getUrlMapping()).isEqualTo("/spring/boot/*");
|
||||
}
|
||||
|
||||
}
|
@ -821,16 +821,6 @@ bom {
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Jersey", "2.35") {
|
||||
prohibit("[3.0.0-M1,)") {
|
||||
because "it uses the jakarta.* namespace"
|
||||
}
|
||||
group("org.glassfish.jersey") {
|
||||
imports = [
|
||||
"jersey-bom"
|
||||
]
|
||||
}
|
||||
}
|
||||
library("Jetty EL", "9.0.52") {
|
||||
prohibit("[10.0.0-M1,)") {
|
||||
because "it requires Java 11"
|
||||
@ -1437,7 +1427,6 @@ bom {
|
||||
"spring-boot-starter-hateoas",
|
||||
"spring-boot-starter-integration",
|
||||
"spring-boot-starter-jdbc",
|
||||
"spring-boot-starter-jersey",
|
||||
"spring-boot-starter-jetty",
|
||||
"spring-boot-starter-jooq",
|
||||
"spring-boot-starter-json",
|
||||
|
@ -80,6 +80,7 @@ dependencies {
|
||||
implementation("jakarta.jms:jakarta.jms-api")
|
||||
implementation("jakarta.persistence:jakarta.persistence-api")
|
||||
implementation("jakarta.servlet:jakarta.servlet-api")
|
||||
implementation("jakarta.validation:jakarta.validation-api")
|
||||
implementation("net.sourceforge.htmlunit:htmlunit") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
@ -94,8 +95,7 @@ dependencies {
|
||||
}
|
||||
implementation("org.apache.tomcat.embed:tomcat-embed-core")
|
||||
implementation("org.assertj:assertj-core")
|
||||
implementation("org.glassfish.jersey.core:jersey-server")
|
||||
implementation("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
implementation("org.codehaus.groovy:groovy")
|
||||
implementation("org.hibernate:hibernate-jcache") {
|
||||
exclude group: "javax.activation", module: "javax.activation-api"
|
||||
exclude group: "javax.persistence", module: "javax.persistence-api"
|
||||
|
@ -90,7 +90,7 @@ The following technology-agnostic endpoints are available:
|
||||
| Performs a thread dump.
|
||||
|===
|
||||
|
||||
If your application is a web application (Spring MVC, Spring WebFlux, or Jersey), you can use the following additional endpoints:
|
||||
If your application is a web application (Spring MVC or Spring WebFlux), you can use the following additional endpoints:
|
||||
|
||||
[cols="2,5"]
|
||||
|===
|
||||
@ -438,8 +438,7 @@ TIP: See {spring-boot-actuator-autoconfigure-module-code}/endpoint/web/CorsEndpo
|
||||
[[actuator.endpoints.implementing-custom]]
|
||||
=== Implementing Custom Endpoints
|
||||
If you add a `@Bean` annotated with `@Endpoint`, any methods annotated with `@ReadOperation`, `@WriteOperation`, or `@DeleteOperation` are automatically exposed over JMX and, in a web application, over HTTP as well.
|
||||
Endpoints can be exposed over HTTP by using Jersey, Spring MVC, or Spring WebFlux.
|
||||
If both Jersey and Spring MVC are available, Spring MVC is used.
|
||||
Endpoints can be exposed over HTTP by using Spring MVC, or Spring WebFlux.
|
||||
|
||||
The following example exposes a read operation that returns a custom object:
|
||||
|
||||
@ -502,8 +501,7 @@ Before calling an operation method, the input received over JMX or HTTP is conve
|
||||
|
||||
[[actuator.endpoints.implementing-custom.web]]
|
||||
==== Custom Web Endpoints
|
||||
Operations on an `@Endpoint`, `@WebEndpoint`, or `@EndpointWebExtension` are automatically exposed over HTTP using Jersey, Spring MVC, or Spring WebFlux.
|
||||
If both Jersey and Spring MVC are available, Spring MVC is used.
|
||||
Operations on an `@Endpoint`, `@WebEndpoint`, or `@EndpointWebExtension` are automatically exposed over HTTP using Spring MVC or Spring WebFlux.
|
||||
|
||||
|
||||
|
||||
@ -582,9 +580,7 @@ If an operation is invoked without a required parameter or with a parameter that
|
||||
[[actuator.endpoints.implementing-custom.web.range-requests]]
|
||||
===== Web Endpoint Range Requests
|
||||
You can use an HTTP range request to request part of an HTTP resource.
|
||||
When using Spring MVC or Spring Web Flux, operations that return a `org.springframework.core.io.Resource` automatically support range requests.
|
||||
|
||||
NOTE: Range requests are not supported when using Jersey.
|
||||
Operations that return a `org.springframework.core.io.Resource` automatically support range requests.
|
||||
|
||||
|
||||
|
||||
|
@ -767,41 +767,6 @@ Applications can opt in and record exceptions by <<web#web.reactive.webflux.erro
|
||||
|
||||
|
||||
|
||||
[[actuator.metrics.supported.jersey]]
|
||||
==== Jersey Server Metrics
|
||||
Auto-configuration enables the instrumentation of all requests handled by the Jersey JAX-RS implementation.
|
||||
By default, metrics are generated with the name, `http.server.requests`.
|
||||
You can customize the name by setting the configprop:management.metrics.web.server.request.metric-name[] property.
|
||||
|
||||
`@Timed` annotations are supported on request-handling classes and methods (see <<actuator#actuator.metrics.supported.timed-annotation>> for details).
|
||||
If you do not want to record metrics for all Jersey requests, you can set configprop:management.metrics.web.server.request.autotime.enabled[] to `false` and exclusively use `@Timed` annotations instead.
|
||||
|
||||
By default, Jersey server metrics are tagged with the following information:
|
||||
|
||||
|===
|
||||
| Tag | Description
|
||||
|
||||
| `exception`
|
||||
| The simple class name of any exception that was thrown while handling the request.
|
||||
|
||||
| `method`
|
||||
| The request's method (for example, `GET` or `POST`)
|
||||
|
||||
| `outcome`
|
||||
| The request's outcome, based on the status code of the response.
|
||||
1xx is `INFORMATIONAL`, 2xx is `SUCCESS`, 3xx is `REDIRECTION`, 4xx is `CLIENT_ERROR`, and 5xx is `SERVER_ERROR`
|
||||
|
||||
| `status`
|
||||
| The response's HTTP status code (for example, `200` or `500`)
|
||||
|
||||
| `uri`
|
||||
| The request's URI template prior to variable substitution, if possible (for example, `/api/person/\{id}`)
|
||||
|===
|
||||
|
||||
To customize the tags, provide a `@Bean` that implements `JerseyTagsProvider`.
|
||||
|
||||
|
||||
|
||||
[[actuator.metrics.supported.http-clients]]
|
||||
==== HTTP Client Metrics
|
||||
Spring Boot Actuator manages the instrumentation of both `RestTemplate` and `WebClient`.
|
||||
|
@ -4,8 +4,7 @@ If you are developing a web application, Spring Boot Actuator auto-configures al
|
||||
The default convention is to use the `id` of the endpoint with a prefix of `/actuator` as the URL path.
|
||||
For example, `health` is exposed as `/actuator/health`.
|
||||
|
||||
TIP: Actuator is supported natively with Spring MVC, Spring WebFlux, and Jersey.
|
||||
If both Jersey and Spring MVC are available, Spring MVC is used.
|
||||
TIP: Actuator is supported natively with Spring MVC and Spring WebFlux.
|
||||
|
||||
NOTE: Jackson is a required dependency in order to get the correct JSON responses as documented in the API documentation ({spring-boot-actuator-restapi-docs}[HTML] or {spring-boot-actuator-restapi-pdfdocs}[PDF]).
|
||||
|
||||
|
@ -186,7 +186,6 @@ boot-features-webflux-template-engines=features.developing-web-applications.spri
|
||||
boot-features-webflux-error-handling=features.developing-web-applications.spring-webflux.error-handling
|
||||
boot-features-webflux-error-handling-custom-error-pages=features.developing-web-applications.spring-webflux.error-handling.error-pages
|
||||
boot-features-webflux-web-filters=features.developing-web-applications.spring-webflux.web-filters
|
||||
boot-features-jersey=features.developing-web-applications.jersey
|
||||
boot-features-embedded-container=features.developing-web-applications.embedded-container
|
||||
boot-features-embedded-container-servlets-filters-listeners=features.developing-web-applications.embedded-container.servlets-filters-listeners
|
||||
boot-features-embedded-container-servlets-filters-listeners-beans=features.developing-web-applications.embedded-container.servlets-filters-listeners.beans
|
||||
@ -475,7 +474,6 @@ production-ready-metrics-system=actuator.metrics.supported.system
|
||||
production-ready-metrics-logger=actuator.metrics.supported.logger
|
||||
production-ready-metrics-spring-mvc=actuator.metrics.supported.spring-mvc
|
||||
production-ready-metrics-web-flux=actuator.metrics.supported.spring-webflux
|
||||
production-ready-metrics-jersey-server=actuator.metrics.supported.jersey
|
||||
production-ready-metrics-http-clients=actuator.metrics.supported.http-clients
|
||||
production-ready-metrics-tomcat=actuator.metrics.supported.tomcat
|
||||
production-ready-metrics-cache=actuator.metrics.supported.cache
|
||||
@ -619,9 +617,6 @@ howto-switch-off-the-spring-mvc-dispatcherservlet=howto.spring-mvc.switch-off-di
|
||||
howto-switch-off-default-mvc-configuration=howto.spring-mvc.switch-off-default-configuration
|
||||
howto-customize-view-resolvers=howto.spring-mvc.customize-view-resolvers
|
||||
howto-use-test-with-spring-security=howto.spring-mvc.testing.with-spring-security
|
||||
howto-jersey=howto.jersey
|
||||
howto-jersey-spring-security=howto.jersey.spring-security
|
||||
howto-jersey-alongside-another-web-framework=howto.jersey.alongside-another-web-framework
|
||||
howto-http-clients=howto.http-clients
|
||||
howto-http-clients-proxy-configuration=howto.http-clients.rest-template-proxy-configuration
|
||||
howto-webclient-reactor-netty-customization=howto.http-clients.webclient-reactor-netty-customization
|
||||
@ -848,7 +843,6 @@ features.developing-web-applications.spring-mvc.error-handling.error-pages=web.s
|
||||
features.developing-web-applications.spring-mvc.error-handling.error-pages-without-spring-mvc=web.servlet.spring-mvc.error-handling.error-pages-without-spring-mvc
|
||||
features.developing-web-applications.spring-mvc.error-handling.in-a-war-deployment=web.servlet.spring-mvc.error-handling.in-a-war-deployment
|
||||
features.developing-web-applications.spring-mvc.cors=web.servlet.spring-mvc.cors
|
||||
features.developing-web-applications.jersey=web.servlet.jersey
|
||||
features.developing-web-applications.embedded-container=web.servlet.embedded-container
|
||||
features.developing-web-applications.embedded-container.servlets-filters-listeners=web.servlet.embedded-container.servlets-filters-listeners
|
||||
features.developing-web-applications.embedded-container.servlets-filters-listeners.beans=web.servlet.embedded-container.servlets-filters-listeners.beans
|
||||
|
@ -2,7 +2,7 @@
|
||||
== Web
|
||||
If you develop Spring Boot web applications, take a look at the following content:
|
||||
|
||||
* *Servlet Web Applications:* <<web#web.servlet, Spring MVC, Jersey, Embedded Servlet Containers>>
|
||||
* *Servlet Web Applications:* <<web#web.servlet, Spring MVC, Embedded Servlet Containers>>
|
||||
* *Reactive Web Applications:* <<web#web.reactive, Spring Webflux, Embedded Servlet Containers>>
|
||||
* *Graceful Shutdown:* <<web#web.graceful-shutdown, Graceful Shutdown>>
|
||||
* *Spring Security:* <<web#web.security, Default Security Configuration, Auto-configuration for OAuth2, SAML>>
|
||||
|
@ -23,8 +23,6 @@ include::howto/webserver.adoc[]
|
||||
|
||||
include::howto/spring-mvc.adoc[]
|
||||
|
||||
include::howto/jersey.adoc[]
|
||||
|
||||
include::howto/http-clients.adoc[]
|
||||
|
||||
include::howto/logging.adoc[]
|
||||
|
@ -1,30 +0,0 @@
|
||||
[[howto.jersey]]
|
||||
== Jersey
|
||||
|
||||
|
||||
|
||||
[[howto.jersey.spring-security]]
|
||||
=== Secure Jersey endpoints with Spring Security
|
||||
Spring Security can be used to secure a Jersey-based web application in much the same way as it can be used to secure a Spring MVC-based web application.
|
||||
However, if you want to use Spring Security's method-level security with Jersey, you must configure Jersey to use `setStatus(int)` rather `sendError(int)`.
|
||||
This prevents Jersey from committing the response before Spring Security has had an opportunity to report an authentication or authorization failure to the client.
|
||||
|
||||
The `jersey.config.server.response.setStatusOverSendError` property must be set to `true` on the application's `ResourceConfig` bean, as shown in the following example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim"]
|
||||
----
|
||||
include::{docs-java}/howto/jersey/springsecurity/JerseySetStatusOverSendErrorConfig.java[]
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[howto.jersey.alongside-another-web-framework]]
|
||||
=== Use Jersey Alongside Another Web Framework
|
||||
To use Jersey alongside another web framework, such as Spring MVC, it should be configured so that it will allow the other framework to handle requests that it cannot handle.
|
||||
First, configure Jersey to use a filter rather than a servlet by configuring the configprop:spring.jersey.type[] application property with a value of `filter`.
|
||||
Second, configure your `ResourceConfig` to forward requests that would have resulted in a 404, as shown in the following example.
|
||||
|
||||
[source,java,indent=0,subs="verbatim"]
|
||||
----
|
||||
include::{docs-java}/howto/jersey/alongsideanotherwebframework/JerseyConfig.java[]
|
||||
----
|
@ -1,6 +1,6 @@
|
||||
[[web.servlet]]
|
||||
== Servlet Web Applications
|
||||
If you want to build servlet-based web applications, you can take advantage of Spring Boot's auto-configuration for Spring MVC or Jersey.
|
||||
If you want to build servlet-based web applications, you can take advantage of Spring Boot's auto-configuration for Spring MVC.
|
||||
|
||||
[[web.servlet.spring-mvc]]
|
||||
=== The "`Spring Web MVC Framework`"
|
||||
@ -456,48 +456,6 @@ include::{docs-java}/web/servlet/springmvc/cors/MyCorsConfiguration.java[]
|
||||
|
||||
|
||||
|
||||
[[web.servlet.jersey]]
|
||||
=== JAX-RS and Jersey
|
||||
If you prefer the JAX-RS programming model for REST endpoints, you can use one of the available implementations instead of Spring MVC.
|
||||
https://jersey.github.io/[Jersey] and https://cxf.apache.org/[Apache CXF] work quite well out of the box.
|
||||
CXF requires you to register its `Servlet` or `Filter` as a `@Bean` in your application context.
|
||||
Jersey has some native Spring support, so we also provide auto-configuration support for it in Spring Boot, together with a starter.
|
||||
|
||||
To get started with Jersey, include the `spring-boot-starter-jersey` as a dependency and then you need one `@Bean` of type `ResourceConfig` in which you register all the endpoints, as shown in the following example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim"]
|
||||
----
|
||||
include::{docs-java}/web/servlet/jersey/MyJerseyConfig.java[]
|
||||
----
|
||||
|
||||
WARNING: Jersey's support for scanning executable archives is rather limited.
|
||||
For example, it cannot scan for endpoints in a package found in a <<deployment#deployment.installing, fully executable jar file>> or in `WEB-INF/classes` when running an executable war file.
|
||||
To avoid this limitation, the `packages` method should not be used, and endpoints should be registered individually by using the `register` method, as shown in the preceding example.
|
||||
|
||||
For more advanced customizations, you can also register an arbitrary number of beans that implement `ResourceConfigCustomizer`.
|
||||
|
||||
All the registered endpoints should be `@Components` with HTTP resource annotations (`@GET` and others), as shown in the following example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim"]
|
||||
----
|
||||
include::{docs-java}/web/servlet/jersey/MyEndpoint.java[]
|
||||
----
|
||||
|
||||
Since the `Endpoint` is a Spring `@Component`, its lifecycle is managed by Spring and you can use the `@Autowired` annotation to inject dependencies and use the `@Value` annotation to inject external configuration.
|
||||
By default, the Jersey servlet is registered and mapped to `/*`.
|
||||
You can change the mapping by adding `@ApplicationPath` to your `ResourceConfig`.
|
||||
|
||||
By default, Jersey is set up as a servlet in a `@Bean` of type `ServletRegistrationBean` named `jerseyServletRegistration`.
|
||||
By default, the servlet is initialized lazily, but you can customize that behavior by setting `spring.jersey.servlet.load-on-startup`.
|
||||
You can disable or override that bean by creating one of your own with the same name.
|
||||
You can also use a filter instead of a servlet by setting `spring.jersey.type=filter` (in which case, the `@Bean` to replace or override is `jerseyFilterRegistration`).
|
||||
The filter has an `@Order`, which you can set with `spring.jersey.filter.order`.
|
||||
When using Jersey as a filter, a servlet that will handle any requests that are not intercepted by Jersey must be present.
|
||||
If your application does not contain such a servlet, you may want to enable the default servlet by setting configprop:server.servlet.register-default-servlet[] to `true`.
|
||||
Both the servlet and the filter registrations can be given init parameters by using `spring.jersey.init.*` to specify a map of properties.
|
||||
|
||||
|
||||
|
||||
[[web.servlet.embedded-container]]
|
||||
=== Embedded Servlet Container Support
|
||||
For servlet application, Spring Boot includes support for embedded https://tomcat.apache.org/[Tomcat], https://www.eclipse.org/jetty/[Jetty], and https://github.com/undertow-io/undertow[Undertow] servers.
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.howto.jersey.alongsideanotherwebframework;
|
||||
|
||||
class Endpoint {
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.howto.jersey.alongsideanotherwebframework;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.servlet.ServletProperties;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JerseyConfig extends ResourceConfig {
|
||||
|
||||
public JerseyConfig() {
|
||||
register(Endpoint.class);
|
||||
property(ServletProperties.FILTER_FORWARD_ON_404, true);
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.howto.jersey.springsecurity;
|
||||
|
||||
class Endpoint {
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.howto.jersey.springsecurity;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JerseySetStatusOverSendErrorConfig extends ResourceConfig {
|
||||
|
||||
public JerseySetStatusOverSendErrorConfig() {
|
||||
register(Endpoint.class);
|
||||
setProperties(Collections.singletonMap("jersey.config.server.response.setStatusOverSendError", true));
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.web.servlet.jersey;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/hello")
|
||||
public class MyEndpoint {
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 org.springframework.boot.docs.web.servlet.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MyJerseyConfig extends ResourceConfig {
|
||||
|
||||
public MyJerseyConfig() {
|
||||
register(MyEndpoint.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
plugins {
|
||||
id "org.springframework.boot.starter"
|
||||
}
|
||||
|
||||
description = "Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to spring-boot-starter-web"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json"))
|
||||
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat"))
|
||||
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-validation"))
|
||||
api("org.springframework:spring-web")
|
||||
api("org.glassfish.jersey.core:jersey-server")
|
||||
api("org.glassfish.jersey.containers:jersey-container-servlet-core")
|
||||
api("org.glassfish.jersey.containers:jersey-container-servlet")
|
||||
api("org.glassfish.jersey.ext:jersey-bean-validation") {
|
||||
exclude group: "jakarta.el", module: "jakarta.el-api"
|
||||
exclude group: "org.glassfish", module: "jakarta.el"
|
||||
}
|
||||
api("org.glassfish.jersey.ext:jersey-spring5")
|
||||
api("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
}
|
||||
|
||||
checkRuntimeClasspathForConflicts {
|
||||
ignore { name -> name.startsWith("org/aopalliance/intercept/") }
|
||||
ignore { name -> name.startsWith("org/aopalliance/aop/") }
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -90,8 +90,6 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
|
||||
|
||||
private static final String MVC_WEB_ENVIRONMENT_CLASS = "org.springframework.web.servlet.DispatcherServlet";
|
||||
|
||||
private static final String JERSEY_WEB_ENVIRONMENT_CLASS = "org.glassfish.jersey.server.ResourceConfig";
|
||||
|
||||
private static final String ACTIVATE_SERVLET_LISTENER = "org.springframework.test."
|
||||
+ "context.web.ServletTestExecutionListener.activateListener";
|
||||
|
||||
@ -177,8 +175,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
|
||||
|
||||
private WebApplicationType deduceWebApplicationType() {
|
||||
if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
|
||||
&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)
|
||||
&& !ClassUtils.isPresent(JERSEY_WEB_ENVIRONMENT_CLASS, null)) {
|
||||
&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) {
|
||||
return WebApplicationType.REACTIVE;
|
||||
}
|
||||
for (String className : WEB_ENVIRONMENT_CLASSES) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -52,15 +52,13 @@ public enum WebApplicationType {
|
||||
|
||||
private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
|
||||
|
||||
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
|
||||
|
||||
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
|
||||
|
||||
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
|
||||
|
||||
static WebApplicationType deduceFromClasspath() {
|
||||
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
|
||||
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
|
||||
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
|
||||
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)) {
|
||||
return WebApplicationType.REACTIVE;
|
||||
}
|
||||
for (String className : SERVLET_INDICATOR_CLASSES) {
|
||||
|
@ -1,18 +0,0 @@
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot.conventions"
|
||||
}
|
||||
|
||||
description = "Spring Boot Jersey smoke test"
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jersey"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-tomcat"))
|
||||
|
||||
if (JavaVersion.current().java9Compatible) {
|
||||
runtimeOnly("jakarta.xml.bind:jakarta.xml.bind-api")
|
||||
}
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/hello")
|
||||
public class Endpoint {
|
||||
|
||||
private final Service service;
|
||||
|
||||
public Endpoint(Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.service.message();
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JerseyConfig extends ResourceConfig {
|
||||
|
||||
public JerseyConfig() {
|
||||
register(Endpoint.class);
|
||||
register(ReverseEndpoint.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/reverse")
|
||||
public class ReverseEndpoint {
|
||||
|
||||
@GET
|
||||
public String reverse(@QueryParam("input") @NotNull String input) {
|
||||
return new StringBuilder(input).reverse().toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleJerseyApplication extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new SampleJerseyApplication().configure(new SpringApplicationBuilder(SampleJerseyApplication.class)).run(args);
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Service {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "logging.level.root=debug")
|
||||
abstract class AbstractJerseyApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reverse() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/reverse?input=olleh", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).isEqualTo("hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validation() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/reverse", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorStatus() {
|
||||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).isEqualTo("{\"status\":\"UP\"}");
|
||||
}
|
||||
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import smoketest.jersey.AbstractJerseyManagementPortTests.ResourceConfigConfiguration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Base class for integration tests for Jersey using separate management and main service
|
||||
* ports.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "management.server.port=0")
|
||||
@Import(ResourceConfigConfiguration.class)
|
||||
class AbstractJerseyManagementPortTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate testRestTemplate;
|
||||
|
||||
@Test
|
||||
void resourceShouldBeAvailableOnMainPort() {
|
||||
ResponseEntity<String> entity = this.testRestTemplate.getForEntity("http://localhost:" + this.port + "/test",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resourceShouldNotBeAvailableOnManagementPort() {
|
||||
ResponseEntity<String> entity = this.testRestTemplate
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/test", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorShouldBeAvailableOnManagementPort() {
|
||||
ResponseEntity<String> entity = this.testRestTemplate
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorShouldNotBeAvailableOnMainPort() {
|
||||
ResponseEntity<String> entity = this.testRestTemplate
|
||||
.getForEntity("http://localhost:" + this.port + "/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
static class ResourceConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
ResourceConfigCustomizer customizer() {
|
||||
return new ResourceConfigCustomizer() {
|
||||
@Override
|
||||
public void customize(ResourceConfig config) {
|
||||
config.register(TestEndpoint.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Path("/test")
|
||||
public static class TestEndpoint {
|
||||
|
||||
@GET
|
||||
public String test() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 smoketest.jersey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with custom
|
||||
* application path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "spring.jersey.application-path=/app" })
|
||||
class JerseyApplicationPathAndManagementPortTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate testRestTemplate;
|
||||
|
||||
@Test
|
||||
void applicationPathShouldNotAffectActuators() {
|
||||
ResponseEntity<String> entity = this.testRestTemplate
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/actuator/health", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.jersey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with empty base path
|
||||
* for endpoints.
|
||||
*
|
||||
* @author HaiTao Zhang
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "management.endpoints.web.base-path=/" })
|
||||
class JerseyDifferentPortSampleActuatorApplicationTests {
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Test
|
||||
void linksEndpointShouldBeAvailable() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate("user", getPassword())
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"_links\"");
|
||||
}
|
||||
|
||||
private String getPassword() {
|
||||
return "password";
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
/**
|
||||
* Smoke tests for Jersey configured as a Filter.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@TestPropertySource(properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
class JerseyFilterApplicationTests extends AbstractJerseyApplicationTests {
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
/**
|
||||
* Integration tests for Jersey configured as a Servlet using separate management and main
|
||||
* service ports.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@TestPropertySource(properties = { "spring.jersey.type=filter", "server.servlet.register-default-servlet=true" })
|
||||
class JerseyFilterManagementPortTests extends AbstractJerseyManagementPortTests {
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
/**
|
||||
* Smoke tests for Jersey configured as a Servlet.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyServletApplicationTests extends AbstractJerseyApplicationTests {
|
||||
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.jersey;
|
||||
|
||||
/**
|
||||
* Integration tests for Jersey configured as a Servlet using separate management and main
|
||||
* service ports.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class JerseyServletManagementPortTests extends AbstractJerseyManagementPortTests {
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot.conventions"
|
||||
}
|
||||
|
||||
description = "Spring Boot secure Jersey smoke test"
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-actuator"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jersey"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security"))
|
||||
implementation("org.jolokia:jolokia-core")
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/hello")
|
||||
public class Endpoint {
|
||||
|
||||
private final Service service;
|
||||
|
||||
public Endpoint(Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return "Hello " + this.service.message();
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JerseyConfig extends ResourceConfig {
|
||||
|
||||
public JerseyConfig() {
|
||||
register(Endpoint.class);
|
||||
register(ReverseEndpoint.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Path("/reverse")
|
||||
public class ReverseEndpoint {
|
||||
|
||||
@GET
|
||||
public String reverse(@QueryParam("input") @NotNull String input) {
|
||||
return new StringBuilder(input).reverse().toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SampleSecureJerseyApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SampleSecureJerseyApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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 smoketest.secure.jersey;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
|
||||
import org.springframework.boot.actuate.web.mappings.MappingsEndpoint;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Bean
|
||||
public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
|
||||
return new InMemoryUserDetailsManager(
|
||||
User.withDefaultPasswordEncoder().username("user").password("password").authorities("ROLE_USER")
|
||||
.build(),
|
||||
User.withDefaultPasswordEncoder().username("admin").password("admin")
|
||||
.authorities("ROLE_ACTUATOR", "ROLE_USER").build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http.authorizeRequests()
|
||||
.requestMatchers(EndpointRequest.to("health")).permitAll()
|
||||
.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)).hasRole("ACTUATOR")
|
||||
.antMatchers("/**").hasRole("USER")
|
||||
.and()
|
||||
.httpBasic();
|
||||
return http.build();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Service {
|
||||
|
||||
@Value("${message:World}")
|
||||
private String msg;
|
||||
|
||||
public String message() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
|
||||
|
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for actuator tests with custom security.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
abstract class AbstractJerseySecureTests {
|
||||
|
||||
abstract String getPath();
|
||||
|
||||
abstract String getManagementPath();
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate testRestTemplate;
|
||||
|
||||
@Test
|
||||
void helloEndpointIsSecure() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getPath() + "/hello", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorInsecureEndpoint() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health/diskSpace", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorLinksWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorLinksWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorLinksWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
adminRestTemplate().getForEntity(getManagementPath() + "/actuator/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorSecureEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorSecureEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorSecureEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/env",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(
|
||||
getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void secureServletEndpointWithAnonymous() {
|
||||
ResponseEntity<String> entity = restTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
entity = restTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void secureServletEndpointWithUnauthorizedUser() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void secureServletEndpointWithAuthorizedUser() {
|
||||
ResponseEntity<String> entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/jolokia/list", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void actuatorExcludedFromEndpointRequestMatcher() {
|
||||
ResponseEntity<String> entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/mappings",
|
||||
String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
}
|
||||
|
||||
TestRestTemplate restTemplate() {
|
||||
return this.testRestTemplate;
|
||||
}
|
||||
|
||||
TestRestTemplate adminRestTemplate() {
|
||||
return this.testRestTemplate.withBasicAuth("admin", "admin");
|
||||
}
|
||||
|
||||
TestRestTemplate userRestTemplate() {
|
||||
return this.testRestTemplate.withBasicAuth("user", "password");
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
|
||||
/**
|
||||
* Integration tests for actuator endpoints with custom application path.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = "spring.jersey.application-path=/example")
|
||||
|
||||
class CustomApplicationPathActuatorTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.port + "/example";
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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 smoketest.secure.jersey;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
|
||||
/**
|
||||
* Integration tests for actuator endpoints with custom security configuration.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
class JerseySecureApplicationTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 smoketest.secure.jersey;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for separate management and main service ports with custom management
|
||||
* context path.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
||||
properties = { "management.server.port=0", "management.server.base-path=/management" })
|
||||
class ManagementPortAndPathJerseyApplicationTests extends AbstractJerseySecureTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@LocalManagementPort
|
||||
private int managementPort;
|
||||
|
||||
@Test
|
||||
void testMissing() {
|
||||
ResponseEntity<String> entity = new TestRestTemplate("admin", "admin")
|
||||
.getForEntity("http://localhost:" + this.managementPort + "/management/actuator/missing", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getPath() {
|
||||
return "http://localhost:" + this.port;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getManagementPath() {
|
||||
return "http://localhost:" + this.managementPort + "/management";
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user